@@ -578,10 +578,10 @@ static int simplify_binop_same_args(struct instruction *insn, pseudo_t arg)
case OP_AND_BOOL:
case OP_OR_BOOL:
- // simplification is correct only if the operands
- // have already been compared against zero which
- // is not enforced.
- break;
+ remove_usage(arg, &insn->src2);
+ insn->src2 = value_pseudo(0);
+ insn->opcode = OP_SET_NE;
+ return REPEAT_CSE;
default:
break;
new file mode 100644
@@ -0,0 +1,12 @@
+static int ior(int a) { return a || a; }
+static int and(int a) { return a && a; }
+
+/*
+ * check-name: bool-same-args
+ * check-command: test-linearize $file
+ * check-output-ignore
+ *
+ * check-output-excludes: or-bool\\.
+ * check-output-excludes: and-bool\\.
+ * check-output-contains: setne\\.
+ */
The operators '||' and '&&' being idempotent, the expressions '(x || x)' and '(x && x)' can be simplified to a test against zero. Note: they could even be replaced by 'x' itself but only if 'x' is already a boolean expression/has already been tested against zero. If it is the case, the redundant test this will be optimized away in further steps. For example, test-linearize on the following code: int ior(int a) { return a || a; } emitted the following instructions: or-bool.32 %r3 <- %arg1, %arg1 after the patch, it now emits: setne.32 %r3 <- %arg1, $0 which is easier to combine with others simplifications. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com> --- simplify.c | 8 ++++---- validation/optim/bool-same-args.c | 12 ++++++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 validation/optim/bool-same-args.c