diff options
| author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2017-08-07 11:14:37 +0200 |
|---|---|---|
| committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2018-08-08 09:55:12 +0200 |
| commit | 0fa902bbcf33024cc02d0582eb8b17f97d0e6048 (patch) | |
| tree | ba3b113a69c286c9785464310ba396ce0976815b /simplify.c | |
| parent | ed1e163b88d6cc2e3435474caf9c1bc5c3764096 (diff) | |
| download | sparse-dev-0fa902bbcf33024cc02d0582eb8b17f97d0e6048.tar.gz | |
simplify (x << S) >> S into x & (-1 >> S)
This transformation is especially usefull when simplifying code
accessing bitfields or for other masking manipulations.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Diffstat (limited to 'simplify.c')
| -rw-r--r-- | simplify.c | 11 |
1 files changed, 11 insertions, 0 deletions
@@ -656,6 +656,17 @@ static int simplify_shift(struct instruction *insn, pseudo_t pseudo, long long v if (def_opcode(src) == OP_AND) return simplify_or_lsr(insn, src, def->src1, value); break; + case OP_SHL: + // replace (A << S) >> S + // by A & (Mask(size) >> S) + if (!constant(def->src2)) + break; + if (def->src2->value != value) + break; + size = insn->size - value; + insn->opcode = OP_AND; + insn->src2 = value_pseudo((1ULL << size) - 1); + return replace_pseudo(insn, &insn->src1, def->src1); } break; case OP_SHL: |
