This is an archive of the discontinued LLVM Phabricator instance.

[SCEV] Help getLoopInvariantExitCondDuringFirstIterations deal with complex `umin` exit counts. PR59615
ClosedPublic

Authored by mkazantsev on Dec 20 2022, 10:09 PM.

Details

Summary

Recent improvements in symbolic exit count computation revealed some problems with
SCEV's ability to find invariant predicate during first iterations. Ultimately it is based on its
ability to prove some facts for value on the last iteration. This last value, when it includes
umin as part of exit count, isn't always simplified enough. The motivatin example is following:

https://github.com/llvm/llvm-project/issues/59615

Could not prove:

Pred = 36, LHS = (-1 + (-1 * (2147483645 umin (-1 + %var)<nsw>))<nsw> + %var), RHS = %var
FoundPred = 36, FoundLHS = {1,+,1}<nuw><nsw><%bb3>, FoundRHS = %var

Can prove:

Pred = 36, LHS = (-1 + (-1 * (-1 + %var)<nsw>)<nsw> + %var), RHS = %var
FoundPred = 36, FoundLHS = {1,+,1}<nuw><nsw><%bb3>, FoundRHS = %var

Here (2147483645 umin (-1 + %var)<nsw>) is exit count composed of two parts from
two different exits: 2147483645 and (-1 + %var)<nsw>. When it was only one (latter)
analyzeable exit, for it everything was easily provable. Unfortunately, in general case umin
in one of add's operands doesn't guarantee that the whole sum reduces, especially in presence
of negative steps and lack of nuw. I don't think there is a generic legal way to somehow play
around this umin.

So the ad-hoc solution is following: if we failed to find an equivalent predicate that is invariant
during first MaxIter iterations, and MaxIter = umin(a, b, c...), try to find solution for at least one
of a, b, c... Because they all are uge than MaxIter, whatever is true during a (b, c) iterations
is also true during MaxIter iterations.

Diff Detail

Event Timeline

mkazantsev created this revision.Dec 20 2022, 10:09 PM
Herald added a project: Restricted Project. · View Herald TranscriptDec 20 2022, 10:09 PM
mkazantsev requested review of this revision.Dec 20 2022, 10:09 PM
Herald added a project: Restricted Project. · View Herald TranscriptDec 20 2022, 10:09 PM
mkazantsev edited the summary of this revision. (Show Details)Dec 20 2022, 10:09 PM
mkazantsev retitled this revision from [SCEV] Help getLoopInvariantExitCondDuringFirstIterations deal with complex `umin` exit counts to [SCEV] Help getLoopInvariantExitCondDuringFirstIterations deal with complex `umin` exit counts. PR59615.Dec 20 2022, 10:18 PM
mkazantsev edited the summary of this revision. (Show Details)
nikic accepted this revision.Dec 21 2022, 2:10 AM

LGTM

This revision is now accepted and ready to land.Dec 21 2022, 2:10 AM
nikic added inline comments.Dec 21 2022, 2:14 AM
llvm/lib/Analysis/ScalarEvolution.cpp
11052

As a followup, handle umin_seq as well? Don't think poison behavior is important here.

mkazantsev added inline comments.Dec 21 2022, 2:57 AM
llvm/lib/Analysis/ScalarEvolution.cpp
11052

Not sure how to achieve that, we need umin_seq to be a max iter count... Need to think how to make a test.

This revision was landed with ongoing or failed builds.Dec 21 2022, 3:12 AM
This revision was automatically updated to reflect the committed changes.