@@ -445,9 +445,25 @@ static int simplify_seteq_setne(struct instruction *insn, long long value)
remove_usage(old, &insn->src1);
return REPEAT_CSE;
+ case OP_CAST:
+ if (def->orig_type->bit_size != 1)
+ break;
+
+ // Convert:
+ // cast.n %t <- (1) %a
+ // setne.m %r <- %t, $0
+ // into:
+ // ...
+ // setne.m %r <- %a, $0
+ // and similar for setne/eq ... 0/1
+ use_pseudo(insn, def->src1, &insn->src1);
+ remove_usage(old, &insn->src1);
+ return REPEAT_CSE;
+
default:
- return 0;
+ break;
}
+ return 0;
}
static int simplify_constant_rightside(struct instruction *insn)
new file mode 100644
@@ -0,0 +1,12 @@
+_Bool beq0(_Bool a) { return (a == 0); }
+_Bool beq1(_Bool a) { return (a == 1); }
+_Bool bne0(_Bool a) { return (a != 0); }
+_Bool bne1(_Bool a) { return (a != 1); }
+
+/*
+ * check-name: bool - int - bool constants
+ * check-command: test-linearize -Wno-decl $file
+ *
+ * check-output-ignore
+ * check-output-excludes: cast\\.
+ */
Because of C's integer promotion, in code like 'a == 0', the operand 'a' must be promoted to int, which result in following linearization if the type of 'a' was _Bool: cast.32 %t <- (1) %a setne.32 %r <- %t, $0 While required by the standard, this promotion is unneeded in the given situation. Change this by simplifying away such casts. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com> --- simplify.c | 18 +++++++++++++++++- validation/optim/bool-int-bool.c | 12 ++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 validation/optim/bool-int-bool.c