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@xxxxxxxxx> --- simplify.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/simplify.c b/simplify.c index 6b44d447c0a9..1fcfc691579a 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) { -- 2.29.2