diff options
author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2020-11-06 21:50:31 +0100 |
---|---|---|
committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2020-11-22 15:58:07 +0100 |
commit | 7f03e99c7e74d9971460e42a2230de66ae6ffdcf (patch) | |
tree | fd49d57421f49f0b22b804d7ffc8f901a6a55f46 | |
parent | a49663abcf7f1a0139b403fa23856ca998ffee28 (diff) | |
download | sparse-7f03e99c7e74d9971460e42a2230de66ae6ffdcf.tar.gz |
not: simplify ((x cmp y) {&,|,^} (x !cmp y)) --> {0,1,1}
Simplify bitwise operations on a compare and its complement
into 0 (for &) or 1 for (| and ^).
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r-- | simplify.c | 24 | ||||
-rw-r--r-- | validation/optim/cse-not02.c | 1 |
2 files changed, 21 insertions, 4 deletions
@@ -1632,7 +1632,7 @@ static int simplify_compare(struct instruction *insn) static int simplify_and_one_side(struct instruction *insn, pseudo_t *p1, pseudo_t *p2) { - struct instruction *def; + struct instruction *def, *defr = NULL; pseudo_t src1 = *p1; switch (DEF_OPCODE(def, src1)) { @@ -1640,6 +1640,12 @@ static int simplify_and_one_side(struct instruction *insn, pseudo_t *p1, pseudo_ if (def->src == *p2) return replace_with_value(insn, 0); break; + case OP_BINCMP ... OP_BINCMP_END: + if (DEF_OPCODE(defr, *p2) == opcode_negate(def->opcode)) { + if (def->src1 == defr->src1 && def->src2 == defr->src2) + return replace_with_value(insn, 0); + } + break; } return 0; } @@ -1652,7 +1658,7 @@ static int simplify_and(struct instruction *insn) static int simplify_ior_one_side(struct instruction *insn, pseudo_t *p1, pseudo_t *p2) { - struct instruction *def; + struct instruction *def, *defr = NULL; pseudo_t src1 = *p1; switch (DEF_OPCODE(def, src1)) { @@ -1660,6 +1666,12 @@ static int simplify_ior_one_side(struct instruction *insn, pseudo_t *p1, pseudo_ if (def->src == *p2) return replace_with_value(insn, bits_mask(insn->size)); break; + case OP_BINCMP ... OP_BINCMP_END: + if (DEF_OPCODE(defr, *p2) == opcode_negate(def->opcode)) { + if (def->src1 == defr->src1 && def->src2 == defr->src2) + return replace_with_value(insn, 1); + } + break; } return 0; } @@ -1672,7 +1684,7 @@ static int simplify_ior(struct instruction *insn) static int simplify_xor_one_side(struct instruction *insn, pseudo_t *p1, pseudo_t *p2) { - struct instruction *def; + struct instruction *def, *defr = NULL; pseudo_t src1 = *p1; switch (DEF_OPCODE(def, src1)) { @@ -1680,6 +1692,12 @@ static int simplify_xor_one_side(struct instruction *insn, pseudo_t *p1, pseudo_ if (def->src == *p2) return replace_with_value(insn, bits_mask(insn->size)); break; + case OP_BINCMP ... OP_BINCMP_END: + if (DEF_OPCODE(defr, *p2) == opcode_negate(def->opcode)) { + if (def->src1 == defr->src1 && def->src2 == defr->src2) + return replace_with_value(insn, 1); + } + break; } return 0; } diff --git a/validation/optim/cse-not02.c b/validation/optim/cse-not02.c index aa54a375..70addebc 100644 --- a/validation/optim/cse-not02.c +++ b/validation/optim/cse-not02.c @@ -5,7 +5,6 @@ int xor(int a, int b) { return ((a == b) ^ (a != b)) == 1; } /* * check-name: cse-not02 * check-command: test-linearize -Wno-decl $file - * check-known-to-fail * * check-output-ignore * check-output-returns: 1 |