[PATCH] D126040: [InstCombine] Fold a mul with bool value into and

Allen zhong via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri May 20 05:26:49 PDT 2022


Allen updated this revision to Diff 430946.
Allen added a comment.

split the test into new file mull.ll


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

https://reviews.llvm.org/D126040

Files:
  llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
  llvm/test/Transforms/InstCombine/mull.ll


Index: llvm/test/Transforms/InstCombine/mull.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/InstCombine/mull.ll
@@ -0,0 +1,41 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+
+; Instcombine should be able to simplify mull operator.
+
+define i64 @PR55599_One0(i64 %x, i64 %y) {
+; CHECK-LABEL: @PR55599_One0(
+; CHECK-NEXT:    [[AND2:%.*]] = and i64 [[Y:%.*]], 1
+; CHECK-NEXT:    [[MUL:%.*]] = and i64 [[AND2]], [[X:%.*]]
+; CHECK-NEXT:    ret i64 [[MUL]]
+;
+  %and1 = and i64 %x, 1
+  %and2 = and i64 %y, 1
+  %mul = mul i64 %and1, %and2
+  ret i64 %mul
+}
+
+define i64 @PR55599_One1(i64 %x, i64 %y, i64 %c) {
+; CHECK-LABEL: @PR55599_One1(
+; CHECK-NEXT:    [[AND1:%.*]] = and i64 [[X:%.*]], 1
+; CHECK-NEXT:    [[AND2:%.*]] = and i64 [[Y:%.*]], [[C:%.*]]
+; CHECK-NEXT:    [[MUL:%.*]] = mul nuw i64 [[AND1]], [[AND2]]
+; CHECK-NEXT:    ret i64 [[MUL]]
+;
+  %and1 = and i64 %x, 1
+  %and2 = and i64 %y, %c
+  %mul = mul i64 %and1, %and2
+  ret i64 %mul
+}
+
+; Aleady supported before
+define i64 @PR55599_Zero(i64 %x, i64 %y, i64 %c) {
+; CHECK-LABEL: @PR55599_Zero(
+; CHECK-NEXT:    ret i64 0
+;
+  %and1 = and i64 %x, %c
+  %and2 = and i64 %y, 0
+  %mul = mul i64 %and1, %and2
+  ret i64 %mul
+}
Index: llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -375,6 +375,15 @@
   if (match(Op1, m_LShr(m_Value(X), m_APInt(C))) && *C == C->getBitWidth() - 1)
     return BinaryOperator::CreateAnd(Builder.CreateAShr(X, *C), Op0);
 
+  // X * Y --> X & Y, iff X, Y can be only 0 or 1
+  {
+    KnownBits XKnown = computeKnownBits(Op0, 0, &I);
+    KnownBits YKnown = computeKnownBits(Op1, 0, &I);
+    if ((XKnown.countMaxPopulation() == 1) &&
+        (YKnown.countMaxPopulation() == 1))
+      return BinaryOperator::CreateAnd(Op0, Op1);
+  }
+
   // ((ashr X, 31) | 1) * X --> abs(X)
   // X * ((ashr X, 31) | 1) --> abs(X)
   if (match(&I, m_c_BinOp(m_Or(m_AShr(m_Value(X),


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D126040.430946.patch
Type: text/x-patch
Size: 2393 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220520/00154a40/attachment.bin>


More information about the llvm-commits mailing list