[PATCH] D14100: [ValueTracking] Compute sign bit from range metadata
Sanjoy Das via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 26 19:49:42 PDT 2015
Nick Lewycky wrote:
> On 26 October 2015 at 18:46, Sanjoy Das <sanjoy at playingwithpointers.com
> <mailto:sanjoy at playingwithpointers.com>> wrote:
>
> sanjoy created this revision.
> sanjoy added reviewers: jingyue, majnemer, nlewycky.
> sanjoy added a subscriber: llvm-commits.
>
> Teach `computeKnownBitsFromRangeMetadata` to use `!range` metadata to
> prove that a value is always negative, and hence always has a
sign bit
> set.
>
>
> I think that's overly specialized. If you have a range of i8 [64..127]
> then you know the top two bits are '01'.
How about:
for R in MD.ranges() { // now I wish we had a range iterator for this :P
find N such that the highest N bits are common between
R.unsignedMin and R.unsignedMax
KnownZero &= bitmask with zeroes in R.unsignedMax[BitWidth..N] set to 1
KnownOne &= bitmask with ones in R.unsignedMax[BitWidth..N] set to 1
}
?
>
>
> http://reviews.llvm.org/D14100
>
> Files:
> include/llvm/Analysis/ValueTracking.h
> lib/Analysis/ValueTracking.cpp
> lib/CodeGen/SelectionDAG/SelectionDAG.cpp
> test/Analysis/ValueTracking/sign-bit-from-md.ll
>
> Index: test/Analysis/ValueTracking/sign-bit-from-md.ll
> ===================================================================
> --- /dev/null
> +++ test/Analysis/ValueTracking/sign-bit-from-md.ll
> @@ -0,0 +1,13 @@
> +; RUN: opt -S -instsimplify < %s | FileCheck %s
> +
> +define i1 @f(i8* %ptr) {
> +; CHECK-LABEL: @f(
> + entry:
> + %val = load i8, i8* %ptr, !range !0
> + %and = and i8 %val, 128
> + %is.eq = icmp eq i8 %and, 128
> + ret i1 %is.eq
> +; CHECK: true
> +}
> +
> +!0 = !{i8 -50, i8 0}
> Index: lib/CodeGen/SelectionDAG/SelectionDAG.cpp
> ===================================================================
> --- lib/CodeGen/SelectionDAG/SelectionDAG.cpp
> +++ lib/CodeGen/SelectionDAG/SelectionDAG.cpp
> @@ -2284,7 +2284,7 @@
> unsigned MemBits = VT.getScalarType().getSizeInBits();
> KnownZero |= APInt::getHighBitsSet(BitWidth, BitWidth -
> MemBits);
> } else if (const MDNode *Ranges = LD->getRanges()) {
> - computeKnownBitsFromRangeMetadata(*Ranges, KnownZero);
> + computeKnownBitsFromRangeMetadata(*Ranges, KnownZero,
KnownOne);
> }
> break;
> }
> Index: lib/Analysis/ValueTracking.cpp
> ===================================================================
> --- lib/Analysis/ValueTracking.cpp
> +++ lib/Analysis/ValueTracking.cpp
> @@ -367,11 +367,14 @@
> }
>
> void llvm::computeKnownBitsFromRangeMetadata(const MDNode &Ranges,
> - APInt &KnownZero) {
> + APInt &KnownZero,
> + APInt &KnownOne) {
> unsigned BitWidth = KnownZero.getBitWidth();
> unsigned NumRanges = Ranges.getNumOperands() / 2;
> assert(NumRanges >= 1);
>
> + bool AlwaysNegative = true;
> +
> // Use the high end of the ranges to find leading zeros.
> unsigned MinLeadingZeros = BitWidth;
> for (unsigned i = 0; i < NumRanges; ++i) {
> @@ -382,9 +385,14 @@
> ConstantRange Range(Lower->getValue(), Upper->getValue());
> unsigned LeadingZeros =
> Range.getUnsignedMax().countLeadingZeros();
> MinLeadingZeros = std::min(LeadingZeros, MinLeadingZeros);
> + AlwaysNegative &= Range.getSignedMax().isNegative();
> }
>
> KnownZero = APInt::getHighBitsSet(BitWidth, MinLeadingZeros);
> + if (AlwaysNegative) {
> + assert(MinLeadingZeros == 0 && "We found at least one negative
> number!");
> + KnownOne = APInt::getHighBitsSet(BitWidth, 1);
> + }
> }
>
> static bool isEphemeralValueOf(Instruction *I, const Value *E) {
> @@ -1060,7 +1068,7 @@
> 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 +1460,7 @@
> 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.
> Index: include/llvm/Analysis/ValueTracking.h
> ===================================================================
> --- include/llvm/Analysis/ValueTracking.h
> +++ include/llvm/Analysis/ValueTracking.h
> @@ -49,8 +49,9 @@
> 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,
>
>
>
More information about the llvm-commits
mailing list