diff options
| author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2017-01-29 11:48:02 +0100 |
|---|---|---|
| committer | Christopher Li <sparse@chrisli.org> | 2017-02-13 09:34:45 +0800 |
| commit | 412a61828670c1eb8c474640d787b522f9384222 (patch) | |
| tree | bfe6433bbddd1201ed73cc1f02df20cc811b31d9 /validation | |
| parent | b5e06b1c455c544e43dbe14badbef0fd07687d64 (diff) | |
| download | sparse-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.c | 54 |
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\\. + */ |
