[llvm] 7fd8af1 - [InstCombine] fold mul of sext bools to 'and'

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 3 14:29:07 PDT 2020


Author: Sanjay Patel
Date: 2020-07-03T17:28:40-04:00
New Revision: 7fd8af1de052e5bb0e07adba1d2c9e58d1a8f6a4

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

LOG: [InstCombine] fold mul of sext bools to 'and'

Alive2:
  define i32 @src(i1 %x, i1 %y) {
  %0:
  %zx = sext i1 %x to i32
  %zy = sext i1 %y to i32
  %r = mul i32 %zx, %zy
  ret i32 %r
  }
  =>
  define i32 @tgt(i1 %x, i1 %y) {
  %0:
  %a = and i1 %x, %y
  %r = zext i1 %a to i32
  ret i32 %r
  }
  Transformation seems to be correct!

https://alive2.llvm.org/ce/z/gaPQxA

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
    llvm/test/Transforms/InstCombine/mul.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index 39b6c6765fad..2965103d4029 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -367,8 +367,11 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
   }
 
   // (zext bool X) * (zext bool Y) --> zext (and X, Y)
-  if (match(Op0, m_ZExt(m_Value(X))) && X->getType()->isIntOrIntVectorTy(1) &&
-      match(Op1, m_ZExt(m_Value(Y))) && Y->getType()->isIntOrIntVectorTy(1) &&
+  // (sext bool X) * (sext bool Y) --> zext (and X, Y)
+  // Note: -1 * -1 == 1 * 1 == 1 (if the extends match, the result is the same)
+  if (((match(Op0, m_ZExt(m_Value(X))) && match(Op1, m_ZExt(m_Value(Y)))) ||
+       (match(Op0, m_SExt(m_Value(X))) && match(Op1, m_SExt(m_Value(Y))))) &&
+      X->getType()->isIntOrIntVectorTy(1) && X->getType() == Y->getType() &&
       (Op0->hasOneUse() || Op1->hasOneUse())) {
     Value *And = Builder.CreateAnd(X, Y, "mulbool");
     return CastInst::Create(Instruction::ZExt, And, I.getType());

diff  --git a/llvm/test/Transforms/InstCombine/mul.ll b/llvm/test/Transforms/InstCombine/mul.ll
index b23dff3eeb52..9d1b8ad457e4 100644
--- a/llvm/test/Transforms/InstCombine/mul.ll
+++ b/llvm/test/Transforms/InstCombine/mul.ll
@@ -188,9 +188,8 @@ define i32 @mul_bools_use3(i1 %x, i1 %y) {
 
 define <3 x i32> @mul_bools_sext(<3 x i1> %x, <3 x i1> %y) {
 ; CHECK-LABEL: @mul_bools_sext(
-; CHECK-NEXT:    [[SX:%.*]] = sext <3 x i1> [[X:%.*]] to <3 x i32>
-; CHECK-NEXT:    [[SY:%.*]] = sext <3 x i1> [[Y:%.*]] to <3 x i32>
-; CHECK-NEXT:    [[R:%.*]] = mul nsw <3 x i32> [[SX]], [[SY]]
+; CHECK-NEXT:    [[MULBOOL:%.*]] = and <3 x i1> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = zext <3 x i1> [[MULBOOL]] to <3 x i32>
 ; CHECK-NEXT:    ret <3 x i32> [[R]]
 ;
   %sx = sext <3 x i1> %x to <3 x i32>
@@ -201,10 +200,10 @@ define <3 x i32> @mul_bools_sext(<3 x i1> %x, <3 x i1> %y) {
 
 define i32 @mul_bools_sext_use1(i1 %x, i1 %y) {
 ; CHECK-LABEL: @mul_bools_sext_use1(
-; CHECK-NEXT:    [[SX:%.*]] = sext i1 [[X:%.*]] to i32
 ; CHECK-NEXT:    [[SY:%.*]] = sext i1 [[Y:%.*]] to i32
 ; CHECK-NEXT:    call void @use32(i32 [[SY]])
-; CHECK-NEXT:    [[R:%.*]] = mul nsw i32 [[SX]], [[SY]]
+; CHECK-NEXT:    [[MULBOOL:%.*]] = and i1 [[X:%.*]], [[Y]]
+; CHECK-NEXT:    [[R:%.*]] = zext i1 [[MULBOOL]] to i32
 ; CHECK-NEXT:    ret i32 [[R]]
 ;
   %sx = sext i1 %x to i32
@@ -216,10 +215,10 @@ define i32 @mul_bools_sext_use1(i1 %x, i1 %y) {
 
 define i32 @mul_bools_sext_use2(i1 %x, i1 %y) {
 ; CHECK-LABEL: @mul_bools_sext_use2(
-; CHECK-NEXT:    [[SX:%.*]] = sext i1 [[X:%.*]] to i32
 ; CHECK-NEXT:    [[SY:%.*]] = sext i1 [[Y:%.*]] to i32
 ; CHECK-NEXT:    call void @use32(i32 [[SY]])
-; CHECK-NEXT:    [[R:%.*]] = mul nsw i32 [[SY]], [[SX]]
+; CHECK-NEXT:    [[MULBOOL:%.*]] = and i1 [[Y]], [[X:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = zext i1 [[MULBOOL]] to i32
 ; CHECK-NEXT:    ret i32 [[R]]
 ;
   %sx = sext i1 %x to i32


        


More information about the llvm-commits mailing list