This is an archive of the discontinued LLVM Phabricator instance.

[ValueTracking] ConstantRange based overflow detection for unsigned add/sub
ClosedPublic

Authored by nikic on Mar 14 2019, 2:21 PM.

Details

Summary

Based on D59193 and rL356290 this makes some improvements to the computeOverflowForUnsignedAdd/Sub functions in ValueTracking:

  • Additionally call computeConstantRange() and intersect it with the KnownBits range.
  • Extend computeConstantRange() to compute constant ranges for constant integers and constant integer vectors.

The main tests are based on saturating math intrinsics, though a couple nuw's also get inferred in existing tests.

Diff Detail

Repository
rL LLVM

Event Timeline

nikic created this revision.Mar 14 2019, 2:21 PM
  • The KnownBits are converted into ConstantRanges and the unsigned(Add|Sub)MayOverflow method on ConstantRange is used to determine the overflow condition. This part is NFC because this effectively matches what the code already did in a more explicit way.

Can you please at least separate the NFC ^ part?

  • Additionally call computeConstantRange() and intersect it with the KnownBits range.
  • Extend computeConstantRange() to compute constant ranges for constant integers and constant integer vectors.
nikic updated this revision to Diff 190864.Mar 15 2019, 11:56 AM
nikic edited the summary of this revision. (Show Details)

Rebase over rL356290, which was the NFC portion of this change.

lebedev.ri added inline comments.Mar 15 2019, 12:06 PM
llvm/lib/Analysis/ValueTracking.cpp
5708 ↗(On Diff #190864)

This is used in simplifyICmpWithConstant(). thus i think this can be split off too,
although i'm not sure if that will show any test changes as-is?

nikic marked an inline comment as done.Mar 15 2019, 12:39 PM
nikic added inline comments.
llvm/lib/Analysis/ValueTracking.cpp
5708 ↗(On Diff #190864)

For this code to apply in simplifyICmpWithConstant() it would have to be an icmp with both operands constant, which will already be folded earlier. (This code is split off from simplifyICmpWithConstant, which is why the constant handling was missing: It's not needed for that usage.)

nagisa added a subscriber: nagisa.Mar 16 2019, 5:30 AM

Hmm, this looks reasonable to me, @spatel ?
Are there any concerns of performance impact of using ConstantRange() here ?
Though i do think it does pull it's weight.

llvm/lib/Analysis/ValueTracking.cpp
4212 ↗(On Diff #190864)

When committing, it might be a good idea to commit the computeOverflowForUnsignedSub() change as a follow-up, as usual..

5708 ↗(On Diff #190864)

Oh right, thanks for explanation.

nikic added a comment.Mar 17 2019, 3:16 AM

Are there any concerns of performance impact of using ConstantRange() here ?

Right now the computeConstantRange() function only looks at one instruction to determine the constant range, so it should be rather cheap compared to the computeKnownBits() call (and in the signed case, additionally ComputeNumSignBits()).

For the longer-term future, I think it would make sense to turn the computeConstantRange() function into a recursive computation, in which case it could subsume both computeKnownBits and ComputeNumSignBits for the purpose of overflow checks (which are, in the end, purely range based). But getting to that point would be quite a bit of work...

Hmm, this looks reasonable to me, @spatel ?
Are there any concerns of performance impact of using ConstantRange() here ?
Though i do think it does pull it's weight.

At this point, any change to heavily used ValueTracking calls may be cause for compile-time concern.
I'd hope that ConstantRange can be optimized to just 2 ints in the usual case, so it should be fast (as we assume for KnownBits too I think).
To be safe, we could do a test-suite or stage2 compile and see if that shows regressions, but the optimizations in the tests do look nice. :)

llvm/lib/Analysis/ValueTracking.cpp
5717 ↗(On Diff #190864)

By limiting to ConstantDataVector, are we excluding weird (non-power-of-2 bitwidths or number of elements) types? Is that intentional?

nikic updated this revision to Diff 191127.Mar 18 2019, 11:01 AM

Rebase and remove constant vector code.

nikic marked an inline comment as done.Mar 18 2019, 11:05 AM
nikic added inline comments.
llvm/lib/Analysis/ValueTracking.cpp
5717 ↗(On Diff #190864)

Nope, that's not intentional. This is just me being fuzzy on the Constant hierarchy...

I've dropped the non-splat vector handling code from this revision and will handle this properly in a followup.

spatel accepted this revision.Mar 18 2019, 3:36 PM

LGTM

This revision is now accepted and ready to land.Mar 18 2019, 3:36 PM
lebedev.ri accepted this revision.Mar 19 2019, 12:18 AM

Hmm, this looks reasonable to me

This revision was automatically updated to reflect the committed changes.