This is an archive of the discontinued LLVM Phabricator instance.

[LoopPredication] Fix where we generate widened condition. PR61963
ClosedPublic

Authored by anna on Apr 5 2023, 2:34 PM.

Details

Summary

Loop predication's predicateLoopExit pass does two incorrect things:

It sinks the widenable call into the loop, thereby converting an invariant condition to a variant one
It widens the widenable call at a branch thereby converting it into a loop-varying one.

The latter is problematic when the branch may have been a loop-invariant
branch and prior optimizations (such as indvars) may have relied on this
fact, and updated the deopt state accordingly.

Now, when we widen this with a loop-varying condition, the deopt state
is no longer correct. See
https://github.com/llvm/llvm-project/issues/61963.

Diff Detail

Event Timeline

anna created this revision.Apr 5 2023, 2:34 PM
Herald added a project: Restricted Project. · View Herald TranscriptApr 5 2023, 2:34 PM
anna requested review of this revision.Apr 5 2023, 2:34 PM
Herald added a project: Restricted Project. · View Herald TranscriptApr 5 2023, 2:34 PM

I generally agree with the change in code, but can we shrink the test? I'm pretty sure most of things here are not really required.

llvm/test/Transforms/LoopPredication/pr61963.ll
11

Is it possible to reduce the test via bugpoint? Just assert whenever you move non-loop-invariant into loop in this transform and let it do the job.

anna added inline comments.Apr 6 2023, 7:38 AM
llvm/test/Transforms/LoopPredication/pr61963.ll
11

Yea, I had reduced this with bugpoint using exactly similar assert. The problem is it removes all the deopt calls as well and makes it oversimplified (we can see the problem, but it's not that clear, since the deopt states are missing). I can hack bug point to avoid removing these deopt calls. Will try that or manually reducing this further.

anna marked an inline comment as done.Apr 6 2023, 10:48 AM
anna updated this revision to Diff 511473.Apr 6 2023, 10:49 AM

simplified testcase.

anna updated this revision to Diff 511476.Apr 6 2023, 10:57 AM

renamed some blocks in test and simplified further.

Given that it's the second time we have to fix a similar issue, we should make a common utility for widening that makes it impossible to emit a widened condition in an incorrect context.

anna updated this revision to Diff 511495.Apr 6 2023, 11:44 AM

rebased over landed testcase.

anna added a comment.EditedApr 6 2023, 12:30 PM

Given that it's the second time we have to fix a similar issue, we should make a common utility for widening that makes it impossible to emit a widened condition in an incorrect context.

Yep, I think it works naturally with the guard widening fix as well (as a follow-up commit). One thing though - this does not prevent from directly identifying an incorrect context unless the utility is used (in short, a verifier would be best).

Also, we should add asserts at two utilities in GuardUtils: https://github.com/llvm/llvm-project/blob/main/llvm/lib/Transforms/Utils/GuardUtils.cpp#L82

  1. setWidenableBranchCond(BranchInst *WidenableBR, Value *NewCond)
  2. widenWidenableBranch(BranchInst *WidenableBR, Value *NewCond)

Assert that we didn't convert a loop-invariant WidenableBR into a loop-variant one. We add an optional LI to this API, but LI is available in both these passes which use the utilities. Will try this out.

mkazantsev accepted this revision.Apr 6 2023, 10:07 PM

LG, thanks

llvm/test/Transforms/LoopPredication/pr61963.ll
89

I guess we can also just leave 1 value here (the one that was replaced with invariant) rather than keeping all of them.

This revision is now accepted and ready to land.Apr 6 2023, 10:07 PM
anna marked an inline comment as done.Apr 10 2023, 7:37 AM
This revision was landed with ongoing or failed builds.Apr 10 2023, 7:37 AM
This revision was automatically updated to reflect the committed changes.