This is an archive of the discontinued LLVM Phabricator instance.

[InstSimplify] enhance simplifyWithOpReplaced() to allow more 'select' removal
ClosedPublic

Authored by spatel on Feb 21 2023, 7:52 AM.

Details

Summary

This is a generalization of a suggestion from issue #60799 that allows removing a redundant guard of an input value via icmp+select. It should also solve issue #60801.

This only comes into play for a select with an equality condition where we are trying to substitute a constant into the false arm of a select. (A 'true' select arm substitution allows "refinement", so it is not on this code path.)

The constant must be the same in the compare and the select, and it must be a "binop absorber" (X op C = C). That query currently includes 'or', 'and', and 'mul', so there are tests for all of those opcodes.

We then use "impliesPoison" on the false arm binop and the original "Op" to be replaced to ensure that the select is not actually blocking poison from leaking. That could be potentially expensive as we recursively test each operand, but it is currently limited to a depth of 2. That's enough to catch our motivating cases, but probably nothing more complicated (although that seems unlikely).

I don't know how to generalize a proof for Alive2 for this, but here's a positive and negative test example to help illustrate the subtle logic differences of poison propagation:
https://alive2.llvm.org/ce/z/Sz5K-c

Diff Detail

Event Timeline

spatel created this revision.Feb 21 2023, 7:52 AM
spatel requested review of this revision.Feb 21 2023, 7:52 AM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 21 2023, 7:52 AM
nikic added a comment.Feb 21 2023, 8:04 AM

I like the approach, but I'm not sure you're checking the right poison implications. My first thought would be that we need impliesPoison(V, Op). We are replacing the select with V, so what we want to establish is that if V is poison, the select would be poison anyway because Op is also implied poison.

I like the approach, but I'm not sure you're checking the right poison implications. My first thought would be that we need impliesPoison(V, Op). We are replacing the select with V, so what we want to establish is that if V is poison, the select would be poison anyway because Op is also implied poison.

Yes, that is clearer and seems to work. I'm not finding a test diff given the other constraints in place...
Also, I initially misread the recursive depth check in impliesPoison() - we can look past the binop itself and each of its operands.

spatel updated this revision to Diff 499199.Feb 21 2023, 9:06 AM

Patch updated:
Reduced the impliesPoison() logic as suggested.

spatel edited the summary of this revision. (Show Details)Feb 21 2023, 9:11 AM
nikic accepted this revision.Feb 21 2023, 11:44 AM

LGTM

This revision is now accepted and ready to land.Feb 21 2023, 11:44 AM
This revision was landed with ongoing or failed builds.Feb 21 2023, 2:03 PM
This revision was automatically updated to reflect the committed changes.