aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/validation
diff options
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2017-01-29 11:48:02 +0100
committerChristopher Li <sparse@chrisli.org>2017-02-13 09:34:45 +0800
commit412a61828670c1eb8c474640d787b522f9384222 (patch)
treebfe6433bbddd1201ed73cc1f02df20cc811b31d9 /validation
parentb5e06b1c455c544e43dbe14badbef0fd07687d64 (diff)
downloadsparse-dev-412a61828670c1eb8c474640d787b522f9384222.tar.gz
kill uses of replaced instructions
When an instruction is replaced by a pseudo, the 'usage' of its operands should be removed too but it's not the case. The fix consists in calling kill_use() for each operands after the pseudo is replaced. Not all types of instruction are considered, only those which can be replaced by a pseudo. The following example illustrate the situation. When looking at the output of test-linearize, the following function: static int kill_add(int a, int b) { return (a + b) && 0; } without the patch, gives this output: kill_add: add.32 %r3 <- %arg1, %arg2 ret.32 $0 The 'add' instruction is obviously unneeded but nevertheless present. Before any optimization the code was something like: kill_add: add.32 %r3 <- %arg1, %arg2 and_bool.32 %r4 <- %r3, $0 ret.32 %r4 During the simplification phase, the result of the 'and' instruction (%r4) have been replaced by '0' and the instruction itself is discarded. But '%r3' usage has not been adjusted and the further phases are not aware that '%r3' is not needed anymore and so the 'add' instruction is kept while not needed by anything. With the patch the 'add' instruction is correctly discarded, giving the expected output: kill_add: ret.32 $0 Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com> Signed-off-by: Christopher Li <sparse@chrisli.org>
Diffstat (limited to 'validation')
-rw-r--r--validation/kill-replaced-insn.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/validation/kill-replaced-insn.c b/validation/kill-replaced-insn.c
new file mode 100644
index 00000000..be031b6c
--- /dev/null
+++ b/validation/kill-replaced-insn.c
@@ -0,0 +1,54 @@
+// See if the replaced operation is effectively killed or not
+
+static int kill_add(int a, int b)
+{
+ return (a + b) && 0;
+}
+
+static int kill_scast(short a)
+{
+ return ((int) a) && 0;
+}
+
+static int kill_ucast(unsigned char a)
+{
+ return ((int) a) && 0;
+}
+
+static int kill_pcast(int *a)
+{
+ return ((void*) a) && 0;
+}
+
+static int kill_fcast(double a)
+{
+ return ((int) a) && 0;
+}
+
+static int kill_select(int a)
+{
+ return (a ? 1 : 0) && 0;
+}
+
+static int kill_load(int *a)
+{
+ return *a && 0;
+}
+
+static int kill_store(int *a)
+{
+ return (*a = 1) && 0;
+}
+
+/*
+ * check-name: kill-replaced-insn
+ * check-command: test-linearize $file
+ *
+ * check-output-ignore
+ * check-output-excludes: add\\.
+ * check-output-excludes: scast\\.
+ * check-output-excludes: \\<cast\\.
+ * check-output-excludes: ptrcast\\.
+ * check-output-excludes: fpcast\\.
+ * check-output-excludes: sel\\.
+ */