This is an archive of the discontinued LLVM Phabricator instance.

[ValueTracking] Use ConstantRange overflow check for signed add (NFC)
ClosedPublic

Authored by nikic on Mar 16 2019, 3:28 AM.

Details

Summary

This is the same change as rL356290, but for signed add. It replaces the existing ripple logic with the overflow logic in ConstantRange, where the range is produced from KnownBits in a way that avoids wrapping the signed domain.

This is still intended as NFC, but it's somewhat less obvious here, so I'm putting up a review. It should be noted that this does make computeOverflowForSignedAdd more powerful, but only in that it can now also determine AlwaysOverflows conditions. However, none of the consumers of this method make use of this yet, so it does not impact optimization (I'll submit a followup to use AlwaysOverflows for with.overflow).

Diff Detail

Repository
rL LLVM

Event Timeline

nikic created this revision.Mar 16 2019, 3:28 AM
nagisa added a subscriber: nagisa.Mar 16 2019, 5:30 AM

This is still intended as NFC

https://reviews.llvm.org/rL356290

This is NFC: <...> This is not the case for the
signed equivalents, so I'm only changing unsigned here.

So is it NFC (not counting the AlwaysOverflows) or not?

llvm/lib/Analysis/ValueTracking.cpp
4082 ↗(On Diff #190952)

Please commit this rename directly.

4099 ↗(On Diff #190952)

return unsignedConstantRangeFromKnownBits(Known); ?

nikic added a comment.Mar 17 2019, 2:51 AM

So is it NFC (not counting the AlwaysOverflows) or not?

It is. The signed sub case wouldn't be though, as it only implements a basic sign check. At the time I wrote that I also thought that the ripple logic for signed add was more powerful than the constant range logic, but that was because I was thinking in unsigned ranges.

lebedev.ri added inline comments.Mar 17 2019, 3:08 AM
llvm/lib/Analysis/ValueTracking.cpp
4104–4105 ↗(On Diff #190952)

This seems like the only non-obvious place here.
There are tests that will fail if it is written any other way?

Actually, one more thought: why [un]signedConstantRangeFromKnownBits() are here, in ValueTracking?
Can they go into KnownBits class e.g. (as{Uns,S}ignedConstantRange())?

nikic updated this revision to Diff 191041.Mar 17 2019, 1:27 PM

Switch to ConstantRange::fromKnownBits().

Almost there ...

llvm/lib/Analysis/ValueTracking.cpp
4151 ↗(On Diff #191041)

This is still reachable, computeKnownBits(Add, ... is still more powerful than signedAddMayOverflow()?

nikic marked an inline comment as done.Mar 17 2019, 1:49 PM
nikic added inline comments.
llvm/lib/Analysis/ValueTracking.cpp
4151 ↗(On Diff #191041)

computeKnownBitsFromOperator() itself is not more powerful than signedAddMayOverflow (or the existing ripple logic). However, computeKnownBits() also computes known bits from assumes on the add, which is what this call is really for. I've created D59473 to both make that more explicit and avoid a redundant known bits calculation.

lebedev.ri accepted this revision.Mar 17 2019, 1:52 PM

Looks good as a NFC to me.

llvm/lib/Analysis/ValueTracking.cpp
4132 ↗(On Diff #191041)

I'm guessing OverflowResult won't grow, so there is no danger of accidentally doing the wrong thing here.

This revision is now accepted and ready to land.Mar 17 2019, 1:52 PM
This revision was automatically updated to reflect the committed changes.
nikic marked an inline comment as done.Mar 17 2019, 2:32 PM
nikic added inline comments.
llvm/lib/Analysis/ValueTracking.cpp
4132 ↗(On Diff #191041)

I do want to grow it a bit... I'd like to split up the AlwaysOverflows case into AlwaysOverflowsLow and AlwaysOverflowsHigh, so that it can be used in saturating math optimization. But that shouldn't have any impact on this check :)