summaryrefslogtreecommitdiffstats
path: root/llvm/lib/IR/ConstantRange.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/IR/ConstantRange.cpp')
-rw-r--r--llvm/lib/IR/ConstantRange.cpp80
1 files changed, 52 insertions, 28 deletions
diff --git a/llvm/lib/IR/ConstantRange.cpp b/llvm/lib/IR/ConstantRange.cpp
index 4bd17257016..77ecd7a9077 100644
--- a/llvm/lib/IR/ConstantRange.cpp
+++ b/llvm/lib/IR/ConstantRange.cpp
@@ -199,39 +199,63 @@ ConstantRange::makeGuaranteedNoWrapRegion(Instruction::BinaryOps BinOp,
"NoWrapKind invalid!");
unsigned BitWidth = Other.getBitWidth();
- if (BinOp != Instruction::Add)
+ ConstantRange Result(BitWidth);
+
+ switch (BinOp) {
+ default:
// Conservative answer: empty set
return ConstantRange(BitWidth, false);
- if (auto *C = Other.getSingleElement())
- if (C->isNullValue())
- // Full set: nothing signed / unsigned wraps when added to 0.
- return ConstantRange(BitWidth);
-
- ConstantRange Result(BitWidth);
+ case Instruction::Add:
+ if (auto *C = Other.getSingleElement())
+ if (C->isNullValue())
+ // Full set: nothing signed / unsigned wraps when added to 0.
+ return ConstantRange(BitWidth);
+ if (NoWrapKind & OBO::NoUnsignedWrap)
+ Result =
+ SubsetIntersect(Result, ConstantRange(APInt::getNullValue(BitWidth),
+ -Other.getUnsignedMax()));
+ if (NoWrapKind & OBO::NoSignedWrap) {
+ const APInt &SignedMin = Other.getSignedMin();
+ const APInt &SignedMax = Other.getSignedMax();
+ if (SignedMax.isStrictlyPositive())
+ Result = SubsetIntersect(
+ Result,
+ ConstantRange(APInt::getSignedMinValue(BitWidth),
+ APInt::getSignedMinValue(BitWidth) - SignedMax));
+ if (SignedMin.isNegative())
+ Result = SubsetIntersect(
+ Result,
+ ConstantRange(APInt::getSignedMinValue(BitWidth) - SignedMin,
+ APInt::getSignedMinValue(BitWidth)));
+ }
+ return Result;
- if (NoWrapKind & OBO::NoUnsignedWrap)
- Result =
- SubsetIntersect(Result, ConstantRange(APInt::getNullValue(BitWidth),
- -Other.getUnsignedMax()));
-
- if (NoWrapKind & OBO::NoSignedWrap) {
- const APInt &SignedMin = Other.getSignedMin();
- const APInt &SignedMax = Other.getSignedMax();
-
- if (SignedMax.isStrictlyPositive())
- Result = SubsetIntersect(
- Result,
- ConstantRange(APInt::getSignedMinValue(BitWidth),
- APInt::getSignedMinValue(BitWidth) - SignedMax));
-
- if (SignedMin.isNegative())
- Result = SubsetIntersect(
- Result, ConstantRange(APInt::getSignedMinValue(BitWidth) - SignedMin,
- APInt::getSignedMinValue(BitWidth)));
+ case Instruction::Sub:
+ if (auto *C = Other.getSingleElement())
+ if (C->isNullValue())
+ // Full set: nothing signed / unsigned wraps when subtracting 0.
+ return ConstantRange(BitWidth);
+ if (NoWrapKind & OBO::NoUnsignedWrap)
+ Result =
+ SubsetIntersect(Result, ConstantRange(Other.getUnsignedMax(),
+ APInt::getMinValue(BitWidth)));
+ if (NoWrapKind & OBO::NoSignedWrap) {
+ const APInt &SignedMin = Other.getSignedMin();
+ const APInt &SignedMax = Other.getSignedMax();
+ if (SignedMax.isStrictlyPositive())
+ Result = SubsetIntersect(
+ Result,
+ ConstantRange(APInt::getSignedMinValue(BitWidth) + SignedMax,
+ APInt::getSignedMinValue(BitWidth)));
+ if (SignedMin.isNegative())
+ Result = SubsetIntersect(
+ Result,
+ ConstantRange(APInt::getSignedMinValue(BitWidth),
+ APInt::getSignedMinValue(BitWidth) + SignedMin));
+ }
+ return Result;
}
-
- return Result;
}
bool ConstantRange::isFullSet() const {
OpenPOWER on IntegriCloud