diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 19 | ||||
-rw-r--r-- | llvm/lib/IR/ConstantRange.cpp | 19 |
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()) |