[llvm] e92a27b - [InstCombine] Verify CmpInst is equality in `foldICmpPow2Test`; PR63327

Noah Goldstein via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 15 10:21:34 PDT 2023


Author: Noah Goldstein
Date: 2023-06-15T12:21:24-05:00
New Revision: e92a27bcb7bfca7849be7d709f81be7bdbfd353e

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

LOG: [InstCombine] Verify CmpInst is equality in `foldICmpPow2Test`; PR63327

When D152728 hoisted the code to a helper function, it moved the call
to the helper outside of `foldICmpEquality`, so an equality check is
needed in the helper.

Reviewed By: nikic, fhahn

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

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
    llvm/test/Transforms/InstCombine/ispow2.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 95e34bf146ff4..03bbd22236ff5 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -4812,21 +4812,22 @@ static Instruction *foldICmpPow2Test(ICmpInst &I,
   Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
   const CmpInst::Predicate Pred = I.getPredicate();
   Value *A = nullptr;
-  // (A & (A-1)) == 0 --> ctpop(A) < 2 (two commuted variants)
-  // ((A-1) & A) != 0 --> ctpop(A) > 1 (two commuted variants)
-  if (!match(Op0, m_OneUse(m_c_And(m_Add(m_Value(A), m_AllOnes()),
-                                   m_Deferred(A)))) ||
-      !match(Op1, m_ZeroInt()))
-    A = nullptr;
-
-  // (A & -A) == A --> ctpop(A) < 2 (four commuted variants)
-  // (-A & A) != A --> ctpop(A) > 1 (four commuted variants)
-  if (match(Op0, m_OneUse(m_c_And(m_Neg(m_Specific(Op1)), m_Specific(Op1)))))
-    A = Op1;
-  else if (match(Op1,
-                 m_OneUse(m_c_And(m_Neg(m_Specific(Op0)), m_Specific(Op0)))))
-    A = Op0;
-
+  if (I.isEquality()) {
+    // (A & (A-1)) == 0 --> ctpop(A) < 2 (two commuted variants)
+    // ((A-1) & A) != 0 --> ctpop(A) > 1 (two commuted variants)
+    if (!match(Op0, m_OneUse(m_c_And(m_Add(m_Value(A), m_AllOnes()),
+                                     m_Deferred(A)))) ||
+        !match(Op1, m_ZeroInt()))
+      A = nullptr;
+
+    // (A & -A) == A --> ctpop(A) < 2 (four commuted variants)
+    // (-A & A) != A --> ctpop(A) > 1 (four commuted variants)
+    if (match(Op0, m_OneUse(m_c_And(m_Neg(m_Specific(Op1)), m_Specific(Op1)))))
+      A = Op1;
+    else if (match(Op1,
+                   m_OneUse(m_c_And(m_Neg(m_Specific(Op0)), m_Specific(Op0)))))
+      A = Op0;
+  }
   if (A) {
     Type *Ty = A->getType();
     CallInst *CtPop = Builder.CreateUnaryIntrinsic(Intrinsic::ctpop, A);

diff  --git a/llvm/test/Transforms/InstCombine/ispow2.ll b/llvm/test/Transforms/InstCombine/ispow2.ll
index 191ff9f005a5d..7301fbb46212f 100644
--- a/llvm/test/Transforms/InstCombine/ispow2.ll
+++ b/llvm/test/Transforms/InstCombine/ispow2.ll
@@ -1140,3 +1140,16 @@ define <2 x i1> @isnot_pow2nor0_wrong_pred3_ctpop_commute_vec(<2 x i8> %x) {
   %r = or <2 x i1> %cmp, %notzero
   ret <2 x i1> %r
 }
+
+define i1 @is_pow2_fail_pr63327(i32 %x) {
+; CHECK-LABEL: @is_pow2_fail_pr63327(
+; CHECK-NEXT:    [[NX:%.*]] = sub i32 0, [[X:%.*]]
+; CHECK-NEXT:    [[X_AND_NX:%.*]] = and i32 [[NX]], [[X]]
+; CHECK-NEXT:    [[R:%.*]] = icmp sge i32 [[X_AND_NX]], [[X]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %nx = sub i32 0, %x
+  %x_and_nx = and i32 %x, %nx
+  %r = icmp sge i32 %x_and_nx, %x
+  ret i1 %r
+}


        


More information about the llvm-commits mailing list