[PATCH] D14100: [ValueTracking] Compute sign bit from range metadata

Nick Lewycky via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 26 21:02:35 PDT 2015


On 26 October 2015 at 19:49, Sanjoy Das <sanjoy at playingwithpointers.com>
wrote:

>
>
> 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
>   }
>
> ?


Just double-checking, given a range that's wrapping, unsignedMin/Max will
return 0 and uintmax, right? If so, that logic sounds correct to me!


> >     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,
> >
> >
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20151026/b6377aba/attachment.html>


More information about the llvm-commits mailing list