[llvm] r358340 - [ConstantRange] Disallow NUW | NSW in makeGuaranteedNoWrapRegion()
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Sat Apr 13 12:43:45 PDT 2019
Author: nikic
Date: Sat Apr 13 12:43:45 2019
New Revision: 358340
URL: http://llvm.org/viewvc/llvm-project?rev=358340&view=rev
Log:
[ConstantRange] Disallow NUW | NSW in makeGuaranteedNoWrapRegion()
As motivated in D60598, this drops support for specifying both NUW and
NSW in makeGuaranteedNoWrapRegion(). None of the users of this function
currently make use of this.
When both NUW and NSW are specified, the exact nowrap region has two
disjoint parts and makeGNWR() returns one of them. This result doesn't
seem to be useful for anything, but makes the semantics of the function
fuzzier.
Differential Revision: https://reviews.llvm.org/D60632
Modified:
llvm/trunk/include/llvm/IR/ConstantRange.h
llvm/trunk/lib/IR/ConstantRange.cpp
llvm/trunk/unittests/IR/ConstantRangeTest.cpp
Modified: llvm/trunk/include/llvm/IR/ConstantRange.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/ConstantRange.h?rev=358340&r1=358339&r2=358340&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/ConstantRange.h (original)
+++ llvm/trunk/include/llvm/IR/ConstantRange.h Sat Apr 13 12:43:45 2019
@@ -116,16 +116,10 @@ public:
static ConstantRange makeExactICmpRegion(CmpInst::Predicate Pred,
const APInt &Other);
- /// Return the largest range containing all X such that "X BinOpC Y" is
+ /// Return the exact range containing all X such that "X BinOpC Y" is
/// guaranteed not to wrap (overflow) for all Y in Other.
///
- /// If only one of NoUnsignedWrap or NoSignedWrap is specified, the returned
- /// range is exact: It contains *all* possible values of X for which
- /// "X BinOpC Y" does not wrap. However, if both NUW and NSW are specified, it
- /// may return only a subset of non-wrapping values. In this case the
- /// returned region cannot be used to constrain X's range. E.g. in the
- /// fourth example, "(-2) + 1" is both nsw and nuw (so the "X" could be -2),
- /// but (-2) is not in the set returned.
+ /// NoWrapKind must be one of OBO::NoUnsignedWrap or OBO::NoSignedWrap.
///
/// Examples:
/// typedef OverflowingBinaryOperator OBO;
@@ -133,13 +127,9 @@ public:
/// MGNR(Add, [i8 1, 2), OBO::NoSignedWrap) == [-128, 127)
/// MGNR(Add, [i8 1, 2), OBO::NoUnsignedWrap) == [0, -1)
/// MGNR(Add, [i8 0, 1), OBO::NoUnsignedWrap) == Full Set
- /// MGNR(Add, [i8 1, 2), OBO::NoUnsignedWrap | OBO::NoSignedWrap)
- /// == [0,INT_MAX)
/// MGNR(Add, [i8 -1, 6), OBO::NoSignedWrap) == [INT_MIN+1, INT_MAX-4)
/// MGNR(Sub, [i8 1, 2), OBO::NoSignedWrap) == [-127, 128)
/// MGNR(Sub, [i8 1, 2), OBO::NoUnsignedWrap) == [1, 0)
- /// MGNR(Sub, [i8 1, 2), OBO::NoUnsignedWrap | OBO::NoSignedWrap)
- /// == [1,INT_MAX)
static ConstantRange makeGuaranteedNoWrapRegion(Instruction::BinaryOps BinOp,
const ConstantRange &Other,
unsigned NoWrapKind);
Modified: llvm/trunk/lib/IR/ConstantRange.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/ConstantRange.cpp?rev=358340&r1=358339&r2=358340&view=diff
==============================================================================
--- llvm/trunk/lib/IR/ConstantRange.cpp (original)
+++ llvm/trunk/lib/IR/ConstantRange.cpp Sat Apr 13 12:43:45 2019
@@ -214,8 +214,7 @@ ConstantRange::makeGuaranteedNoWrapRegio
assert(Instruction::isBinaryOp(BinOp) && "Binary operators only!");
assert((NoWrapKind == OBO::NoSignedWrap ||
- NoWrapKind == OBO::NoUnsignedWrap ||
- NoWrapKind == (OBO::NoUnsignedWrap | OBO::NoSignedWrap)) &&
+ NoWrapKind == OBO::NoUnsignedWrap) &&
"NoWrapKind invalid!");
unsigned BitWidth = Other.getBitWidth();
@@ -231,11 +230,12 @@ ConstantRange::makeGuaranteedNoWrapRegio
if (C->isNullValue())
// Full set: nothing signed / unsigned wraps when added to 0.
return getFull(BitWidth);
- if (NoWrapKind & OBO::NoUnsignedWrap)
- Result =
- SubsetIntersect(Result, ConstantRange(APInt::getNullValue(BitWidth),
- -Other.getUnsignedMax()));
- if (NoWrapKind & OBO::NoSignedWrap) {
+
+ if (NoWrapKind == OBO::NoUnsignedWrap)
+ return ConstantRange(APInt::getNullValue(BitWidth),
+ -Other.getUnsignedMax());
+
+ if (NoWrapKind == OBO::NoSignedWrap) {
const APInt &SignedMin = Other.getSignedMin();
const APInt &SignedMax = Other.getSignedMax();
if (SignedMax.isStrictlyPositive())
@@ -256,11 +256,12 @@ ConstantRange::makeGuaranteedNoWrapRegio
if (C->isNullValue())
// Full set: nothing signed / unsigned wraps when subtracting 0.
return getFull(BitWidth);
- if (NoWrapKind & OBO::NoUnsignedWrap)
- Result =
- SubsetIntersect(Result, ConstantRange(Other.getUnsignedMax(),
- APInt::getMinValue(BitWidth)));
- if (NoWrapKind & OBO::NoSignedWrap) {
+
+ if (NoWrapKind == OBO::NoUnsignedWrap)
+ return ConstantRange(Other.getUnsignedMax(),
+ APInt::getMinValue(BitWidth));
+
+ if (NoWrapKind == OBO::NoSignedWrap) {
const APInt &SignedMin = Other.getSignedMin();
const APInt &SignedMax = Other.getSignedMax();
if (SignedMax.isStrictlyPositive())
@@ -275,13 +276,8 @@ ConstantRange::makeGuaranteedNoWrapRegio
APInt::getSignedMinValue(BitWidth) + SignedMin));
}
return Result;
- case Instruction::Mul: {
- if (NoWrapKind == (OBO::NoSignedWrap | OBO::NoUnsignedWrap)) {
- return SubsetIntersect(
- makeGuaranteedNoWrapRegion(BinOp, Other, OBO::NoSignedWrap),
- makeGuaranteedNoWrapRegion(BinOp, Other, OBO::NoUnsignedWrap));
- }
+ case Instruction::Mul: {
// Equivalent to calling makeGuaranteedNoWrapRegion() on [V, V+1).
const bool Unsigned = NoWrapKind == OBO::NoUnsignedWrap;
const auto makeSingleValueRegion = [Unsigned,
Modified: llvm/trunk/unittests/IR/ConstantRangeTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/ConstantRangeTest.cpp?rev=358340&r1=358339&r2=358340&view=diff
==============================================================================
--- llvm/trunk/unittests/IR/ConstantRangeTest.cpp (original)
+++ llvm/trunk/unittests/IR/ConstantRangeTest.cpp Sat Apr 13 12:43:45 2019
@@ -922,12 +922,6 @@ TEST(ConstantRange, MakeGuaranteedNoWrap
EXPECT_FALSE(NSWRegion.isEmptySet());
- auto NoWrapRegion = ConstantRange::makeGuaranteedNoWrapRegion(
- Instruction::Add, C, OBO::NoSignedWrap | OBO::NoUnsignedWrap);
-
- EXPECT_FALSE(NoWrapRegion.isEmptySet());
- EXPECT_TRUE(NUWRegion.intersectWith(NSWRegion).contains(NoWrapRegion));
-
for (APInt I = NUWRegion.getLower(), E = NUWRegion.getUpper(); I != E;
++I) {
bool Overflow = false;
@@ -941,17 +935,6 @@ TEST(ConstantRange, MakeGuaranteedNoWrap
(void)I.sadd_ov(C, Overflow);
EXPECT_FALSE(Overflow);
}
-
- for (APInt I = NoWrapRegion.getLower(), E = NoWrapRegion.getUpper(); I != E;
- ++I) {
- bool Overflow = false;
-
- (void)I.sadd_ov(C, Overflow);
- EXPECT_FALSE(Overflow);
-
- (void)I.uadd_ov(C, Overflow);
- EXPECT_FALSE(Overflow);
- }
}
for (int Const : {0, -1, -2, 1, 2, IntMin4Bits, IntMax4Bits}) {
@@ -967,12 +950,6 @@ TEST(ConstantRange, MakeGuaranteedNoWrap
EXPECT_FALSE(NSWRegion.isEmptySet());
- auto NoWrapRegion = ConstantRange::makeGuaranteedNoWrapRegion(
- Instruction::Sub, C, OBO::NoSignedWrap | OBO::NoUnsignedWrap);
-
- EXPECT_FALSE(NoWrapRegion.isEmptySet());
- EXPECT_TRUE(NUWRegion.intersectWith(NSWRegion).contains(NoWrapRegion));
-
for (APInt I = NUWRegion.getLower(), E = NUWRegion.getUpper(); I != E;
++I) {
bool Overflow = false;
@@ -986,17 +963,6 @@ TEST(ConstantRange, MakeGuaranteedNoWrap
(void)I.ssub_ov(C, Overflow);
EXPECT_FALSE(Overflow);
}
-
- for (APInt I = NoWrapRegion.getLower(), E = NoWrapRegion.getUpper(); I != E;
- ++I) {
- bool Overflow = false;
-
- (void)I.ssub_ov(C, Overflow);
- EXPECT_FALSE(Overflow);
-
- (void)I.usub_ov(C, Overflow);
- EXPECT_FALSE(Overflow);
- }
}
auto NSWForAllValues = ConstantRange::makeGuaranteedNoWrapRegion(
@@ -1023,32 +989,14 @@ TEST(ConstantRange, MakeGuaranteedNoWrap
EXPECT_TRUE(NUWForAllValues.isSingleElement() &&
NUWForAllValues.getSingleElement()->isMaxValue());
- auto NUWAndNSWForAllValues = ConstantRange::makeGuaranteedNoWrapRegion(
- Instruction::Add, ConstantRange(32, /* isFullSet = */ true),
- OBO::NoUnsignedWrap | OBO::NoSignedWrap);
- EXPECT_TRUE(NUWAndNSWForAllValues.isSingleElement() &&
- NUWAndNSWForAllValues.getSingleElement()->isMinValue());
-
- NUWAndNSWForAllValues = ConstantRange::makeGuaranteedNoWrapRegion(
- Instruction::Sub, ConstantRange(32, /* isFullSet = */ true),
- OBO::NoUnsignedWrap | OBO::NoSignedWrap);
- EXPECT_TRUE(NUWAndNSWForAllValues.isSingleElement() &&
- NUWAndNSWForAllValues.getSingleElement()->isMaxValue());
-
EXPECT_TRUE(ConstantRange::makeGuaranteedNoWrapRegion(
Instruction::Add, APInt(32, 0), OBO::NoUnsignedWrap).isFullSet());
EXPECT_TRUE(ConstantRange::makeGuaranteedNoWrapRegion(
Instruction::Add, APInt(32, 0), OBO::NoSignedWrap).isFullSet());
EXPECT_TRUE(ConstantRange::makeGuaranteedNoWrapRegion(
- Instruction::Add, APInt(32, 0),
- OBO::NoUnsignedWrap | OBO::NoSignedWrap).isFullSet());
- EXPECT_TRUE(ConstantRange::makeGuaranteedNoWrapRegion(
Instruction::Sub, APInt(32, 0), OBO::NoUnsignedWrap).isFullSet());
EXPECT_TRUE(ConstantRange::makeGuaranteedNoWrapRegion(
Instruction::Sub, APInt(32, 0), OBO::NoSignedWrap).isFullSet());
- EXPECT_TRUE(ConstantRange::makeGuaranteedNoWrapRegion(
- Instruction::Sub, APInt(32, 0),
- OBO::NoUnsignedWrap | OBO::NoSignedWrap).isFullSet());
ConstantRange OneToFive(APInt(32, 1), APInt(32, 6));
EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
@@ -1058,10 +1006,6 @@ TEST(ConstantRange, MakeGuaranteedNoWrap
EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
Instruction::Add, OneToFive, OBO::NoUnsignedWrap),
ConstantRange(APInt::getMinValue(32), APInt::getMinValue(32) - 5));
- EXPECT_EQ(
- ConstantRange::makeGuaranteedNoWrapRegion(
- Instruction::Add, OneToFive, OBO::NoUnsignedWrap | OBO::NoSignedWrap),
- ConstantRange(APInt::getMinValue(32), APInt::getSignedMaxValue(32) - 4));
EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
Instruction::Sub, OneToFive, OBO::NoSignedWrap),
ConstantRange(APInt::getSignedMinValue(32) + 5,
@@ -1069,10 +1013,6 @@ TEST(ConstantRange, MakeGuaranteedNoWrap
EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
Instruction::Sub, OneToFive, OBO::NoUnsignedWrap),
ConstantRange(APInt::getMinValue(32) + 5, APInt::getMinValue(32)));
- EXPECT_EQ(
- ConstantRange::makeGuaranteedNoWrapRegion(
- Instruction::Sub, OneToFive, OBO::NoUnsignedWrap | OBO::NoSignedWrap),
- ConstantRange(APInt::getMinValue(32) + 5, APInt::getSignedMinValue(32)));
ConstantRange MinusFiveToMinusTwo(APInt(32, -5), APInt(32, -1));
EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
@@ -1083,10 +1023,6 @@ TEST(ConstantRange, MakeGuaranteedNoWrap
Instruction::Add, MinusFiveToMinusTwo, OBO::NoUnsignedWrap),
ConstantRange(APInt(32, 0), APInt(32, 2)));
EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
- Instruction::Add, MinusFiveToMinusTwo,
- OBO::NoUnsignedWrap | OBO::NoSignedWrap),
- ConstantRange(APInt(32, 0), APInt(32, 2)));
- EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
Instruction::Sub, MinusFiveToMinusTwo, OBO::NoSignedWrap),
ConstantRange(APInt::getSignedMinValue(32),
APInt::getSignedMaxValue(32) - 4));
@@ -1094,11 +1030,6 @@ TEST(ConstantRange, MakeGuaranteedNoWrap
Instruction::Sub, MinusFiveToMinusTwo, OBO::NoUnsignedWrap),
ConstantRange(APInt::getMaxValue(32) - 1,
APInt::getMinValue(32)));
- EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
- Instruction::Sub, MinusFiveToMinusTwo,
- OBO::NoUnsignedWrap | OBO::NoSignedWrap),
- ConstantRange(APInt::getMaxValue(32) - 1,
- APInt::getMinValue(32)));
ConstantRange MinusOneToOne(APInt(32, -1), APInt(32, 2));
EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
@@ -1109,10 +1040,6 @@ TEST(ConstantRange, MakeGuaranteedNoWrap
Instruction::Add, MinusOneToOne, OBO::NoUnsignedWrap),
ConstantRange(APInt(32, 0), APInt(32, 1)));
EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
- Instruction::Add, MinusOneToOne,
- OBO::NoUnsignedWrap | OBO::NoSignedWrap),
- ConstantRange(APInt(32, 0), APInt(32, 1)));
- EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
Instruction::Sub, MinusOneToOne, OBO::NoSignedWrap),
ConstantRange(APInt::getSignedMinValue(32) + 1,
APInt::getSignedMinValue(32) - 1));
@@ -1120,11 +1047,6 @@ TEST(ConstantRange, MakeGuaranteedNoWrap
Instruction::Sub, MinusOneToOne, OBO::NoUnsignedWrap),
ConstantRange(APInt::getMaxValue(32),
APInt::getMinValue(32)));
- EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
- Instruction::Sub, MinusOneToOne,
- OBO::NoUnsignedWrap | OBO::NoSignedWrap),
- ConstantRange(APInt::getMaxValue(32),
- APInt::getMinValue(32)));
ConstantRange One(APInt(32, 1), APInt(32, 2));
EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
@@ -1134,10 +1056,6 @@ TEST(ConstantRange, MakeGuaranteedNoWrap
EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
Instruction::Add, One, OBO::NoUnsignedWrap),
ConstantRange(APInt::getMinValue(32), APInt::getMaxValue(32)));
- EXPECT_EQ(
- ConstantRange::makeGuaranteedNoWrapRegion(
- Instruction::Add, One, OBO::NoUnsignedWrap | OBO::NoSignedWrap),
- ConstantRange(APInt(32, 0), APInt::getSignedMaxValue(32)));
EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
Instruction::Sub, One, OBO::NoSignedWrap),
ConstantRange(APInt::getSignedMinValue(32) + 1,
@@ -1145,10 +1063,6 @@ TEST(ConstantRange, MakeGuaranteedNoWrap
EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
Instruction::Sub, One, OBO::NoUnsignedWrap),
ConstantRange(APInt::getMinValue(32) + 1, APInt::getMinValue(32)));
- EXPECT_EQ(
- ConstantRange::makeGuaranteedNoWrapRegion(
- Instruction::Sub, One, OBO::NoUnsignedWrap | OBO::NoSignedWrap),
- ConstantRange(APInt::getMinValue(32) + 1, APInt::getSignedMinValue(32)));
}
template<typename Fn>
@@ -1341,26 +1255,6 @@ TEST(ConstantRange, MakeGuaranteedNoWrap
}
}
}
-
-TEST(ConstantRange, MakeGuaranteedNoWrapRegionMulUnsignedAndSignedSingleValue) {
- typedef OverflowingBinaryOperator OBO;
-
- for (uint64_t I = std::numeric_limits<uint8_t>::min();
- I <= std::numeric_limits<uint8_t>::max(); I++) {
- auto Range = ConstantRange::makeGuaranteedNoWrapRegion(
- Instruction::Mul, ConstantRange(APInt(8, I), APInt(8, I + 1)),
- OBO::NoUnsignedWrap | OBO::NoSignedWrap);
-
- for (uint64_t V = std::numeric_limits<uint8_t>::min();
- V <= std::numeric_limits<uint8_t>::max(); V++) {
- bool UOverflow;
- (void)APInt(8, I).umul_ov(APInt(8, V), UOverflow);
- bool SOverflow;
- (void)APInt(8, I).smul_ov(APInt(8, V), SOverflow);
- EXPECT_EQ(!(UOverflow || SOverflow), Range.contains(APInt(8, V)));
- }
- }
-}
TEST(ConstantRange, MakeGuaranteedNoWrapRegionMulUnsignedRange) {
typedef OverflowingBinaryOperator OBO;
More information about the llvm-commits
mailing list