aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
-rw-r--r--simplify.c17
-rw-r--r--validation/optim/muldiv-by-one.c13
-rw-r--r--validation/optim/muldiv-by-zero.c13
3 files changed, 43 insertions, 0 deletions
diff --git a/simplify.c b/simplify.c
index 6ab9f622..47ec780c 100644
--- a/simplify.c
+++ b/simplify.c
@@ -337,6 +337,21 @@ static int simplify_asr(struct instruction *insn, pseudo_t pseudo, long long val
return 0;
}
+static int simplify_mul_div(struct instruction *insn, long long value)
+{
+ if (value == 1)
+ return replace_with_pseudo(insn, insn->src1);
+
+ switch (insn->opcode) {
+ case OP_MULS:
+ case OP_MULU:
+ if (value == 0)
+ return replace_with_pseudo(insn, insn->src2);
+ }
+
+ return 0;
+}
+
static int simplify_constant_rightside(struct instruction *insn)
{
long long value = insn->src2->value;
@@ -361,6 +376,8 @@ static int simplify_constant_rightside(struct instruction *insn)
return simplify_asr(insn, insn->src1, value);
case OP_MULU: case OP_MULS:
+ return simplify_mul_div(insn, value);
+
case OP_AND_BOOL:
if (value == 1)
return replace_with_pseudo(insn, insn->src1);
diff --git a/validation/optim/muldiv-by-one.c b/validation/optim/muldiv-by-one.c
new file mode 100644
index 00000000..ac8ac95b
--- /dev/null
+++ b/validation/optim/muldiv-by-one.c
@@ -0,0 +1,13 @@
+typedef unsigned int ui;
+typedef int si;
+
+si smul1(si a) { return a * 1; }
+ui umul1(ui a) { return a * 1; }
+
+/*
+ * check-name: muldiv-by-one
+ * check-command: test-linearize -Wno-decl $file
+ * check-output-ignore
+ *
+ * check-output-excludes: mul[us]\\.
+ */
diff --git a/validation/optim/muldiv-by-zero.c b/validation/optim/muldiv-by-zero.c
new file mode 100644
index 00000000..07b7b1a7
--- /dev/null
+++ b/validation/optim/muldiv-by-zero.c
@@ -0,0 +1,13 @@
+typedef unsigned int ui;
+typedef int si;
+
+si smul0(si a) { return a * 0; }
+ui umul0(ui a) { return a * 0; }
+
+/*
+ * check-name: muldiv-by-zero
+ * check-command: test-linearize -Wno-decl $file
+ * check-output-ignore
+ *
+ * check-output-excludes: mul[us]\\.
+ */