summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp19
-rw-r--r--llvm/lib/IR/ConstantRange.cpp19
2 files changed, 27 insertions, 11 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 9a87667827a..f0c02eec4e2 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -4077,13 +4077,6 @@ static OverflowResult mapOverflowResult(ConstantRange::OverflowResult OR) {
llvm_unreachable("Unknown OverflowResult");
}
-static ConstantRange constantRangeFromKnownBits(const KnownBits &Known) {
- if (Known.isUnknown())
- return ConstantRange(Known.getBitWidth(), /* full */ true);
-
- return ConstantRange(Known.One, ~Known.Zero + 1);
-}
-
OverflowResult llvm::computeOverflowForUnsignedAdd(
const Value *LHS, const Value *RHS, const DataLayout &DL,
AssumptionCache *AC, const Instruction *CxtI, const DominatorTree *DT,
@@ -4092,8 +4085,10 @@ OverflowResult llvm::computeOverflowForUnsignedAdd(
nullptr, UseInstrInfo);
KnownBits RHSKnown = computeKnownBits(RHS, DL, /*Depth=*/0, AC, CxtI, DT,
nullptr, UseInstrInfo);
- ConstantRange LHSRange = constantRangeFromKnownBits(LHSKnown);
- ConstantRange RHSRange = constantRangeFromKnownBits(RHSKnown);
+ ConstantRange LHSRange =
+ ConstantRange::fromKnownBits(LHSKnown, /*signed*/ false);
+ ConstantRange RHSRange =
+ ConstantRange::fromKnownBits(RHSKnown, /*signed*/ false);
return mapOverflowResult(LHSRange.unsignedAddMayOverflow(RHSRange));
}
@@ -4208,8 +4203,10 @@ OverflowResult llvm::computeOverflowForUnsignedSub(const Value *LHS,
const DominatorTree *DT) {
KnownBits LHSKnown = computeKnownBits(LHS, DL, /*Depth=*/0, AC, CxtI, DT);
KnownBits RHSKnown = computeKnownBits(RHS, DL, /*Depth=*/0, AC, CxtI, DT);
- ConstantRange LHSRange = constantRangeFromKnownBits(LHSKnown);
- ConstantRange RHSRange = constantRangeFromKnownBits(RHSKnown);
+ ConstantRange LHSRange =
+ ConstantRange::fromKnownBits(LHSKnown, /*signed*/ false);
+ ConstantRange RHSRange =
+ ConstantRange::fromKnownBits(RHSKnown, /*signed*/ false);
return mapOverflowResult(LHSRange.unsignedSubMayOverflow(RHSRange));
}
diff --git a/llvm/lib/IR/ConstantRange.cpp b/llvm/lib/IR/ConstantRange.cpp
index 23737bb4650..d41914ba4a9 100644
--- a/llvm/lib/IR/ConstantRange.cpp
+++ b/llvm/lib/IR/ConstantRange.cpp
@@ -31,6 +31,7 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/KnownBits.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
@@ -53,6 +54,24 @@ ConstantRange::ConstantRange(APInt L, APInt U)
"Lower == Upper, but they aren't min or max value!");
}
+ConstantRange ConstantRange::fromKnownBits(const KnownBits &Known,
+ bool IsSigned) {
+ if (Known.isUnknown())
+ return ConstantRange(Known.getBitWidth(), /* full */ true);
+
+ // For unsigned ranges, or signed ranges with known sign bit, create a simple
+ // range between the smallest and largest possible value.
+ if (!IsSigned || Known.isNegative() || Known.isNonNegative())
+ return ConstantRange(Known.One, ~Known.Zero + 1);
+
+ // If we don't know the sign bit, pick the lower bound as a negative number
+ // and the upper bound as a non-negative one.
+ APInt Lower = Known.One, Upper = ~Known.Zero;
+ Lower.setSignBit();
+ Upper.clearSignBit();
+ return ConstantRange(Lower, Upper + 1);
+}
+
ConstantRange ConstantRange::makeAllowedICmpRegion(CmpInst::Predicate Pred,
const ConstantRange &CR) {
if (CR.isEmptySet())
OpenPOWER on IntegriCloud