This is an archive of the discontinued LLVM Phabricator instance.

[ConstantRange] Add isNegative() and isNonNegative() methods
ClosedPublic

Authored by nikic on Apr 4 2019, 6:28 AM.

Details

Summary

Add isNegative() and isNonNegative() methods to ConstantRange, which determine whether all values in the constant range are negative/non-negative. The naming follows KnownBits, where these methods have the same meaning. Could also use something like isAllNegative() and isAllNonNegative(), if that's more clear.

Motivation is to replace existing KnownBits calls when switching over computeOverflowForSignedAdd() to use ranges only (https://github.com/llvm-mirror/llvm/blob/master/lib/Analysis/ValueTracking.cpp#L4154).

Diff Detail

Repository
rL LLVM

Event Timeline

nikic created this revision.Apr 4 2019, 6:28 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 4 2019, 6:28 AM

Looks good.

The naming follows KnownBits, where these methods have the same meaning.
Could also use something like isAllNegative() and isAllNonNegative(), if that's more clear.

I think,
In KnownBits case, we either know signbit (and thus the sign), or we don't.
If we do know it, then we can answer if that KnownBits is negative / non-negative.

Here, in ConstantRange, we don't just know sign. We know *range*.
So negative/non-negative becomes ambigious, at least to me.
Does it mean that the *whole* range is like that (the intended meaning),
or only at least some part of the range?

So yes, i would personally prefer the variants with All.

llvm/lib/IR/ConstantRange.cpp
393–395 ↗(On Diff #193697)

Hm, i would prefer to do

if(isEmptySet())
  return true; // Empty set is all-negative.
if(isFullSet())
  return false; // Full set is not all-negative.

since it is arguably more obvious.
Not sure it is better though.

llvm/unittests/IR/ConstantRangeTest.cpp
1648 ↗(On Diff #193697)

Can you also explicitly check full sets?

nikic updated this revision to Diff 193716.Apr 4 2019, 8:08 AM
nikic marked 2 inline comments as done.

Rename to isAllNegative() and isAllNonNegative(), explicitly check empty/full set in isNegative() implementation, add explicit test for full ranges.

lebedev.ri accepted this revision.Apr 4 2019, 8:23 AM

LG, thank you.

llvm/unittests/IR/ConstantRangeTest.cpp
1664 ↗(On Diff #193716)

Hmm, can we also check that

if(!CR.isEmptySet() && !CR.isFullSet())
  EXPECT_NE(AllNegative, AllNonNegative);

?

This revision is now accepted and ready to land.Apr 4 2019, 8:23 AM
nikic marked an inline comment as done.Apr 4 2019, 8:31 AM
nikic added inline comments.
llvm/unittests/IR/ConstantRangeTest.cpp
1664 ↗(On Diff #193716)

This doesn't hold in general, as AllNegative and AllNonNegative may both be false for ranges that cross zero (but are not necessarily full). E.g. [-5, 6) is neither negative nor non-negative.

lebedev.ri added inline comments.Apr 4 2019, 8:40 AM
llvm/unittests/IR/ConstantRangeTest.cpp
1664 ↗(On Diff #193716)

Hmm, of course it is.
I believe i meant EXPECT_FALSE(AllNegative && AllNonNegative);.

This revision was automatically updated to reflect the committed changes.