[llvm] r262637 - [ConstantRange] Generalize makeGuaranteedNoWrapRegion to work on ranges
Sanjoy Das via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 3 10:31:17 PST 2016
Author: sanjoy
Date: Thu Mar 3 12:31:16 2016
New Revision: 262637
URL: http://llvm.org/viewvc/llvm-project?rev=262637&view=rev
Log:
[ConstantRange] Generalize makeGuaranteedNoWrapRegion to work on ranges
This will be used in a later patch to ScalarEvolution. Right now only
the unit tests exercise the newly added code.
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=262637&r1=262636&r2=262637&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/ConstantRange.h (original)
+++ llvm/trunk/include/llvm/IR/ConstantRange.h Thu Mar 3 12:31:16 2016
@@ -82,24 +82,26 @@ public:
static ConstantRange makeSatisfyingICmpRegion(CmpInst::Predicate Pred,
const ConstantRange &Other);
- /// Return the largest range containing all X such that "X BinOpC C" is
- /// guaranteed not to wrap (overflow).
+ /// Return the largest range containing all X such that "X BinOpC Y" is
+ /// guaranteed not to wrap (overflow) for all Y in Other.
///
/// NB! The returned set does *not* contain **all** possible values of X for
- /// which "X BinOpC C" does not wrap -- some viable values of X may be
+ /// which "X BinOpC Y" does not wrap -- some viable values of X may be
/// missing, so you cannot use this to contrain X's range. E.g. in the last
/// example, "(-2) + 1" is both nsw and nuw (so the "X" could be -2), but (-2)
/// is not in the set returned.
///
- /// Example:
+ /// Examples:
/// typedef OverflowingBinaryOperator OBO;
- /// makeNoWrapRegion(Add, i8 1, OBO::NoSignedWrap) == [-128, 127)
- /// makeNoWrapRegion(Add, i8 1, OBO::NoUnsignedWrap) == [0, -1)
- /// makeNoWrapRegion(Add, i8 0, OBO::NoUnsignedWrap) == Full Set
- /// makeNoWrapRegion(Add, i8 1, OBO::NoUnsignedWrap | OBO::NoSignedWrap) ==
- /// [0,INT_MAX)
+ /// #define MGNR makeGuaranteedNoWrapRegion
+ /// 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)
static ConstantRange makeGuaranteedNoWrapRegion(Instruction::BinaryOps BinOp,
- const APInt &C,
+ const ConstantRange &Other,
unsigned NoWrapKind);
/// Return the lower value for this range.
Modified: llvm/trunk/lib/IR/ConstantRange.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/ConstantRange.cpp?rev=262637&r1=262636&r2=262637&view=diff
==============================================================================
--- llvm/trunk/lib/IR/ConstantRange.cpp (original)
+++ llvm/trunk/lib/IR/ConstantRange.cpp Thu Mar 3 12:31:16 2016
@@ -129,7 +129,8 @@ ConstantRange ConstantRange::makeSatisfy
ConstantRange
ConstantRange::makeGuaranteedNoWrapRegion(Instruction::BinaryOps BinOp,
- const APInt &C, unsigned NoWrapKind) {
+ const ConstantRange &Other,
+ unsigned NoWrapKind) {
typedef OverflowingBinaryOperator OBO;
// Computes the intersection of CR0 and CR1. It is different from
@@ -149,29 +150,36 @@ ConstantRange::makeGuaranteedNoWrapRegio
NoWrapKind == (OBO::NoUnsignedWrap | OBO::NoSignedWrap)) &&
"NoWrapKind invalid!");
- unsigned BitWidth = C.getBitWidth();
+ unsigned BitWidth = Other.getBitWidth();
if (BinOp != Instruction::Add)
// Conservative answer: empty set
return ConstantRange(BitWidth, false);
- if (C.isMinValue())
- // Full set: nothing signed / unsigned wraps when added to 0.
- return ConstantRange(BitWidth);
+ if (auto *C = Other.getSingleElement())
+ if (C->isMinValue())
+ // Full set: nothing signed / unsigned wraps when added to 0.
+ return ConstantRange(BitWidth);
ConstantRange Result(BitWidth);
if (NoWrapKind & OBO::NoUnsignedWrap)
- Result = SubsetIntersect(Result,
- ConstantRange(APInt::getNullValue(BitWidth), -C));
+ Result =
+ SubsetIntersect(Result, ConstantRange(APInt::getNullValue(BitWidth),
+ -Other.getUnsignedMax()));
if (NoWrapKind & OBO::NoSignedWrap) {
- if (C.isStrictlyPositive())
+ APInt SignedMin = Other.getSignedMin();
+ APInt SignedMax = Other.getSignedMax();
+
+ if (SignedMax.isStrictlyPositive())
Result = SubsetIntersect(
- Result, ConstantRange(APInt::getSignedMinValue(BitWidth),
- APInt::getSignedMinValue(BitWidth) - C));
- else
+ Result,
+ ConstantRange(APInt::getSignedMinValue(BitWidth),
+ APInt::getSignedMinValue(BitWidth) - SignedMax));
+
+ if (SignedMin.isNegative())
Result = SubsetIntersect(
- Result, ConstantRange(APInt::getSignedMinValue(BitWidth) - C,
+ Result, ConstantRange(APInt::getSignedMinValue(BitWidth) - SignedMin,
APInt::getSignedMinValue(BitWidth)));
}
Modified: llvm/trunk/unittests/IR/ConstantRangeTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/ConstantRangeTest.cpp?rev=262637&r1=262636&r2=262637&view=diff
==============================================================================
--- llvm/trunk/unittests/IR/ConstantRangeTest.cpp (original)
+++ llvm/trunk/unittests/IR/ConstantRangeTest.cpp Thu Mar 3 12:31:16 2016
@@ -657,6 +657,63 @@ TEST(ConstantRange, MakeOverflowingRegio
EXPECT_FALSE(Overflow);
}
}
+
+ auto NSWForAllValues = ConstantRange::makeGuaranteedNoWrapRegion(
+ Instruction::Add, ConstantRange(32, /* isFullSet = */ true),
+ OBO::NoSignedWrap);
+ EXPECT_TRUE(NSWForAllValues.isSingleElement() &&
+ NSWForAllValues.getSingleElement()->isMinValue());
+
+ auto NUWForAllValues = ConstantRange::makeGuaranteedNoWrapRegion(
+ Instruction::Add, ConstantRange(32, /* isFullSet = */ true),
+ OBO::NoUnsignedWrap);
+ EXPECT_TRUE(NUWForAllValues.isSingleElement() &&
+ NSWForAllValues.getSingleElement()->isMinValue());
+
+ auto NUWAndNSWForAllValues = ConstantRange::makeGuaranteedNoWrapRegion(
+ Instruction::Add, ConstantRange(32, /* isFullSet = */ true),
+ OBO::NoUnsignedWrap | OBO::NoSignedWrap);
+ EXPECT_TRUE(NUWAndNSWForAllValues.isSingleElement() &&
+ NSWForAllValues.getSingleElement()->isMinValue());
+
+ ConstantRange OneToFive(APInt(32, 1), APInt(32, 6));
+ EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
+ Instruction::Add, OneToFive, OBO::NoSignedWrap),
+ ConstantRange(APInt::getSignedMinValue(32),
+ APInt::getSignedMaxValue(32) - 4));
+ 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));
+
+ ConstantRange MinusFiveToMinusTwo(APInt(32, -5), APInt(32, -1));
+ EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
+ Instruction::Add, MinusFiveToMinusTwo, OBO::NoSignedWrap),
+ ConstantRange(APInt::getSignedMinValue(32) + 5,
+ APInt::getSignedMinValue(32)));
+ EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
+ 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)));
+
+ ConstantRange MinusOneToOne(APInt(32, -1), APInt(32, 2));
+ EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
+ Instruction::Add, MinusOneToOne, OBO::NoSignedWrap),
+ ConstantRange(APInt::getSignedMinValue(32) + 1,
+ APInt::getSignedMinValue(32) - 1));
+ EXPECT_EQ(ConstantRange::makeGuaranteedNoWrapRegion(
+ 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)));
}
} // anonymous namespace
More information about the llvm-commits
mailing list