[PATCH] D109059: [InstCombine] allow more min/max with 'not' folds for intrinsics

Sanjay Patel via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 1 06:08:12 PDT 2021


spatel created this revision.
spatel added reviewers: lebedev.ri, t.p.northover, nikic, dmgreen.
Herald added subscribers: hiraditya, mcrosier.
spatel requested review of this revision.
Herald added a project: LLVM.

isFreeToInvert allows min/max with 'not' on both operands, so easing the argument restriction catches the case where that operand has one use.

      

We already handle the sub-patterns when there are less uses:
https://alive2.llvm.org/ce/z/8Jatm_

...but this is another step towards parity with the equivalent icmp+select idioms ( D98152 <https://reviews.llvm.org/D98152> ).


https://reviews.llvm.org/D109059

Files:
  llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
  llvm/test/Transforms/InstCombine/minmax-intrinsics.ll


Index: llvm/test/Transforms/InstCombine/minmax-intrinsics.ll
===================================================================
--- llvm/test/Transforms/InstCombine/minmax-intrinsics.ll
+++ llvm/test/Transforms/InstCombine/minmax-intrinsics.ll
@@ -508,13 +508,13 @@
 
 define i8 @umin_of_not_and_smax(i8 %x, i8 %y, i8 %z) {
 ; CHECK-LABEL: @umin_of_not_and_smax(
-; CHECK-NEXT:    [[NOTX:%.*]] = xor i8 [[X:%.*]], -1
 ; CHECK-NEXT:    [[NOTY:%.*]] = xor i8 [[Y:%.*]], -1
 ; CHECK-NEXT:    call void @use(i8 [[NOTY]])
 ; CHECK-NEXT:    [[NOTZ:%.*]] = xor i8 [[Z:%.*]], -1
 ; CHECK-NEXT:    call void @use(i8 [[NOTZ]])
-; CHECK-NEXT:    [[M1:%.*]] = call i8 @llvm.smax.i8(i8 [[NOTY]], i8 [[NOTZ]])
-; CHECK-NEXT:    [[M2:%.*]] = call i8 @llvm.umin.i8(i8 [[M1]], i8 [[NOTX]])
+; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[Y]], i8 [[Z]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[TMP1]])
+; CHECK-NEXT:    [[M2:%.*]] = xor i8 [[TMP2]], -1
 ; CHECK-NEXT:    ret i8 [[M2]]
 ;
   %notx = xor i8 %x, -1
@@ -529,13 +529,13 @@
 
 define i8 @smin_of_umax_and_not(i8 %x, i8 %y, i8 %z) {
 ; CHECK-LABEL: @smin_of_umax_and_not(
-; CHECK-NEXT:    [[NOTX:%.*]] = xor i8 [[X:%.*]], -1
 ; CHECK-NEXT:    [[NOTY:%.*]] = xor i8 [[Y:%.*]], -1
 ; CHECK-NEXT:    call void @use(i8 [[NOTY]])
 ; CHECK-NEXT:    [[NOTZ:%.*]] = xor i8 [[Z:%.*]], -1
 ; CHECK-NEXT:    call void @use(i8 [[NOTZ]])
-; CHECK-NEXT:    [[M1:%.*]] = call i8 @llvm.umax.i8(i8 [[NOTY]], i8 [[NOTZ]])
-; CHECK-NEXT:    [[M2:%.*]] = call i8 @llvm.smin.i8(i8 [[NOTX]], i8 [[M1]])
+; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[Y]], i8 [[Z]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[TMP1]])
+; CHECK-NEXT:    [[M2:%.*]] = xor i8 [[TMP2]], -1
 ; CHECK-NEXT:    ret i8 [[M2]]
 ;
   %notx = xor i8 %x, -1
Index: llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -1082,13 +1082,12 @@
     // Examples:
     // max ~A, ~Y --> ~(min A, Y)
     // max ~A, C --> ~(min A, ~C)
+    // max ~A, (max ~Y, ~Z) --> ~min( A, (min Y, Z))
     auto moveNotAfterMinMax = [&](Value *X, Value *Y) -> Instruction * {
       Value *A;
       if (match(X, m_OneUse(m_Not(m_Value(A)))) &&
           !isFreeToInvert(A, A->hasOneUse()) &&
-          // Passing false to only consider m_Not and constants.
-          // TODO: Allow Y to match other patterns by checking use count.
-          isFreeToInvert(Y, false)) {
+          isFreeToInvert(Y, Y->hasOneUse())) {
         Value *NotY = Builder.CreateNot(Y);
         Intrinsic::ID InvID = getInverseMinMaxIntrinsic(IID);
         Value *InvMaxMin = Builder.CreateBinaryIntrinsic(InvID, A, NotY);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D109059.369912.patch
Type: text/x-patch
Size: 2850 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210901/5b377b1f/attachment.bin>


More information about the llvm-commits mailing list