[llvm] 8c7a7e1 - [InstCombine] allow more min/max with 'not' folds for intrinsics

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 1 11:40:46 PDT 2021


Author: Sanjay Patel
Date: 2021-09-01T14:40:00-04:00
New Revision: 8c7a7e1f67b12d250fbd6cbd3aed39dccacd53bf

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

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

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 ).

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

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 2c7254beda25..048cc8470989 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -1082,13 +1082,12 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
     // 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);

diff  --git a/llvm/test/Transforms/InstCombine/minmax-intrinsics.ll b/llvm/test/Transforms/InstCombine/minmax-intrinsics.ll
index 827f2f7fe4c7..1b54144bd966 100644
--- a/llvm/test/Transforms/InstCombine/minmax-intrinsics.ll
+++ b/llvm/test/Transforms/InstCombine/minmax-intrinsics.ll
@@ -508,13 +508,13 @@ define i8 @umin_of_not_and_const(i8 %x) {
 
 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 @umin_of_not_and_smax(i8 %x, i8 %y, i8 %z) {
 
 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


        


More information about the llvm-commits mailing list