This is an archive of the discontinued LLVM Phabricator instance.

[SCEV] Prove implication of predicates to their sign-flipped counterparts
ClosedPublic

Authored by mkazantsev on Sep 26 2021, 10:47 PM.

Details

Summary

This patch teaches SCEV two implication rules:

x <u y && y >=s 0 --> x <s y,
x <s y && y <s 0 --> x <u y.

And all equivalents with signs/parts swapped.

Diff Detail

Event Timeline

mkazantsev created this revision.Sep 26 2021, 10:47 PM
mkazantsev requested review of this revision.Sep 26 2021, 10:47 PM
Herald added a project: Restricted Project. · View Herald TranscriptSep 26 2021, 10:47 PM
nikic added inline comments.Sep 27 2021, 12:57 PM
llvm/lib/Analysis/ScalarEvolution.cpp
10793

This looks correct to me, but also rather ad-hoc -- it handles one out of multiple symmetrical patterns. For example, if we just swap both predicates (Pred == SGT and non-negative LHS) this will not trigger anymore. Or did that already get canonicalized away (in which case we should test it)?

reames added inline comments.Sep 27 2021, 3:22 PM
llvm/lib/Analysis/ScalarEvolution.cpp
10793

In line with the point Nikita makes, there's also an interesting case we should handle when RHS is known negative. In that case, ult A, B && A < 0 is enough to prove slt A, B. What's interesting to me is that we've already paid the cost of determining if A is known negative, so this becomes just a canonicalization.

All of this is building on the equivalence:
SLT A, B == (ULT A, B && signof(A) == signof(B)) || (A < 0 && B > 0)

(Note that ULT A, B + B > 0 => A > 0.)

Thinking about all this, it feels unfortunate that we're dropping to implication instead of rewriting based on equivalence. At the same time though, I don't really see an obvious code structure to use the equivalence fact though, so maybe there's nothing we can do on that front.

mkazantsev planned changes to this revision.Sep 27 2021, 9:23 PM
mkazantsev added inline comments.
llvm/lib/Analysis/ScalarEvolution.cpp
10793

As for canonicalization, we try to canonicalize so that LHS matched FoundLHS or RHS matched FoundRHS, and we also try to move constant to right hand side. So in practice, I think in some cases it will be canonicalized so that constant (which is surely a known (non) negative) will be in RHS, but it's not guaranteed for all cases. I'll add more tests to see how it reacts on different equivalent code patterns, and if it's not general enough, I'll try to make the logic smarter.

mkazantsev updated this revision to Diff 377512.Oct 6 2021, 5:47 AM
mkazantsev retitled this revision from [SCEV] Prove implication X <u Y, Y >=s 0 --> X <s Y to [SCEV] Prove implication of predicates to their sign-flipped counterparts.
mkazantsev edited the summary of this revision. (Show Details)

Generalized as widely as I could, now this covers all varieties of these.

mkazantsev edited the summary of this revision. (Show Details)Oct 6 2021, 5:47 AM
nikic accepted this revision.Oct 14 2021, 12:14 PM

LGTM

llvm/lib/Analysis/ScalarEvolution.cpp
10797

Is this malicious compliance? ^^

This revision is now accepted and ready to land.Oct 14 2021, 12:14 PM
mkazantsev added inline comments.Oct 14 2021, 8:57 PM
llvm/lib/Analysis/ScalarEvolution.cpp
10797

It's full-scaled paranoia! :)