diff options
author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2020-11-07 01:09:07 +0100 |
---|---|---|
committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2020-11-07 12:19:02 +0100 |
commit | 93bb38fdbfb16f8382954db1e02a6ff1731bd60f (patch) | |
tree | 10603e2d931bb0a6ec8d8147ee3bc26980a363a8 | |
parent | 7ccaa8a6e88a02e05cb37adc2658071947e9331c (diff) | |
download | sparse-93bb38fdbfb16f8382954db1e02a6ff1731bd60f.tar.gz |
select: simplify SEL(SEL(x, C, 0), C, 0) --> SEL(x, C, 0) == cond
If the condition of a select is also a select, both with the same
arguments: first a non-zero constant, then a zero constant, then
the outer select is equivalent to the inner one and can thus
be replaced by the result of the inner select (which is its own
condition).
Note: this is a special case of:
SEL(SEL(x, C, 0), y, z) --> SEL(x, y, z)
and without this patch we'll have:
t = SEL(x, C, 0)
r = SEL(t, C, 0)
simplified into:
t = SEL(x, C, 0) // possibly unused now
r = SEL(x, C, 0)
but the present patch do
t = SEL(x, C, 0)
r = t
In other words, functionally, the result is the same but
now the result is taken from the first instruction.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r-- | simplify.c | 3 |
1 files changed, 3 insertions, 0 deletions
@@ -1791,8 +1791,11 @@ static int simplify_select(struct instruction *insn) // And if that one results in a "zero or not", use the // original conditional instead. // SEL(SEL(x, C, 0), y, z) --> SEL(x, y, z) + // SEL(SEL(x, C, 0), C, 0) --> SEL(x, C, 0) == cond // SEL(SEL(x, 0, C), y, z) --> SEL(x, z, y) if (!def->src3->value) { + if ((src1 == def->src2) && (src2 == def->src3)) + return replace_with_pseudo(insn, cond); return replace_pseudo(insn, &insn->cond, def->cond); } if (!def->src2->value) { |