Simplify bitwise operations on a compare and its complement into 0 (for &) or 1 for (| and ^). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx> --- simplify.c | 24 +++++++++++++++++++++--- validation/optim/cse-not02.c | 1 - 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/simplify.c b/simplify.c index b41c155735d1..9938a5974744 100644 --- a/simplify.c +++ b/simplify.c @@ -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 aa54a375a9ea..70addebcfbb6 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 -- 2.29.2