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

Sanjoy Das via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 26 18:46:39 PDT 2015


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.

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 --------------
A non-text attachment was scrubbed...
Name: D14100.38489.patch
Type: text/x-patch
Size: 4092 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20151027/779aa7ad/attachment.bin>


More information about the llvm-commits mailing list