[llvm] r251294 - [ValueTracking] Extend r251146 to catch a fairly common case

James Molloy via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 26 07:10:47 PDT 2015


Author: jamesm
Date: Mon Oct 26 09:10:46 2015
New Revision: 251294

URL: http://llvm.org/viewvc/llvm-project?rev=251294&view=rev
Log:
[ValueTracking] Extend r251146 to catch a fairly common case

Even though we may not know the value of the shifter operand, it's possible we know the shifter operand is non-zero. This can allow us to infer more known bits - for example:

  %1 = load %p !range {1, 5}
  %2 = shl %q, %1

We don't know %1, but we do know that it is nonzero so %2[0] is known zero, and importantly %2 is known non-zero.

Calling isKnownNonZero is nontrivially expensive so use an Optional to run it lazily and cache its result.

Added:
    llvm/trunk/test/Analysis/ValueTracking/knownnonzero-shift.ll
Modified:
    llvm/trunk/lib/Analysis/ValueTracking.cpp

Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ValueTracking.cpp?rev=251294&r1=251293&r2=251294&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ValueTracking.cpp (original)
+++ llvm/trunk/lib/Analysis/ValueTracking.cpp Mon Oct 26 09:10:46 2015
@@ -13,6 +13,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Analysis/ValueTracking.h"
+#include "llvm/ADT/Optional.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/Analysis/AssumptionCache.h"
 #include "llvm/Analysis/InstructionSimplify.h"
@@ -1004,9 +1005,18 @@ static void computeKnownBitsFromShiftOpe
   // calculation. Reusing the APInts here to prevent unnecessary allocations.
   KnownZero.clearAllBits(), KnownOne.clearAllBits();
 
+  // If we know the shifter operand is nonzero, we can sometimes infer more
+  // known bits. However this is expensive to compute, so be lazy about it and
+  // only compute it when absolutely necessary.
+  Optional<bool> ShifterOperandIsNonZero;
+
   // Early exit if we can't constrain any well-defined shift amount.
-  if (!(ShiftAmtKZ & (BitWidth-1)) && !(ShiftAmtKO & (BitWidth-1)))
-    return;
+  if (!(ShiftAmtKZ & (BitWidth - 1)) && !(ShiftAmtKO & (BitWidth - 1))) {
+    ShifterOperandIsNonZero =
+        isKnownNonZero(I->getOperand(1), DL, Depth + 1, Q);
+    if (!*ShifterOperandIsNonZero)
+      return;
+  }
 
   computeKnownBits(I->getOperand(0), KnownZero2, KnownOne2, DL, Depth + 1, Q);
 
@@ -1018,6 +1028,16 @@ static void computeKnownBitsFromShiftOpe
       continue;
     if ((ShiftAmt | ShiftAmtKO) != ShiftAmt)
       continue;
+    // If we know the shifter is nonzero, we may be able to infer more known
+    // bits. This check is sunk down as far as possible to avoid the expensive
+    // call to isKnownNonZero if the cheaper checks above fail.
+    if (ShiftAmt == 0) {
+      if (!ShifterOperandIsNonZero.hasValue())
+        ShifterOperandIsNonZero =
+            isKnownNonZero(I->getOperand(1), DL, Depth + 1, Q);
+      if (*ShifterOperandIsNonZero)
+        continue;
+    }
 
     KnownZero &= KZF(KnownZero2, ShiftAmt);
     KnownOne  &= KOF(KnownOne2, ShiftAmt);

Added: llvm/trunk/test/Analysis/ValueTracking/knownnonzero-shift.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ValueTracking/knownnonzero-shift.ll?rev=251294&view=auto
==============================================================================
--- llvm/trunk/test/Analysis/ValueTracking/knownnonzero-shift.ll (added)
+++ llvm/trunk/test/Analysis/ValueTracking/knownnonzero-shift.ll Mon Oct 26 09:10:46 2015
@@ -0,0 +1,13 @@
+; RUN: opt -instsimplify -S < %s | FileCheck %s
+
+; CHECK-LABEL: @test
+define i1 @test(i8 %p, i8* %pq) {
+  %q = load i8, i8* %pq, !range !0 ; %q is known nonzero; no known bits
+  %1 = shl i8 %p, %q              ; because %q is nonzero, %1[0] is known to be zero.
+  %2 = and i8 %1, 1
+  %x = icmp eq i8 %2, 0
+  ; CHECK: ret i1 true
+  ret i1 %x
+}
+
+!0 = !{ i8 1, i8 5 }




More information about the llvm-commits mailing list