[llvm] r284597 - Introduce ConstantRange.addWithNoSignedWrap
Artur Pilipenko via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 19 07:44:24 PDT 2016
Author: apilipenko
Date: Wed Oct 19 09:44:23 2016
New Revision: 284597
URL: http://llvm.org/viewvc/llvm-project?rev=284597&view=rev
Log:
Introduce ConstantRange.addWithNoSignedWrap
To be used by upcoming change to IndVarSimplify
Reviewed By: sanjoy
Differential Revision: https://reviews.llvm.org/D25732
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=284597&r1=284596&r2=284597&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/ConstantRange.h (original)
+++ llvm/trunk/include/llvm/IR/ConstantRange.h Wed Oct 19 09:44:23 2016
@@ -261,6 +261,10 @@ public:
/// from an addition of a value in this range and a value in \p Other.
ConstantRange add(const ConstantRange &Other) const;
+ /// Return a new range representing the possible values resulting from a
+ /// known NSW addition of a value in this range and \p Other constant.
+ ConstantRange addWithNoSignedWrap(const APInt &Other) const;
+
/// Return a new range representing the possible values resulting
/// from a subtraction of a value in this range and a value in \p Other.
ConstantRange sub(const ConstantRange &Other) const;
Modified: llvm/trunk/lib/IR/ConstantRange.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/ConstantRange.cpp?rev=284597&r1=284596&r2=284597&view=diff
==============================================================================
--- llvm/trunk/lib/IR/ConstantRange.cpp (original)
+++ llvm/trunk/lib/IR/ConstantRange.cpp Wed Oct 19 09:44:23 2016
@@ -674,6 +674,19 @@ ConstantRange::add(const ConstantRange &
return X;
}
+ConstantRange ConstantRange::addWithNoSignedWrap(const APInt &Other) const {
+ // Calculate the subset of this range such that "X + Other" is
+ // guaranteed not to wrap (overflow) for all X in this subset.
+ // makeGuaranteedNoWrapRegion will produce an exact NSW range since we are
+ // passing a single element range.
+ auto NSWRange = ConstantRange::makeGuaranteedNoWrapRegion(BinaryOperator::Add,
+ ConstantRange(Other),
+ OverflowingBinaryOperator::NoSignedWrap);
+ auto NSWConstrainedRange = intersectWith(NSWRange);
+
+ return NSWConstrainedRange.add(ConstantRange(Other));
+}
+
ConstantRange
ConstantRange::sub(const ConstantRange &Other) const {
if (isEmptySet() || Other.isEmptySet())
Modified: llvm/trunk/unittests/IR/ConstantRangeTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/ConstantRangeTest.cpp?rev=284597&r1=284596&r2=284597&view=diff
==============================================================================
--- llvm/trunk/unittests/IR/ConstantRangeTest.cpp (original)
+++ llvm/trunk/unittests/IR/ConstantRangeTest.cpp Wed Oct 19 09:44:23 2016
@@ -357,6 +357,32 @@ TEST_F(ConstantRangeTest, Add) {
ConstantRange(APInt(16, 0xe)));
}
+TEST_F(ConstantRangeTest, AddWithNoSignedWrap) {
+ EXPECT_EQ(Empty.addWithNoSignedWrap(APInt(16, 1)), Empty);
+ EXPECT_EQ(Full.addWithNoSignedWrap(APInt(16, 1)),
+ ConstantRange(APInt(16, INT16_MIN+1), APInt(16, INT16_MIN)));
+ EXPECT_EQ(ConstantRange(APInt(8, -50), APInt(8, 50)).addWithNoSignedWrap(APInt(8, 10)),
+ ConstantRange(APInt(8, -40), APInt(8, 60)));
+ EXPECT_EQ(ConstantRange(APInt(8, -50), APInt(8, 120)).addWithNoSignedWrap(APInt(8, 10)),
+ ConstantRange(APInt(8, -40), APInt(8, INT8_MIN)));
+ EXPECT_EQ(ConstantRange(APInt(8, 120), APInt(8, -10)).addWithNoSignedWrap(APInt(8, 5)),
+ ConstantRange(APInt(8, 125), APInt(8, -5)));
+ EXPECT_EQ(ConstantRange(APInt(8, 120), APInt(8, -120)).addWithNoSignedWrap(APInt(8, 10)),
+ ConstantRange(APInt(8, INT8_MIN+10), APInt(8, -110)));
+
+ EXPECT_EQ(Empty.addWithNoSignedWrap(APInt(16, -1)), Empty);
+ EXPECT_EQ(Full.addWithNoSignedWrap(APInt(16, -1)),
+ ConstantRange(APInt(16, INT16_MIN), APInt(16, INT16_MAX)));
+ EXPECT_EQ(ConstantRange(APInt(8, -50), APInt(8, 50)).addWithNoSignedWrap(APInt(8, -10)),
+ ConstantRange(APInt(8, -60), APInt(8, 40)));
+ EXPECT_EQ(ConstantRange(APInt(8, -120), APInt(8, 50)).addWithNoSignedWrap(APInt(8, -10)),
+ ConstantRange(APInt(8, INT8_MIN), APInt(8, 40)));
+ EXPECT_EQ(ConstantRange(APInt(8, 120), APInt(8, -120)).addWithNoSignedWrap(APInt(8, -5)),
+ ConstantRange(APInt(8, 115), APInt(8, -125)));
+ EXPECT_EQ(ConstantRange(APInt(8, 120), APInt(8, -120)).addWithNoSignedWrap(APInt(8, -10)),
+ ConstantRange(APInt(8, 110), APInt(8, INT8_MIN-10)));
+}
+
TEST_F(ConstantRangeTest, Sub) {
EXPECT_EQ(Full.sub(APInt(16, 4)), Full);
EXPECT_EQ(Full.sub(Full), Full);
More information about the llvm-commits
mailing list