[PATCH] D145540: [InstCombine] Reduce absolute diff from min+max+sub

Jun Zhang via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 8 02:56:26 PST 2023


junaire updated this revision to Diff 503290.
junaire added a comment.

Rebase


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D145540

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


Index: llvm/test/Transforms/InstCombine/sub-minmax.ll
===================================================================
--- llvm/test/Transforms/InstCombine/sub-minmax.ll
+++ llvm/test/Transforms/InstCombine/sub-minmax.ll
@@ -1001,9 +1001,8 @@
 define i8 @sub_max_min_nsw(i8 %a, i8 %b) {
 ; CHECK-LABEL: define {{[^@]+}}@sub_max_min_nsw
 ; CHECK-SAME: (i8 [[A:%.*]], i8 [[B:%.*]]) {
-; CHECK-NEXT:    [[MIN:%.*]] = call i8 @llvm.smin.i8(i8 [[A]], i8 [[B]])
-; CHECK-NEXT:    [[MAX:%.*]] = call i8 @llvm.smax.i8(i8 [[A]], i8 [[B]])
-; CHECK-NEXT:    [[AB:%.*]] = sub nsw i8 [[MAX]], [[MIN]]
+; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i8 [[A]], [[B]]
+; CHECK-NEXT:    [[AB:%.*]] = call i8 @llvm.abs.i8(i8 [[SUB]], i1 true)
 ; CHECK-NEXT:    ret i8 [[AB]]
 ;
   %min = call i8 @llvm.smin.i8(i8 %a, i8 %b)
@@ -1015,9 +1014,8 @@
 define i8 @sub_max_min_nuw(i8 %a, i8 %b) {
 ; CHECK-LABEL: define {{[^@]+}}@sub_max_min_nuw
 ; CHECK-SAME: (i8 [[A:%.*]], i8 [[B:%.*]]) {
-; CHECK-NEXT:    [[MIN:%.*]] = call i8 @llvm.smin.i8(i8 [[A]], i8 [[B]])
-; CHECK-NEXT:    [[MAX:%.*]] = call i8 @llvm.smax.i8(i8 [[A]], i8 [[B]])
-; CHECK-NEXT:    [[AB:%.*]] = sub nuw i8 [[MAX]], [[MIN]]
+; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i8 [[A]], [[B]]
+; CHECK-NEXT:    [[AB:%.*]] = call i8 @llvm.abs.i8(i8 [[SUB]], i1 true)
 ; CHECK-NEXT:    ret i8 [[AB]]
 ;
   %min = call i8 @llvm.smin.i8(i8 %a, i8 %b)
@@ -1029,9 +1027,8 @@
 define <2 x i8> @sub_max_min_vec_nsw(<2 x i8> %a, <2 x i8> %b) {
 ; CHECK-LABEL: define {{[^@]+}}@sub_max_min_vec_nsw
 ; CHECK-SAME: (<2 x i8> [[A:%.*]], <2 x i8> [[B:%.*]]) {
-; CHECK-NEXT:    [[MIN:%.*]] = call <2 x i8> @llvm.smin.v2i8(<2 x i8> [[A]], <2 x i8> [[B]])
-; CHECK-NEXT:    [[MAX:%.*]] = call <2 x i8> @llvm.smax.v2i8(<2 x i8> [[A]], <2 x i8> [[B]])
-; CHECK-NEXT:    [[AB:%.*]] = sub nsw <2 x i8> [[MAX]], [[MIN]]
+; CHECK-NEXT:    [[SUB:%.*]] = sub nsw <2 x i8> [[A]], [[B]]
+; CHECK-NEXT:    [[AB:%.*]] = call <2 x i8> @llvm.abs.v2i8(<2 x i8> [[SUB]], i1 true)
 ; CHECK-NEXT:    ret <2 x i8> [[AB]]
 ;
   %min = call <2 x i8> @llvm.smin.v2i8(<2 x i8> %a, <2 x i8> %b)
@@ -1043,9 +1040,8 @@
 define <2 x i8> @sub_max_min_vec_nuw(<2 x i8> %a, <2 x i8> %b) {
 ; CHECK-LABEL: define {{[^@]+}}@sub_max_min_vec_nuw
 ; CHECK-SAME: (<2 x i8> [[A:%.*]], <2 x i8> [[B:%.*]]) {
-; CHECK-NEXT:    [[MIN:%.*]] = call <2 x i8> @llvm.smin.v2i8(<2 x i8> [[A]], <2 x i8> [[B]])
-; CHECK-NEXT:    [[MAX:%.*]] = call <2 x i8> @llvm.smax.v2i8(<2 x i8> [[A]], <2 x i8> [[B]])
-; CHECK-NEXT:    [[AB:%.*]] = sub nuw <2 x i8> [[MAX]], [[MIN]]
+; CHECK-NEXT:    [[SUB:%.*]] = sub nsw <2 x i8> [[A]], [[B]]
+; CHECK-NEXT:    [[AB:%.*]] = call <2 x i8> @llvm.abs.v2i8(<2 x i8> [[SUB]], i1 true)
 ; CHECK-NEXT:    ret <2 x i8> [[AB]]
 ;
   %min = call <2 x i8> @llvm.smin.v2i8(<2 x i8> %a, <2 x i8> %b)
Index: llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -2406,6 +2406,20 @@
     return replaceInstUsesWith(I, Mul);
   }
 
+  // max(X,Y) nsw/nuw - min(X,Y) --> abs(X nsw - Y)
+  if (match(Op0,
+            m_OneUse(m_Intrinsic<Intrinsic::smax>(m_Value(X), m_Value(Y)))) &&
+      match(Op1, m_OneUse(m_Intrinsic<Intrinsic::smin>(m_Specific(X),
+                                                       m_Specific(Y))))) {
+    if (I.hasNoUnsignedWrap() || I.hasNoSignedWrap()) {
+      Value *Sub =
+          Builder.CreateSub(X, Y, "sub", /*HasNUW=*/ false, /*HasNSW=*/ true);
+      Value *Call =
+          Builder.CreateBinaryIntrinsic(Intrinsic::abs, Sub, Builder.getTrue());
+      return replaceInstUsesWith(I, Call);
+    }
+  }
+
   return TryToNarrowDeduceFlags();
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D145540.503290.patch
Type: text/x-patch
Size: 3769 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230308/7efe876e/attachment.bin>


More information about the llvm-commits mailing list