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

Nick Lewycky via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 26 19:38:58 PDT 2015


On 26 October 2015 at 18:46, Sanjoy Das <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'.


>
> 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/445a2641/attachment.html>


More information about the llvm-commits mailing list