[PATCH] D114272: [InstCombine] Add two optimizations for mul-and-icmp patterns

Fabian Wolff via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 8 11:43:32 PST 2022


fwolff updated this revision to Diff 406911.
fwolff added a comment.

In D114272#3299405 <https://reviews.llvm.org/D114272#3299405>, @RKSimon wrote:

> @fwolff Please can you rebase this patch?

Done!


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D114272/new/

https://reviews.llvm.org/D114272

Files:
  llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
  llvm/test/Transforms/InstCombine/icmp-mul-and.ll


Index: llvm/test/Transforms/InstCombine/icmp-mul-and.ll
===================================================================
--- llvm/test/Transforms/InstCombine/icmp-mul-and.ll
+++ llvm/test/Transforms/InstCombine/icmp-mul-and.ll
@@ -22,8 +22,8 @@
 ; CHECK-LABEL: @mul_mask_pow2_ne0_use1(
 ; CHECK-NEXT:    [[MUL:%.*]] = mul i8 [[X:%.*]], 40
 ; CHECK-NEXT:    call void @use(i8 [[MUL]])
-; CHECK-NEXT:    [[AND:%.*]] = and i8 [[MUL]], 8
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[AND]], 0
+; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X]], 1
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[TMP1]], 0
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %mul = mul i8 %x, 40
@@ -241,11 +241,8 @@
 define i1 @pr51551(i32 %x, i32 %y) {
 ; CHECK-LABEL: @pr51551(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[TMP0:%.*]] = and i32 [[Y:%.*]], -8
-; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[TMP0]], 1
-; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP1]], [[X:%.*]]
-; CHECK-NEXT:    [[AND:%.*]] = and i32 [[MUL]], 3
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT:    [[TMP0:%.*]] = and i32 [[X:%.*]], 3
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP0]], 0
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
 entry:
@@ -260,11 +257,8 @@
 define i1 @pr51551_2(i32 %x, i32 %y) {
 ; CHECK-LABEL: @pr51551_2(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[TMP0:%.*]] = and i32 [[Y:%.*]], -8
-; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[TMP0]], 1
-; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP1]], [[X:%.*]]
-; CHECK-NEXT:    [[AND:%.*]] = and i32 [[MUL]], 1
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT:    [[TMP0:%.*]] = and i32 [[X:%.*]], 1
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP0]], 0
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
 entry:
Index: llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -1887,6 +1887,48 @@
     return new ICmpInst(NewPred, X, SubOne(cast<Constant>(Cmp.getOperand(1))));
   }
 
+  const APInt *C2;
+  if (And->hasOneUse() && C.isZero() && match(Y, m_APInt(C2))) {
+    const APInt *C1;
+    Value *X1;
+    // ((X1 * C1) & C2) ==/!= 0 -> ((X1 * (C1/C2)) & 1) ==/!= 0
+    //   iff C2 is a power of 2 greater than 1 and C1 is a multiple of C2
+    if (match(X, m_Mul(m_Value(X1), m_APInt(C1))) && C2->isPowerOf2() &&
+        !C2->isOne() && (C1->urem(*C2)).isZero()) {
+      APInt NewDiv = C1->udiv(*C2);
+      auto *NewMul =
+          Builder.CreateMul(X1, ConstantInt::get(X1->getType(), NewDiv));
+      auto *NewAnd =
+          Builder.CreateAnd(NewMul, ConstantInt::get(NewMul->getType(), 1));
+      return new ICmpInst(Cmp.getPredicate(), NewAnd, Cmp.getOperand(1));
+    }
+
+    Value *X2;
+    // ((X1 * X2) & C2) ==/!= 0 -> (X1 & C2) ==/!= 0
+    //   iff (C2 + 1) is a power of 2 and (X2 & C2) == 1
+    if (match(X, m_Mul(m_Value(X1), m_Value(X2))) && C2->isMask()) {
+      unsigned TrailingOnes = C2->countTrailingOnes();
+      APInt ExpectedZero =
+          C2->usub_sat(APInt::getOneBitSet(C2->getBitWidth(), 0));
+
+      auto Check = [&](Value *Xi, Value *Xj) -> Instruction * {
+        KnownBits XiKnown = computeKnownBits(Xi, 0, &Cmp);
+        if (XiKnown.One.getLoBits(1).isOne() &&
+            XiKnown.Zero.getLoBits(TrailingOnes) == ExpectedZero) {
+          auto *NewAnd =
+              Builder.CreateAnd(Xj, ConstantInt::get(Xj->getType(), *C2));
+          return new ICmpInst(Cmp.getPredicate(), NewAnd, Cmp.getOperand(1));
+        }
+        return nullptr;
+      };
+
+      if (Instruction *I = Check(X1, X2))
+        return I;
+      if (Instruction *I = Check(X2, X1))
+        return I;
+    }
+  }
+
   return nullptr;
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D114272.406911.patch
Type: text/x-patch
Size: 3794 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220208/685d675f/attachment.bin>


More information about the llvm-commits mailing list