[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