aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
-rw-r--r--simplify.c12
-rw-r--r--validation/optim/eqne-select.c12
2 files changed, 24 insertions, 0 deletions
diff --git a/simplify.c b/simplify.c
index 20ab9b3b..1dba9752 100644
--- a/simplify.c
+++ b/simplify.c
@@ -1783,6 +1783,18 @@ static int simplify_select(struct instruction *insn)
}
switch (DEF_OPCODE(def, cond)) {
+ case OP_SET_EQ:
+ if (src1 == def->src1 && src2 == def->src2)
+ return replace_with_pseudo(insn, src2); // SEL(x==y,x,y) --> y
+ if (src2 == def->src1 && src1 == def->src2)
+ return replace_with_pseudo(insn, src2); // SEL(y==x,x,y) --> y
+ break;
+ case OP_SET_NE:
+ if (src1 == def->src1 && src2 == def->src2)
+ return replace_with_pseudo(insn, src1); // SEL(x!=y,x,y) --> x
+ if (src2 == def->src1 && src1 == def->src2)
+ return replace_with_pseudo(insn, src1); // SEL(y!=x,x,y) --> x
+ break;
case OP_SEL:
if (constant(def->src2) && constant(def->src3)) {
// Is the def of the conditional another select?
diff --git a/validation/optim/eqne-select.c b/validation/optim/eqne-select.c
new file mode 100644
index 00000000..9dfd88b5
--- /dev/null
+++ b/validation/optim/eqne-select.c
@@ -0,0 +1,12 @@
+int sel_eq01(int a, int b) { return ((a == b) ? a : b) == b; }
+int sel_eq10(int a, int b) { return ((a == b) ? b : a) == a; }
+int sel_ne01(int a, int b) { return ((a != b) ? a : b) == a; }
+int sel_ne10(int a, int b) { return ((a != b) ? b : a) == b; }
+
+/*
+ * check-name: eqne-select
+ * check-command: test-linearize -Wno-decl $file
+ *
+ * check-output-ignore
+ * check-output-returns: 1
+ */