[llvm] 394c683 - [InstCombine] sub(add(X,Y),umin(Y,Z)) --> add(X,usub.sat(Y,Z))

Chenbing Zheng via llvm-commits llvm-commits at lists.llvm.org
Sat May 7 02:20:07 PDT 2022


Author: Chenbing Zheng
Date: 2022-05-07T17:17:48+08:00
New Revision: 394c683d4063119086f91bbfbbd514a4ace31683

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

LOG: [InstCombine] sub(add(X,Y),umin(Y,Z)) --> add(X,usub.sat(Y,Z))

Alive2: https://alive2.llvm.org/ce/z/2UNVbp

Reviewed By: RKSimon, spatel

Differential Revision: https://reviews.llvm.org/D124503

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
    llvm/test/Transforms/InstCombine/sub-minmax.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 9e2215d43ea0..15176fc2055f 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -2015,11 +2015,10 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
     }
   }
 
-  {
-    // sub(add(X,Y), s/umin(X,Y)) --> s/umax(X,Y)
-    // sub(add(X,Y), s/umax(X,Y)) --> s/umin(X,Y)
-    // TODO: generalize to sub(add(Z,Y),umin(X,Y)) --> add(Z,usub.sat(Y,X))?
-    if (auto *II = dyn_cast<MinMaxIntrinsic>(Op1)) {
+  if (auto *II = dyn_cast<MinMaxIntrinsic>(Op1)) {
+    {
+      // sub(add(X,Y), s/umin(X,Y)) --> s/umax(X,Y)
+      // sub(add(X,Y), s/umax(X,Y)) --> s/umin(X,Y)
       Value *X = II->getLHS();
       Value *Y = II->getRHS();
       if (match(Op0, m_c_Add(m_Specific(X), m_Specific(Y))) &&
@@ -2029,6 +2028,19 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
         return replaceInstUsesWith(I, InvMaxMin);
       }
     }
+
+    {
+      // sub(add(X,Y),umin(Y,Z)) --> add(X,usub.sat(Y,Z))
+      // sub(add(X,Z),umin(Y,Z)) --> add(X,usub.sat(Y,Z))
+      Value *X, *Y, *Z;
+      if (match(Op1, m_OneUse(m_UMin(m_Value(Y), m_Value(Z)))) &&
+          (match(Op0, m_OneUse(m_c_Add(m_Specific(Y), m_Value(X)))) ||
+           match(Op0, m_OneUse(m_c_Add(m_Specific(Z), m_Value(X)))))) {
+        Value *USub =
+            Builder.CreateIntrinsic(Intrinsic::usub_sat, I.getType(), {Y, Z});
+        return BinaryOperator::CreateAdd(X, USub);
+      }
+    }
   }
 
   {

diff  --git a/llvm/test/Transforms/InstCombine/sub-minmax.ll b/llvm/test/Transforms/InstCombine/sub-minmax.ll
index 8465535fdb2e..059013cf304f 100644
--- a/llvm/test/Transforms/InstCombine/sub-minmax.ll
+++ b/llvm/test/Transforms/InstCombine/sub-minmax.ll
@@ -721,9 +721,8 @@ define i8 @
diff _add_use_umin_use(i8 %x, i8 %y) {
 
 define i8 @sub_add_umin(i8 %x, i8 %y, i8 %z) {
 ; CHECK-LABEL: @sub_add_umin(
-; CHECK-NEXT:    [[A:%.*]] = add i8 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[M:%.*]] = call i8 @llvm.umin.i8(i8 [[Y]], i8 [[Z:%.*]])
-; CHECK-NEXT:    [[S:%.*]] = sub i8 [[A]], [[M]]
+; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[Y:%.*]], i8 [[Z:%.*]])
+; CHECK-NEXT:    [[S:%.*]] = add i8 [[TMP1]], [[X:%.*]]
 ; CHECK-NEXT:    ret i8 [[S]]
 ;
   %a = add i8 %x, %y
@@ -734,9 +733,8 @@ define i8 @sub_add_umin(i8 %x, i8 %y, i8 %z) {
 
 define i8 @sub_add_umin_commute_umin(i8 %x, i8 %y, i8 %z) {
 ; CHECK-LABEL: @sub_add_umin_commute_umin(
-; CHECK-NEXT:    [[A:%.*]] = add i8 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[M:%.*]] = call i8 @llvm.umin.i8(i8 [[Z:%.*]], i8 [[Y]])
-; CHECK-NEXT:    [[S:%.*]] = sub i8 [[A]], [[M]]
+; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[Y:%.*]], i8 [[Z:%.*]])
+; CHECK-NEXT:    [[S:%.*]] = add i8 [[TMP1]], [[X:%.*]]
 ; CHECK-NEXT:    ret i8 [[S]]
 ;
   %a = add i8 %x, %y
@@ -747,9 +745,8 @@ define i8 @sub_add_umin_commute_umin(i8 %x, i8 %y, i8 %z) {
 
 define i8 @sub_add_umin_commute_add(i8 %x, i8 %y, i8 %z) {
 ; CHECK-LABEL: @sub_add_umin_commute_add(
-; CHECK-NEXT:    [[A:%.*]] = add i8 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[M:%.*]] = call i8 @llvm.umin.i8(i8 [[Y]], i8 [[Z:%.*]])
-; CHECK-NEXT:    [[S:%.*]] = sub i8 [[A]], [[M]]
+; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[Y:%.*]], i8 [[Z:%.*]])
+; CHECK-NEXT:    [[S:%.*]] = add i8 [[TMP1]], [[X:%.*]]
 ; CHECK-NEXT:    ret i8 [[S]]
 ;
   %a = add i8 %y, %x
@@ -760,9 +757,8 @@ define i8 @sub_add_umin_commute_add(i8 %x, i8 %y, i8 %z) {
 
 define i8 @sub_add_umin_commute_add_umin(i8 %x, i8 %y, i8 %z) {
 ; CHECK-LABEL: @sub_add_umin_commute_add_umin(
-; CHECK-NEXT:    [[A:%.*]] = add i8 [[Y:%.*]], [[X:%.*]]
-; CHECK-NEXT:    [[M:%.*]] = call i8 @llvm.umin.i8(i8 [[Z:%.*]], i8 [[Y]])
-; CHECK-NEXT:    [[S:%.*]] = sub i8 [[A]], [[M]]
+; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[Y:%.*]], i8 [[Z:%.*]])
+; CHECK-NEXT:    [[S:%.*]] = add i8 [[TMP1]], [[X:%.*]]
 ; CHECK-NEXT:    ret i8 [[S]]
 ;
   %a = add i8 %y, %x
@@ -773,9 +769,8 @@ define i8 @sub_add_umin_commute_add_umin(i8 %x, i8 %y, i8 %z) {
 
 define <2 x i8> @sub_add_umin_vec(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) {
 ; CHECK-LABEL: @sub_add_umin_vec(
-; CHECK-NEXT:    [[A:%.*]] = add <2 x i8> [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    [[M:%.*]] = call <2 x i8> @llvm.umin.v2i8(<2 x i8> [[Y]], <2 x i8> [[Z:%.*]])
-; CHECK-NEXT:    [[S:%.*]] = sub <2 x i8> [[A]], [[M]]
+; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> [[Y:%.*]], <2 x i8> [[Z:%.*]])
+; CHECK-NEXT:    [[S:%.*]] = add <2 x i8> [[TMP1]], [[X:%.*]]
 ; CHECK-NEXT:    ret <2 x i8> [[S]]
 ;
   %a = add <2 x i8> %x, %y


        


More information about the llvm-commits mailing list