aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2020-11-07 01:09:07 +0100
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2020-11-07 12:19:02 +0100
commit93bb38fdbfb16f8382954db1e02a6ff1731bd60f (patch)
tree10603e2d931bb0a6ec8d8147ee3bc26980a363a8
parent7ccaa8a6e88a02e05cb37adc2658071947e9331c (diff)
downloadsparse-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.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/simplify.c b/simplify.c
index 6b44d447..1fcfc691 100644
--- a/simplify.c
+++ b/simplify.c
@@ -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) {