[llvm] 9666e89 - [ValueTracking] Handle shl in isKnownNonEqual()

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 26 12:21:19 PDT 2021


Author: Nikita Popov
Date: 2021-03-26T20:21:05+01:00
New Revision: 9666e89d577887cf574507207484a066588fc9ca

URL: https://github.com/llvm/llvm-project/commit/9666e89d577887cf574507207484a066588fc9ca
DIFF: https://github.com/llvm/llvm-project/commit/9666e89d577887cf574507207484a066588fc9ca.diff

LOG: [ValueTracking] Handle shl in isKnownNonEqual()

This handles the pattern X != X << C for non-zero X and C and a
non-overflowing shift. This establishes parity with the corresponing
fold for multiplies.

Added: 
    

Modified: 
    llvm/lib/Analysis/ValueTracking.cpp
    llvm/test/Analysis/ValueTracking/known-non-equal.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 1c3d5df21907..6f89ba9b5315 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -2564,6 +2564,19 @@ static bool isNonEqualMul(const Value *V1, const Value *V2, unsigned Depth,
   return false;
 }
 
+/// Return true if V2 == V1 << C, where V1 is known non-zero, C is not 0 and
+/// the shift is nuw or nsw.
+static bool isNonEqualShl(const Value *V1, const Value *V2, unsigned Depth,
+                          const Query &Q) {
+  if (auto *OBO = dyn_cast<OverflowingBinaryOperator>(V2)) {
+    const APInt *C;
+    return match(OBO, m_Shl(m_Specific(V1), m_APInt(C))) &&
+           (OBO->hasNoUnsignedWrap() || OBO->hasNoSignedWrap()) &&
+           !C->isNullValue() && isKnownNonZero(V1, Depth + 1, Q);
+  }
+  return false;
+}
+
 static bool isNonEqualPHIs(const PHINode *PN1, const PHINode *PN2,
                            unsigned Depth, const Query &Q) {
   // Check two PHIs are in same block.
@@ -2665,6 +2678,9 @@ static bool isKnownNonEqual(const Value *V1, const Value *V2, unsigned Depth,
   if (isNonEqualMul(V1, V2, Depth, Q) || isNonEqualMul(V2, V1, Depth, Q))
     return true;
 
+  if (isNonEqualShl(V1, V2, Depth, Q) || isNonEqualShl(V2, V1, Depth, Q))
+    return true;
+
   if (V1->getType()->isIntOrIntVectorTy()) {
     // Are any known bits in V1 contradictory to known bits in V2? If V1
     // has a known zero where V2 has a known one, they must not be equal.

diff  --git a/llvm/test/Analysis/ValueTracking/known-non-equal.ll b/llvm/test/Analysis/ValueTracking/known-non-equal.ll
index 552e5d1ecc3e..6958b78b045a 100644
--- a/llvm/test/Analysis/ValueTracking/known-non-equal.ll
+++ b/llvm/test/Analysis/ValueTracking/known-non-equal.ll
@@ -345,10 +345,7 @@ exit:
 
 define i1 @shl_nuw(i16 %x) {
 ; CHECK-LABEL: @shl_nuw(
-; CHECK-NEXT:    [[NZ:%.*]] = or i16 [[X:%.*]], 2
-; CHECK-NEXT:    [[MUL:%.*]] = shl nuw i16 [[NZ]], 1
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i16 [[NZ]], [[MUL]]
-; CHECK-NEXT:    ret i1 [[CMP]]
+; CHECK-NEXT:    ret i1 false
 ;
   %nz = or i16 %x, 2
   %mul = shl nuw i16 %nz, 1
@@ -358,10 +355,7 @@ define i1 @shl_nuw(i16 %x) {
 
 define i1 @shl_nsw(i16 %x) {
 ; CHECK-LABEL: @shl_nsw(
-; CHECK-NEXT:    [[NZ:%.*]] = or i16 [[X:%.*]], 2
-; CHECK-NEXT:    [[MUL:%.*]] = shl nsw i16 [[NZ]], 1
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i16 [[NZ]], [[MUL]]
-; CHECK-NEXT:    ret i1 [[CMP]]
+; CHECK-NEXT:    ret i1 false
 ;
   %nz = or i16 %x, 2
   %mul = shl nsw i16 %nz, 1


        


More information about the llvm-commits mailing list