This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] replace fold of an icmp pattern that should never happen with an assert
ClosedPublic

Authored by spatel on Aug 30 2016, 8:39 AM.

Details

Summary

While removing a scalar shackle from an icmp fold, I noticed that I couldn't find any tests to trigger this code path.

The 'and' shrinking transform should be handled by InstCombiner::foldCastedBitwiseLogic() or eliminated with InstSimplify. The icmp narrowing is part of InstCombiner::foldICmpWithCastAndCast().

Diff Detail

Repository
rL LLVM

Event Timeline

spatel updated this revision to Diff 69692.Aug 30 2016, 8:39 AM
spatel retitled this revision from to [InstCombine] replace fold of an icmp pattern that should never happen with an assert .
spatel updated this object.
spatel added reviewers: efriedma, majnemer.
spatel added a subscriber: llvm-commits.
efriedma edited edge metadata.Aug 31 2016, 10:53 AM

Are you absolutely sure we can't trigger the assertion? I don't think there's any guarantee instcombine will visit the "and" before the "icmp".

Are you absolutely sure we can't trigger the assertion? I don't think there's any guarantee instcombine will visit the "and" before the "icmp".

Hmm...that would kill my (possibly wrong) mental model of InstCombine as a top-down / greedy machine. Is the comment in AddReachableCodeToWorklist() enough?

// Once we've found all of the instructions to add to instcombine's worklist,
// add them in reverse order.  This way instcombine will visit from the top
// of the function down.

If that's not a valid assumption or if there's some other way that the worklist order doesn't match the instruction order, then I agree we can't assert here.

In that case, I think it should still be valid to remove the block of code (but don't add the assert). The regression test verifies that we get the end result that we want.

The initial worklist visits from the top down, but that isn't a general guarantee that every operand of an instruction will be completely combined before you visit that instruction. For example, suppose the zext has a second use. If that use is proven dead and erased between the visit to the "and" and the visit to the "icmp", you can trigger the assertion. (Or something along those lines; I haven't actually gone through and proved that particular example works the way I described it.)

The initial worklist visits from the top down, but that isn't a general guarantee that every operand of an instruction will be completely combined before you visit that instruction. For example, suppose the zext has a second use. If that use is proven dead and erased between the visit to the "and" and the visit to the "icmp", you can trigger the assertion. (Or something along those lines; I haven't actually gone through and proved that particular example works the way I described it.)

OK, I'm sufficiently scared that there is a possibility. :)
Do you think it's better to leave the fold in place? Or remove it but not add the assert?

There isn't any reason to duplicate the combine; instcombine will get to it eventually because it iterates over the function. I would say just remove the combine and don't add an assertion.

spatel updated this revision to Diff 69915.Aug 31 2016, 3:42 PM
spatel edited edge metadata.

Patch updated:
Remove the redundant fold, but don't assert that the base transform has already occurred; we can't be certain about the order.

efriedma accepted this revision.Aug 31 2016, 3:56 PM
efriedma edited edge metadata.

LGTM.

This revision is now accepted and ready to land.Aug 31 2016, 3:56 PM
This revision was automatically updated to reflect the committed changes.