diff options
| author | Sanjoy Das <sanjoy@playingwithpointers.com> | 2015-10-28 03:20:15 +0000 |
|---|---|---|
| committer | Sanjoy Das <sanjoy@playingwithpointers.com> | 2015-10-28 03:20:15 +0000 |
| commit | 1d1929aace4b2b3c87dca8ae87d4e890004deeb4 (patch) | |
| tree | a93a344a79c76b53ecd73d9995e430ab97e7b229 /llvm | |
| parent | 4ff3cf6d927049db47edbd5bc981ab19f5e17f5e (diff) | |
| download | bcm5719-llvm-1d1929aace4b2b3c87dca8ae87d4e890004deeb4.tar.gz bcm5719-llvm-1d1929aace4b2b3c87dca8ae87d4e890004deeb4.zip | |
[ValueTracking] Use !range metadata more aggressively in KnownBits
Summary:
Teach `computeKnownBitsFromRangeMetadata` to use `!range` metadata more
aggressively.
Reviewers: majnemer, nlewycky, jingyue
Subscribers: llvm-commits
Differential Revision: http://reviews.llvm.org/D14100
llvm-svn: 251487
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/include/llvm/Analysis/ValueTracking.h | 3 | ||||
| -rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 24 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 2 | ||||
| -rw-r--r-- | llvm/test/Analysis/ValueTracking/known-bits-from-range-md.ll | 34 |
4 files changed, 52 insertions, 11 deletions
diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h index 6216c4ddfd8..f9e0386a4ed 100644 --- a/llvm/include/llvm/Analysis/ValueTracking.h +++ b/llvm/include/llvm/Analysis/ValueTracking.h @@ -49,8 +49,9 @@ namespace llvm { const DominatorTree *DT = nullptr); /// Compute known bits from the range metadata. /// \p KnownZero the set of bits that are known to be zero + /// \p KnownOne the set of bits that are known to be one void computeKnownBitsFromRangeMetadata(const MDNode &Ranges, - APInt &KnownZero); + APInt &KnownZero, APInt &KnownOne); /// Return true if LHS and RHS have no common bits set. bool haveNoCommonBitsSet(Value *LHS, Value *RHS, const DataLayout &DL, AssumptionCache *AC = nullptr, diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index e25087e6911..fda1dbf8825 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -367,24 +367,30 @@ static void computeKnownBitsMul(Value *Op0, Value *Op1, bool NSW, } void llvm::computeKnownBitsFromRangeMetadata(const MDNode &Ranges, - APInt &KnownZero) { + APInt &KnownZero, + APInt &KnownOne) { unsigned BitWidth = KnownZero.getBitWidth(); unsigned NumRanges = Ranges.getNumOperands() / 2; assert(NumRanges >= 1); - // Use the high end of the ranges to find leading zeros. - unsigned MinLeadingZeros = BitWidth; + KnownZero.setAllBits(); + KnownOne.setAllBits(); + for (unsigned i = 0; i < NumRanges; ++i) { ConstantInt *Lower = mdconst::extract<ConstantInt>(Ranges.getOperand(2 * i + 0)); ConstantInt *Upper = mdconst::extract<ConstantInt>(Ranges.getOperand(2 * i + 1)); ConstantRange Range(Lower->getValue(), Upper->getValue()); - unsigned LeadingZeros = Range.getUnsignedMax().countLeadingZeros(); - MinLeadingZeros = std::min(LeadingZeros, MinLeadingZeros); - } - KnownZero = APInt::getHighBitsSet(BitWidth, MinLeadingZeros); + // The first CommonPrefixBits of all values in Range are equal. + unsigned CommonPrefixBits = + (Range.getUnsignedMax() ^ Range.getUnsignedMin()).countLeadingZeros(); + + APInt Mask = APInt::getHighBitsSet(BitWidth, CommonPrefixBits); + KnownOne &= Range.getUnsignedMax() & Mask; + KnownZero &= ~Range.getUnsignedMax() & Mask; + } } static bool isEphemeralValueOf(Instruction *I, const Value *E) { @@ -1060,7 +1066,7 @@ static void computeKnownBitsFromOperator(Operator *I, APInt &KnownZero, default: break; case Instruction::Load: if (MDNode *MD = cast<LoadInst>(I)->getMetadata(LLVMContext::MD_range)) - computeKnownBitsFromRangeMetadata(*MD, KnownZero); + computeKnownBitsFromRangeMetadata(*MD, KnownZero, KnownOne); break; case Instruction::And: { // If either the LHS or the RHS are Zero, the result is zero. @@ -1452,7 +1458,7 @@ static void computeKnownBitsFromOperator(Operator *I, APInt &KnownZero, case Instruction::Call: case Instruction::Invoke: if (MDNode *MD = cast<Instruction>(I)->getMetadata(LLVMContext::MD_range)) - computeKnownBitsFromRangeMetadata(*MD, KnownZero); + computeKnownBitsFromRangeMetadata(*MD, KnownZero, KnownOne); // If a range metadata is attached to this IntrinsicInst, intersect the // explicit range specified by the metadata and the implicit range of // the intrinsic. diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 66f5ba7f5dd..3296eb41e78 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -2285,7 +2285,7 @@ void SelectionDAG::computeKnownBits(SDValue Op, APInt &KnownZero, KnownZero |= APInt::getHighBitsSet(BitWidth, BitWidth - MemBits); } else if (const MDNode *Ranges = LD->getRanges()) { if (LD->getExtensionType() == ISD::NON_EXTLOAD) - computeKnownBitsFromRangeMetadata(*Ranges, KnownZero); + computeKnownBitsFromRangeMetadata(*Ranges, KnownZero, KnownOne); } break; } diff --git a/llvm/test/Analysis/ValueTracking/known-bits-from-range-md.ll b/llvm/test/Analysis/ValueTracking/known-bits-from-range-md.ll new file mode 100644 index 00000000000..e1de089b350 --- /dev/null +++ b/llvm/test/Analysis/ValueTracking/known-bits-from-range-md.ll @@ -0,0 +1,34 @@ +; RUN: opt -S -instsimplify < %s | FileCheck %s + +define i1 @test0(i8* %ptr) { +; CHECK-LABEL: @test0( + entry: + %val = load i8, i8* %ptr, !range !{i8 -50, i8 0} + %and = and i8 %val, 128 + %is.eq = icmp eq i8 %and, 128 + ret i1 %is.eq +; CHECK: ret i1 true +} + +define i1 @test1(i8* %ptr) { +; CHECK-LABEL: @test1( + entry: + %val = load i8, i8* %ptr, !range !{i8 64, i8 128} + %and = and i8 %val, 64 + %is.eq = icmp eq i8 %and, 64 + ret i1 %is.eq +; CHECK: ret i1 true +} + +define i1 @test2(i8* %ptr) { +; CHECK-LABEL: @test2( + entry: +; CHECK: load +; CHECK: and +; CHECK: icmp eq +; CHECK: ret + %val = load i8, i8* %ptr, !range !{i8 64, i8 129} + %and = and i8 %val, 64 + %is.eq = icmp eq i8 %and, 64 + ret i1 %is.eq +} |

