You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The issue is similar to #60234 (but then it was in Guard Widening). We are not allowed to sink widenable conditions into loops. Here is why it is a miscompile:
The behavior of program before the transform is limited to 2 scenarios:
If %wc is true, branch will always go into the inner loop, and the program will infinitely call @print(). Program never returns.
If %wc is false, program returns 0, and @print() is never called.
This allows us to optimize return value to ret i32 0 (IndVars actually does it, but it also eliminates some other code and breaks the example for unrelated reasons).
After the reansform, %wc is computed in the loop. It means that the legal scenario is that the program calls @print() 10 times and then exits, returning 10. It was impossible scenario before the transform.
[LoopPredication] Fix where we generate widened condition. PR61963
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 the branch into a loop-varying one.
The latter is problematic when the branch may have been loop-invariant
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.
https://github.com/llvm/llvm-project/issues/61963 fixed.
Differential Revision: https://reviews.llvm.org/D147662
https://godbolt.org/z/8j953fhT6
Run
opt -passes=loop-predication
on the following IR:Result:
The issue is similar to #60234 (but then it was in Guard Widening). We are not allowed to sink widenable conditions into loops. Here is why it is a miscompile:
The behavior of program before the transform is limited to 2 scenarios:
%wc
is true, branch will always go into the inner loop, and the program will infinitely call@print()
. Program never returns.%wc
is false, program returns0
, and@print()
is never called.This allows us to optimize return value to
ret i32 0
(IndVars actually does it, but it also eliminates some other code and breaks the example for unrelated reasons).After the reansform,
%wc
is computed in the loop. It means that the legal scenario is that the program calls@print()
10 times and then exits, returning10
. It was impossible scenario before the transform.This code in Loop Predication is wrong: https://gitlab.azulsystems.com/dev/orca/-/blob/master/llvm/lib/Transforms/Scalar/LoopPredication.cpp#L1195
The text was updated successfully, but these errors were encountered: