This is an archive of the discontinued LLVM Phabricator instance.

[SCEV] Attempt to define what flags are legal on a SCEV
ClosedPublic

Authored by reames on Sep 9 2021, 3:54 PM.

Details

Summary

This is an attempt to define what the current semantics are closest too. The existence of D106852 does imply these semantics are not 100% correct, but that piece of code is one of handful of places which are known to violate them. https://bugs.llvm.org/show_bug.cgi?id=51817 tracks the list of currently known violations of the proposed rules so that they don't get forgotten.

This is inspired by the discussion on D106852. If we accept these semantics, then the resolution to D106852 becomes obvious, if painful.

Diff Detail

Event Timeline

reames created this revision.Sep 9 2021, 3:54 PM
reames requested review of this revision.Sep 9 2021, 3:54 PM
Herald added a project: Restricted Project. · View Herald TranscriptSep 9 2021, 3:54 PM

Description makes sense to me.

llvm/include/llvm/Analysis/ScalarEvolution.h
123

I think we assert that the operands of an AddRec are loop-invariant, so the extra text isn't relevant.

132

Existence.

reames updated this revision to Diff 371754.Sep 9 2021, 5:15 PM

Simplify per Eli's observation

reames updated this revision to Diff 371755.Sep 9 2021, 5:16 PM
reames marked 2 inline comments as done.

And the typo fix missed the first time

llvm/include/llvm/Analysis/ScalarEvolution.h
123

I'd thought we'd allowed this, but a quick test seems to say no, so removed.

I think it's too pessmistic with regard of users. Imagine the following situation: we have %a and %b which are SCEVUnknown, and the only their (SCEV) user is a + b which is guarded by conditions a <u 100, b <u 100.

We might have a right to say that a + b is nuw and nsw, since the only place where it is used is guarded by conditions that imply this. But in the suggested definition, basically, guarding conditions don't matter and we cannot infer any flags from them. It means that we can still prove some facts, but it will take us walking dom tree every time we need it.

On the other hand, I understand the motivation, and implications of alternative (use-based) approach for SCEV expander. So what I said is just a highlight of a problem we are going to inherit, not a con against this patch.

If everyone's agree then it's fine for me.

llvm/include/llvm/Analysis/ScalarEvolution.h
118

described?

reames added a comment.EditedSep 10 2021, 10:51 AM

I think @mkazantsev has pointed out something a bit nasty. The current applyLoopGuard code does use contextual knowledge to build new SCEVs, and does appear to violate the proposed rules here. (e.g. it produces a new SCEV with flags specific to the context without consideration of the defining scope.) Skimming the code, I only see one use that appears invalid by the new rules (the urem matching).

I think our best option is to proceed with this definition and consider that one cases as bug. We need to get to something consistent before we can start moving towards a better design.

edit: Treating this as a bug appears to be low impact. A local change which uses conservative flags for the multiply in the urem case causes zero test diffs.

reames updated this revision to Diff 371968.Sep 10 2021, 11:09 AM
reames edited the summary of this revision. (Show Details)

Fix the violation of proposed rules noticed in applyLoopGuards. No test impact.

reames updated this revision to Diff 371969.Sep 10 2021, 11:10 AM

I seem to like to forget typo fixes when reving patches...

efriedma added inline comments.Sep 10 2021, 11:21 AM
llvm/lib/Analysis/ScalarEvolution.cpp
13512 ↗(On Diff #371969)

I think the expression here is naturally nuw: (X /u Y) * Y must be less than or equal to X. No idea why it's getting marked nsw, though.

Anyway, we can deal with various violations (e.g. ScalarEvolution::getGEPExpr) in future patches.

reames added inline comments.Sep 10 2021, 12:32 PM
llvm/lib/Analysis/ScalarEvolution.cpp
13512 ↗(On Diff #371969)

I agree on the definitional nature of the nuw. I'll simplify point out that because it is definitional, it should be in getMulExpr, not here. Interestingly, it's not.

I'd still argue for removing here since it appears to have no test coverage.

I hadn't noticed the issue in getGEPExpr previously, that one is nasty. I'm going to go ahead and file a bug to keep track of the issues as we find them.

reames edited the summary of this revision. (Show Details)Sep 10 2021, 12:39 PM
reames edited the summary of this revision. (Show Details)Sep 14 2021, 10:30 AM
reames updated this revision to Diff 372512.Sep 14 2021, 10:32 AM

Remove the applyLoopGuard fix as the preference seems to be to handle that in a separate change.

Reviewers, are we comfortable with this path forward? If so, I'd like to go ahead and land this so that I can start working on the fixes for the known violations (noted in the bug linked in the review comment).

efriedma accepted this revision.Sep 14 2021, 11:07 AM
This revision is now accepted and ready to land.Sep 14 2021, 11:07 AM
This revision was automatically updated to reflect the committed changes.