[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