[llvm] cc845e9 - [InstCombine] Handle assume(X & Pow2 != 0) in computeKnownBits()

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 11 01:21:23 PST 2023


Author: Noah Goldstein
Date: 2023-01-11T10:21:15+01:00
New Revision: cc845e9de8c87c74d494f4e90e8fcf4fca264989

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

LOG: [InstCombine] Handle assume(X & Pow2 != 0) in computeKnownBits()

If we know that X & Pow2 != 0, then the bit at that position is
known one.

Differential Revision: https://reviews.llvm.org/D140851

Added: 
    

Modified: 
    llvm/lib/Analysis/AssumptionCache.cpp
    llvm/lib/Analysis/ValueTracking.cpp
    llvm/test/Transforms/InstCombine/icmp-ne-pow2.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/AssumptionCache.cpp b/llvm/lib/Analysis/AssumptionCache.cpp
index e7e476dfb5720..11796ef504446 100644
--- a/llvm/lib/Analysis/AssumptionCache.cpp
+++ b/llvm/lib/Analysis/AssumptionCache.cpp
@@ -105,7 +105,7 @@ findAffectedValues(CallBase *CI, TargetTransformInfo *TTI,
         if (match(V, m_BitwiseLogic(m_Value(A), m_Value(B)))) {
           AddAffected(A);
           AddAffected(B);
-        // (A << C) or (A >>_s C) or (A >>_u C) where C is some constant.
+          // (A << C) or (A >>_s C) or (A >>_u C) where C is some constant.
         } else if (match(V, m_Shift(m_Value(A), m_ConstantInt()))) {
           AddAffected(A);
         }
@@ -113,15 +113,22 @@ findAffectedValues(CallBase *CI, TargetTransformInfo *TTI,
 
       AddAffectedFromEq(A);
       AddAffectedFromEq(B);
+    } else if (Pred == ICmpInst::ICMP_NE) {
+      Value *X, *Y;
+      // Handle (a & b != 0). If a/b is a power of 2 we can use this
+      // information.
+      if (match(A, m_And(m_Value(X), m_Value(Y))) && match(B, m_Zero())) {
+        AddAffected(X);
+        AddAffected(Y);
+      }
+    } else if (Pred == ICmpInst::ICMP_ULT) {
+      Value *X;
+      // Handle (A + C1) u< C2, which is the canonical form of A > C3 && A < C4,
+      // and recognized by LVI at least.
+      if (match(A, m_Add(m_Value(X), m_ConstantInt())) &&
+          match(B, m_ConstantInt()))
+        AddAffected(X);
     }
-
-    Value *X;
-    // Handle (A + C1) u< C2, which is the canonical form of A > C3 && A < C4,
-    // and recognized by LVI at least.
-    if (Pred == ICmpInst::ICMP_ULT &&
-        match(A, m_Add(m_Value(X), m_ConstantInt())) &&
-        match(B, m_ConstantInt()))
-      AddAffected(X);
   }
 
   if (TTI) {

diff  --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 7c37b89891d19..e49183db7ab7c 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -940,6 +940,14 @@ static void computeKnownBitsFromAssume(const Value *V, KnownBits &Known,
           Known.Zero.setHighBits(RHSKnown.countMinLeadingZeros());
       }
       break;
+    case ICmpInst::ICMP_NE: {
+      // assume (v & b != 0) where b is a power of 2
+      const APInt *BPow2;
+      if (match(Cmp, m_ICmp(Pred, m_c_And(m_V, m_Power2(BPow2)), m_Zero())) &&
+          isValidAssumeForContext(I, Q.CxtI, Q.DT)) {
+        Known.One |= BPow2->zextOrTrunc(BitWidth);
+      }
+    } break;
     }
   }
 

diff  --git a/llvm/test/Transforms/InstCombine/icmp-ne-pow2.ll b/llvm/test/Transforms/InstCombine/icmp-ne-pow2.ll
index 47c198573b841..224ea3cd76cc6 100644
--- a/llvm/test/Transforms/InstCombine/icmp-ne-pow2.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-ne-pow2.ll
@@ -9,8 +9,7 @@ define i32 @pow2_32_assume(i32 %x) {
 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 4
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[AND]], 0
 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
-; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[X]], 4
-; CHECK-NEXT:    ret i32 [[AND2]]
+; CHECK-NEXT:    ret i32 4
 ;
   %and = and i32 %x, 4
   %cmp = icmp ne i32 %and, 0
@@ -39,8 +38,7 @@ define i64 @pow2_64_assume(i64 %x) {
 ; CHECK-NEXT:    [[AND:%.*]] = and i64 [[X:%.*]], 1
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[AND]], 0
 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
-; CHECK-NEXT:    [[OR:%.*]] = or i64 [[X]], 1
-; CHECK-NEXT:    ret i64 [[OR]]
+; CHECK-NEXT:    ret i64 [[X]]
 ;
   %and = and i64 %x, 1
   %cmp = icmp ne i64 %and, 0
@@ -69,8 +67,7 @@ define i16 @pow2_16_assume(i16 %x) {
 ; CHECK-NEXT:    [[AND:%.*]] = and i16 [[X:%.*]], 16384
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i16 [[AND]], 0
 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
-; CHECK-NEXT:    [[AND2:%.*]] = and i16 [[X]], 16384
-; CHECK-NEXT:    ret i16 [[AND2]]
+; CHECK-NEXT:    ret i16 16384
 ;
   %and = and i16 %x, 16384
   %cmp = icmp eq i16 %and, 16384


        


More information about the llvm-commits mailing list