[llvm] 84d6966 - [InstCombine] Propagate the nuw for combine of add+mul

via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 28 08:01:42 PDT 2022


Author: zhongyunde
Date: 2022-08-28T23:01:11+08:00
New Revision: 84d6966e4d6fe86e1cc198f4f61044a09daded3e

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

LOG: [InstCombine] Propagate the nuw for combine of add+mul

As the commit of D132658, make the 'nuw' change separately.
Reviewed By: spatel
Differential Revision: https://reviews.llvm.org/D132777

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 5ccd91d6aa24..d59a692eadc0 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -221,16 +221,23 @@ Instruction *InstCombinerImpl::visitMul(BinaryOperator &I) {
     return replaceInstUsesWith(I, FoldedMul);
 
   // Simplify mul instructions with a constant RHS.
-  if (isa<Constant>(Op1)) {
-    // Canonicalize (X+C1)*CI -> X*CI+C1*CI.
+  Constant *MulC;
+  if (match(Op1, m_ImmConstant(MulC))) {
+    // Canonicalize (X+C1)*MulC -> X*MulC+C1*MulC.
     Value *X;
     Constant *C1;
-    if (match(Op0, m_OneUse(m_Add(m_Value(X), m_Constant(C1))))) {
-      Value *Mul = Builder.CreateMul(C1, Op1);
-      // Only go forward with the transform if C1*CI simplifies to a tidier
-      // constant.
-      if (!match(Mul, m_Mul(m_Value(), m_Value())))
-        return BinaryOperator::CreateAdd(Builder.CreateMul(X, Op1), Mul);
+    if (match(Op0, m_OneUse(m_Add(m_Value(X), m_ImmConstant(C1))))) {
+      // C1*MulC simplifies to a tidier constant.
+      Value *NewC = Builder.CreateMul(C1, MulC);
+      auto *BOp0 = cast<BinaryOperator>(Op0);
+      Value *NewMul = Builder.CreateMul(X, MulC);
+      auto *BO = BinaryOperator::CreateAdd(NewMul, NewC);
+      auto *NewMulBO = dyn_cast<BinaryOperator>(NewMul);
+      if (I.hasNoUnsignedWrap() && BOp0->hasNoUnsignedWrap() && NewMulBO) {
+        NewMulBO->setHasNoUnsignedWrap();
+        BO->setHasNoUnsignedWrap();
+      }
+      return BO;
     }
   }
 

diff  --git a/llvm/test/Transforms/InstCombine/mul.ll b/llvm/test/Transforms/InstCombine/mul.ll
index c1a8c3113fba..22ed70df7b62 100644
--- a/llvm/test/Transforms/InstCombine/mul.ll
+++ b/llvm/test/Transforms/InstCombine/mul.ll
@@ -624,6 +624,53 @@ define i32 @PR20079(i32 %a) {
   ret i32 %mul
 }
 
+; Keep nuw flag in this change, https://alive2.llvm.org/ce/z/-Wowpk
+define i32 @add_mul_nuw(i32 %a) {
+; CHECK-LABEL: @add_mul_nuw(
+; CHECK-NEXT:    [[TMP1:%.*]] = mul nuw i32 [[A:%.*]], 3
+; CHECK-NEXT:    [[MUL:%.*]] = add nuw i32 [[TMP1]], 9
+; CHECK-NEXT:    ret i32 [[MUL]]
+;
+  %add = add nuw i32 %a, 3
+  %mul = mul nuw i32 %add, 3
+  ret i32 %mul
+}
+
+; Don't propagate nsw flag in this change
+define i32 @add_mul_nsw(i32 %a) {
+; CHECK-LABEL: @add_mul_nsw(
+; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[A:%.*]], 3
+; CHECK-NEXT:    [[MUL:%.*]] = add i32 [[TMP1]], 9
+; CHECK-NEXT:    ret i32 [[MUL]]
+;
+  %add = add nsw i32 %a, 3
+  %mul = mul nsw i32 %add, 3
+  ret i32 %mul
+}
+
+; Only the add or only the mul has nuw, https://alive2.llvm.org/ce/z/vPwbEa
+define i32 @only_add_nuw(i32 %a) {
+; CHECK-LABEL: @only_add_nuw(
+; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[A:%.*]], 3
+; CHECK-NEXT:    [[MUL:%.*]] = add i32 [[TMP1]], 9
+; CHECK-NEXT:    ret i32 [[MUL]]
+;
+  %add = add nuw i32 %a, 3
+  %mul = mul i32 %add, 3
+  ret i32 %mul
+}
+
+define i32 @only_mul_nuw(i32 %a) {
+; CHECK-LABEL: @only_mul_nuw(
+; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[A:%.*]], 3
+; CHECK-NEXT:    [[MUL:%.*]] = add i32 [[TMP1]], 9
+; CHECK-NEXT:    ret i32 [[MUL]]
+;
+  %add = add i32 %a, 3
+  %mul = mul nuw i32 %add, 3
+  ret i32 %mul
+}
+
 define <2 x i1> @test21(<2 x i1> %A, <2 x i1> %B) {
 ; CHECK-LABEL: @test21(
 ; CHECK-NEXT:    [[C:%.*]] = and <2 x i1> [[A:%.*]], [[B:%.*]]


        


More information about the llvm-commits mailing list