[llvm] b3ee127 - [InstCombine] integrate `N{U, S}WAddLike` into existing folds

Noah Goldstein via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 21 11:03:55 PDT 2024


Author: Noah Goldstein
Date: 2024-03-21T13:03:38-05:00
New Revision: b3ee127e7dead25fa284b26d2c5a067671d0e896

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

LOG: [InstCombine] integrate `N{U,S}WAddLike` into existing folds

Just went a quick replacement of `N{U,S}WAdd` with the `Like` variant
that old matches `or disjoint`

Closes #86082

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
    llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
    llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
    llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
    llvm/test/Transforms/InstCombine/add.ll
    llvm/test/Transforms/InstCombine/div.ll
    llvm/test/Transforms/InstCombine/sadd-with-overflow.ll
    llvm/test/Transforms/InstCombine/shift-add.ll
    llvm/test/Transforms/InstCombine/uadd-with-overflow.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index aaf7184a5562cd..a978e9a643f5e9 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -819,7 +819,7 @@ static Instruction *foldNoWrapAdd(BinaryOperator &Add,
   Value *X;
   const APInt *C1, *C2;
   if (match(Op1, m_APInt(C1)) &&
-      match(Op0, m_OneUse(m_ZExt(m_NUWAdd(m_Value(X), m_APInt(C2))))) &&
+      match(Op0, m_OneUse(m_ZExt(m_NUWAddLike(m_Value(X), m_APInt(C2))))) &&
       C1->isNegative() && C1->sge(-C2->sext(C1->getBitWidth()))) {
     Constant *NewC =
         ConstantInt::get(X->getType(), *C2 + C1->trunc(C2->getBitWidth()));
@@ -829,14 +829,16 @@ static Instruction *foldNoWrapAdd(BinaryOperator &Add,
   // More general combining of constants in the wide type.
   // (sext (X +nsw NarrowC)) + C --> (sext X) + (sext(NarrowC) + C)
   Constant *NarrowC;
-  if (match(Op0, m_OneUse(m_SExt(m_NSWAdd(m_Value(X), m_Constant(NarrowC)))))) {
+  if (match(Op0,
+            m_OneUse(m_SExt(m_NSWAddLike(m_Value(X), m_Constant(NarrowC)))))) {
     Value *WideC = Builder.CreateSExt(NarrowC, Ty);
     Value *NewC = Builder.CreateAdd(WideC, Op1C);
     Value *WideX = Builder.CreateSExt(X, Ty);
     return BinaryOperator::CreateAdd(WideX, NewC);
   }
   // (zext (X +nuw NarrowC)) + C --> (zext X) + (zext(NarrowC) + C)
-  if (match(Op0, m_OneUse(m_ZExt(m_NUWAdd(m_Value(X), m_Constant(NarrowC)))))) {
+  if (match(Op0,
+            m_OneUse(m_ZExt(m_NUWAddLike(m_Value(X), m_Constant(NarrowC)))))) {
     Value *WideC = Builder.CreateZExt(NarrowC, Ty);
     Value *NewC = Builder.CreateAdd(WideC, Op1C);
     Value *WideX = Builder.CreateZExt(X, Ty);

diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 426b548c074adf..526fe5d080599f 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -2093,8 +2093,9 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
     Value *Arg0 = II->getArgOperand(0);
     Value *Arg1 = II->getArgOperand(1);
     bool IsSigned = IID == Intrinsic::sadd_with_overflow;
-    bool HasNWAdd = IsSigned ? match(Arg0, m_NSWAdd(m_Value(X), m_APInt(C0)))
-                             : match(Arg0, m_NUWAdd(m_Value(X), m_APInt(C0)));
+    bool HasNWAdd = IsSigned
+                        ? match(Arg0, m_NSWAddLike(m_Value(X), m_APInt(C0)))
+                        : match(Arg0, m_NUWAddLike(m_Value(X), m_APInt(C0)));
     if (HasNWAdd && match(Arg1, m_APInt(C1))) {
       bool Overflow;
       APInt NewC =

diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index 6e05fd8fb4d6d1..10a4b1c2060c8d 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -1171,14 +1171,14 @@ Instruction *InstCombinerImpl::commonIDivTransforms(BinaryOperator &I) {
     // We need a multiple of the divisor for a signed add constant, but
     // unsigned is fine with any constant pair.
     if (IsSigned &&
-        match(Op0, m_NSWAdd(m_NSWMul(m_Value(X), m_SpecificInt(*C2)),
-                            m_APInt(C1))) &&
+        match(Op0, m_NSWAddLike(m_NSWMul(m_Value(X), m_SpecificInt(*C2)),
+                                m_APInt(C1))) &&
         isMultiple(*C1, *C2, Quotient, IsSigned)) {
       return BinaryOperator::CreateNSWAdd(X, ConstantInt::get(Ty, Quotient));
     }
     if (!IsSigned &&
-        match(Op0, m_NUWAdd(m_NUWMul(m_Value(X), m_SpecificInt(*C2)),
-                            m_APInt(C1)))) {
+        match(Op0, m_NUWAddLike(m_NUWMul(m_Value(X), m_SpecificInt(*C2)),
+                                m_APInt(C1)))) {
       return BinaryOperator::CreateNUWAdd(X,
                                           ConstantInt::get(Ty, C1->udiv(*C2)));
     }

diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
index eafd2889ec50bd..95aa2119e2d88b 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
@@ -437,7 +437,7 @@ Instruction *InstCombinerImpl::commonShiftTransforms(BinaryOperator &I) {
   Value *A;
   Constant *C, *C1;
   if (match(Op0, m_Constant(C)) &&
-      match(Op1, m_NUWAdd(m_Value(A), m_Constant(C1)))) {
+      match(Op1, m_NUWAddLike(m_Value(A), m_Constant(C1)))) {
     Value *NewC = Builder.CreateBinOp(I.getOpcode(), C, C1);
     BinaryOperator *NewShiftOp = BinaryOperator::Create(I.getOpcode(), NewC, A);
     if (I.getOpcode() == Instruction::Shl) {

diff  --git a/llvm/test/Transforms/InstCombine/add.ll b/llvm/test/Transforms/InstCombine/add.ll
index 846da7f760b1d4..ec3aca26514caf 100644
--- a/llvm/test/Transforms/InstCombine/add.ll
+++ b/llvm/test/Transforms/InstCombine/add.ll
@@ -3988,9 +3988,8 @@ define i32 @add_reduce_sqr_sum_varC_invalid2(i32 %a, i32 %b) {
 
 define i32 @fold_sext_addition_or_disjoint(i8 %x) {
 ; CHECK-LABEL: @fold_sext_addition_or_disjoint(
-; CHECK-NEXT:    [[XX:%.*]] = or disjoint i8 [[X:%.*]], 12
-; CHECK-NEXT:    [[SE:%.*]] = sext i8 [[XX]] to i32
-; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[SE]], 1234
+; CHECK-NEXT:    [[SE:%.*]] = sext i8 [[XX:%.*]] to i32
+; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[SE]], 1246
 ; CHECK-NEXT:    ret i32 [[R]]
 ;
   %xx = or disjoint i8 %x, 12
@@ -4014,9 +4013,8 @@ define i32 @fold_sext_addition_fail(i8 %x) {
 
 define i32 @fold_zext_addition_or_disjoint(i8 %x) {
 ; CHECK-LABEL: @fold_zext_addition_or_disjoint(
-; CHECK-NEXT:    [[XX:%.*]] = or disjoint i8 [[X:%.*]], 12
-; CHECK-NEXT:    [[SE:%.*]] = zext i8 [[XX]] to i32
-; CHECK-NEXT:    [[R:%.*]] = add nuw nsw i32 [[SE]], 1234
+; CHECK-NEXT:    [[SE:%.*]] = zext i8 [[XX:%.*]] to i32
+; CHECK-NEXT:    [[R:%.*]] = add nuw nsw i32 [[SE]], 1246
 ; CHECK-NEXT:    ret i32 [[R]]
 ;
   %xx = or disjoint i8 %x, 12
@@ -4027,10 +4025,9 @@ define i32 @fold_zext_addition_or_disjoint(i8 %x) {
 
 define i32 @fold_zext_addition_or_disjoint2(i8 %x) {
 ; CHECK-LABEL: @fold_zext_addition_or_disjoint2(
-; CHECK-NEXT:    [[XX:%.*]] = or disjoint i8 [[X:%.*]], 18
+; CHECK-NEXT:    [[XX:%.*]] = add nuw i8 [[X:%.*]], 4
 ; CHECK-NEXT:    [[SE:%.*]] = zext i8 [[XX]] to i32
-; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[SE]], -14
-; CHECK-NEXT:    ret i32 [[R]]
+; CHECK-NEXT:    ret i32 [[SE]]
 ;
   %xx = or disjoint i8 %x, 18
   %se = zext i8 %xx to i32

diff  --git a/llvm/test/Transforms/InstCombine/div.ll b/llvm/test/Transforms/InstCombine/div.ll
index a4d604b329c3c2..e8a25ff44d0296 100644
--- a/llvm/test/Transforms/InstCombine/div.ll
+++ b/llvm/test/Transforms/InstCombine/div.ll
@@ -1813,9 +1813,7 @@ define i6 @udiv_distribute_mul_nsw_add_nuw(i6 %x) {
 
 define i32 @fold_disjoint_or_over_sdiv(i32 %x) {
 ; CHECK-LABEL: @fold_disjoint_or_over_sdiv(
-; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[X:%.*]], 9
-; CHECK-NEXT:    [[OR:%.*]] = or disjoint i32 [[MUL]], 81
-; CHECK-NEXT:    [[R:%.*]] = sdiv i32 [[OR]], 9
+; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[X:%.*]], 9
 ; CHECK-NEXT:    ret i32 [[R]]
 ;
   %mul = mul nsw i32 %x, 9
@@ -1826,9 +1824,7 @@ define i32 @fold_disjoint_or_over_sdiv(i32 %x) {
 
 define i32 @fold_disjoint_or_over_udiv(i32 %x) {
 ; CHECK-LABEL: @fold_disjoint_or_over_udiv(
-; CHECK-NEXT:    [[MUL:%.*]] = mul nuw i32 [[X:%.*]], 9
-; CHECK-NEXT:    [[OR:%.*]] = or disjoint i32 [[MUL]], 81
-; CHECK-NEXT:    [[R:%.*]] = udiv i32 [[OR]], 9
+; CHECK-NEXT:    [[R:%.*]] = add nuw i32 [[X:%.*]], 9
 ; CHECK-NEXT:    ret i32 [[R]]
 ;
   %mul = mul nuw i32 %x, 9

diff  --git a/llvm/test/Transforms/InstCombine/sadd-with-overflow.ll b/llvm/test/Transforms/InstCombine/sadd-with-overflow.ll
index 904dd480caafa6..729ca03ddfd150 100644
--- a/llvm/test/Transforms/InstCombine/sadd-with-overflow.ll
+++ b/llvm/test/Transforms/InstCombine/sadd-with-overflow.ll
@@ -136,8 +136,7 @@ define { i32, i1 } @fold_with_distjoin_or(i32 %x) {
 
 define { i32, i1 } @fold_with_disjoint_or2(i32 %x) {
 ; CHECK-LABEL: @fold_with_disjoint_or2(
-; CHECK-NEXT:    [[A:%.*]] = or disjoint i32 [[X:%.*]], 100
-; CHECK-NEXT:    [[B:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[A]], i32 27)
+; CHECK-NEXT:    [[B:%.*]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X:%.*]], i32 127)
 ; CHECK-NEXT:    ret { i32, i1 } [[B]]
 ;
   %a = or disjoint i32 %x, 100

diff  --git a/llvm/test/Transforms/InstCombine/shift-add.ll b/llvm/test/Transforms/InstCombine/shift-add.ll
index 2be6d9b29d5269..aa3a238e0949ce 100644
--- a/llvm/test/Transforms/InstCombine/shift-add.ll
+++ b/llvm/test/Transforms/InstCombine/shift-add.ll
@@ -778,8 +778,7 @@ define <3 x i32> @add3_i96(<3 x i32> %0, <3 x i32> %1) {
 
 define i8 @shl_fold_or_disjoint_cnt(i8 %x) {
 ; CHECK-LABEL: @shl_fold_or_disjoint_cnt(
-; CHECK-NEXT:    [[A:%.*]] = or disjoint i8 [[X:%.*]], 3
-; CHECK-NEXT:    [[R:%.*]] = shl i8 2, [[A]]
+; CHECK-NEXT:    [[R:%.*]] = shl i8 16, [[X:%.*]]
 ; CHECK-NEXT:    ret i8 [[R]]
 ;
   %a = or disjoint i8 %x, 3
@@ -789,8 +788,7 @@ define i8 @shl_fold_or_disjoint_cnt(i8 %x) {
 
 define <2 x i8> @ashr_fold_or_disjoint_cnt(<2 x i8> %x) {
 ; CHECK-LABEL: @ashr_fold_or_disjoint_cnt(
-; CHECK-NEXT:    [[A:%.*]] = or disjoint <2 x i8> [[X:%.*]], <i8 3, i8 1>
-; CHECK-NEXT:    [[R:%.*]] = lshr <2 x i8> <i8 2, i8 3>, [[A]]
+; CHECK-NEXT:    [[R:%.*]] = lshr <2 x i8> <i8 0, i8 1>, [[X:%.*]]
 ; CHECK-NEXT:    ret <2 x i8> [[R]]
 ;
   %a = or disjoint <2 x i8> %x, <i8 3, i8 1>
@@ -800,9 +798,7 @@ define <2 x i8> @ashr_fold_or_disjoint_cnt(<2 x i8> %x) {
 
 define <2 x i8> @lshr_fold_or_disjoint_cnt_out_of_bounds(<2 x i8> %x) {
 ; CHECK-LABEL: @lshr_fold_or_disjoint_cnt_out_of_bounds(
-; CHECK-NEXT:    [[A:%.*]] = or disjoint <2 x i8> [[X:%.*]], <i8 3, i8 8>
-; CHECK-NEXT:    [[R:%.*]] = lshr <2 x i8> <i8 2, i8 3>, [[A]]
-; CHECK-NEXT:    ret <2 x i8> [[R]]
+; CHECK-NEXT:    ret <2 x i8> zeroinitializer
 ;
   %a = or disjoint <2 x i8> %x, <i8 3, i8 8>
   %r = lshr <2 x i8> <i8 2, i8 3>, %a

diff  --git a/llvm/test/Transforms/InstCombine/uadd-with-overflow.ll b/llvm/test/Transforms/InstCombine/uadd-with-overflow.ll
index b1819e6c3e2b67..fd5d38bb38ddc7 100644
--- a/llvm/test/Transforms/InstCombine/uadd-with-overflow.ll
+++ b/llvm/test/Transforms/InstCombine/uadd-with-overflow.ll
@@ -128,8 +128,7 @@ define { i32, i1 } @no_fold_wrapped_add(i32 %x) {
 
 define { <2 x i32>, <2 x i1> } @fold_simple_splat_with_disjoint_or_constant(<2 x i32> %x) {
 ; CHECK-LABEL: @fold_simple_splat_with_disjoint_or_constant(
-; CHECK-NEXT:    [[A:%.*]] = or disjoint <2 x i32> [[X:%.*]], <i32 12, i32 12>
-; CHECK-NEXT:    [[B:%.*]] = tail call { <2 x i32>, <2 x i1> } @llvm.uadd.with.overflow.v2i32(<2 x i32> [[A]], <2 x i32> <i32 30, i32 30>)
+; CHECK-NEXT:    [[B:%.*]] = call { <2 x i32>, <2 x i1> } @llvm.uadd.with.overflow.v2i32(<2 x i32> [[X:%.*]], <2 x i32> <i32 42, i32 42>)
 ; CHECK-NEXT:    ret { <2 x i32>, <2 x i1> } [[B]]
 ;
   %a = or disjoint <2 x i32> %x, <i32 12, i32 12>


        


More information about the llvm-commits mailing list