This is an archive of the discontinued LLVM Phabricator instance.

[SCEV] Use no-self-wrap flags infered from exit structure to compute trip count
ClosedPublic

Authored by reames on Aug 24 2021, 11:31 AM.

Details

Summary

Ready for review.

The basic problem being solved is that we largely give up when encountering a trip count involving an IV which is not an addrec. We will fall back to the brute force constant eval, but that doesn't have the information about the fact that we can't cycle back through the same set of values.

There's a high level design question of whether this is the right place to handle this, and if not, where that place is.

The major alternative here would be to return a conservative upper bound, and then rely on two invocations of indvars to add the facts to the narrow IV, and then reconstruct SCEV. (I have not implemented the alternative and am not 100% sure this would work out.) That's arguably more in line with existing code, but I find this substantially easier to reason about.

Thoughts?

Diff Detail

Event Timeline

reames created this revision.Aug 24 2021, 11:31 AM
reames requested review of this revision.Aug 24 2021, 11:31 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 24 2021, 11:31 AM
efriedma added inline comments.Aug 24 2021, 12:58 PM
llvm/lib/Analysis/ScalarEvolution.cpp
11630

Can we move this logic to computeExitLimitFromICmp, or maybe even createAddRecFromPHI? It's basically independent of the predicate.

11640

cast<SCEVAddRecExpr>?

reames added inline comments.Aug 24 2021, 2:09 PM
llvm/lib/Analysis/ScalarEvolution.cpp
11630

We can move it out to the caller (computeExitLimitFromICmp), though I'd strongly prefer to land this and then do the move with separate tests added.

I'd argue not in createAddRecFromPHI as I don't want to add the use list walk which would be required there.

11640

At least in theory, this could e.g. be folded to a constant with the additional facts. It's non ideal that we wouldn't really exploit that, but this can't be a cast.

reames updated this revision to Diff 368475.Aug 24 2021, 3:25 PM
reames edited the summary of this revision. (Show Details)

Rebase over landed changes and tests

ping x 3

@efriedma Any chance you could take a look?

efriedma accepted this revision.Sep 7 2021, 4:06 PM

LGTM. Sorry about the delay.

(Please clang-format the patch.)

llvm/lib/Analysis/ScalarEvolution.cpp
11630

I'd argue not in createAddRecFromPHI as I don't want to add the use list walk which would be required there.

I think we already do a similar sort of walk to try to prove poison? Maybe worth looking into. But not a priority, sure; the nowrap is less likely to be useful in other contexts.

This revision is now accepted and ready to land.Sep 7 2021, 4:06 PM
This revision was landed with ongoing or failed builds.Sep 7 2021, 5:01 PM
This revision was automatically updated to reflect the committed changes.

After landing this, I've explored more test cases and have largely convinced myself that this should live in indvarsimplify instead. I don't fully understand why yet, but despite recording the stronger flags in SCEV, we're never able to back propagate them into the IR. (I believe it has something to do with the mutation of existing SCEVs and lack of invalidation resulting in imprecise results continuing to be returned for certain queries.) I think we'd be overall better off letting them be added to the IR, even if SCEV isn't able to leverage them until the next rebuild. The other option is that we duplicate the logic, but I'd really rather not.

I've proposed D109457 which builds on this, and I want to land it with this architecture, but once that's done, I plan on moving the whole bit of logic to indvars (with separate review).