aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
-rw-r--r--simplify.c11
-rw-r--r--validation/kill-pure-call.c17
2 files changed, 28 insertions, 0 deletions
diff --git a/simplify.c b/simplify.c
index b8944f0f..cacf81f9 100644
--- a/simplify.c
+++ b/simplify.c
@@ -236,6 +236,17 @@ void kill_insn(struct instruction *insn, int force)
kill_use(&insn->cond);
break;
+ case OP_CALL:
+ if (!force) {
+ /* a "pure" function can be killed too */
+ if (!(insn->func->type == PSEUDO_SYM))
+ return;
+ if (!(insn->func->sym->ctype.modifiers & MOD_PURE))
+ return;
+ }
+ kill_use_list(insn->arguments);
+ break;
+
case OP_ENTRY:
/* ignore */
return;
diff --git a/validation/kill-pure-call.c b/validation/kill-pure-call.c
new file mode 100644
index 00000000..d3f78c02
--- /dev/null
+++ b/validation/kill-pure-call.c
@@ -0,0 +1,17 @@
+int side(int a);
+int pure(int a) __attribute__((pure));
+
+int keep(int a) { return side(a) && 0; }
+int kill(int a) { return pure(a) && 0; }
+
+/*
+ * check-name: kill-pure-call
+ * check-command: test-linearize -Wno-decl $file
+ * check-description:
+ * See that the call is optimized away but only
+ * when the function is "pure".
+ *
+ * check-output-ignore
+ * check-output-contains: call\\..* side
+ * check-output-excludes: call\\..* pure
+ */