[llvm] d0975b7 - [InstCombine] fold signed min/max intrinsics with negated operands

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 17 10:14:04 PDT 2021


Yes - we wouldn't reduce instruction count if one operand is a constant,
but it would be a canonicalization:
https://alive2.llvm.org/ce/z/TSMHcc

I'll add a TODO note for now. Trying to squash some other known min/max
regressions currently.

On Tue, Aug 17, 2021 at 12:06 PM Philip Reames <listmail at philipreames.com>
wrote:

> It looks like this should be legal for anything which can be cheaply
> negated.  Have you looked at cases such as smax (neg nsw X), C1?
>
> Philip
>
> On 8/17/21 5:16 AM, Sanjay Patel via llvm-commits wrote:
> > Author: Sanjay Patel
> > Date: 2021-08-17T08:10:42-04:00
> > New Revision: d0975b7cb0e184e8e5f3975183c51937dfa4043a
> >
> > URL:
> https://github.com/llvm/llvm-project/commit/d0975b7cb0e184e8e5f3975183c51937dfa4043a
> > DIFF:
> https://github.com/llvm/llvm-project/commit/d0975b7cb0e184e8e5f3975183c51937dfa4043a.diff
> >
> > LOG: [InstCombine] fold signed min/max intrinsics with negated operands
> >
> > If both operands are negated, we can invert the min/max and do
> > the negation after:
> > smax (neg nsw X), (neg nsw Y) --> neg nsw (smin X, Y)
> > smin (neg nsw X), (neg nsw Y) --> neg nsw (smax X, Y)
> >
> > This is visible as a remaining regression in D98152. I don't see
> > a way to generalize this for 'unsigned' or adapt Negator to
> > handle it. This only appears to be safe with 'nsw':
> > https://alive2.llvm.org/ce/z/GUy1zJ
> >
> > Differential Revision: https://reviews.llvm.org/D108165
> >
> > 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 25597840cad3..e3dd12c0c773 100644
> > --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
> > +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
> > @@ -1065,6 +1065,17 @@ Instruction
> *InstCombinerImpl::visitCallInst(CallInst &CI) {
> >         }
> >       }
> >
> > +    if (IID == Intrinsic::smax || IID == Intrinsic::smin) {
> > +      // smax (neg nsw X), (neg nsw Y) --> neg nsw (smin X, Y)
> > +      // smin (neg nsw X), (neg nsw Y) --> neg nsw (smax X, Y)
> > +      if (match(I0, m_NSWNeg(m_Value(X))) && match(I1,
> m_NSWNeg(m_Value(Y))) &&
> > +          (I0->hasOneUse() || I1->hasOneUse())) {
> > +        Intrinsic::ID InvID = getInverseMinMaxIntrinsic(IID);
> > +        Value *InvMaxMin = Builder.CreateBinaryIntrinsic(InvID, X, Y);
> > +        return BinaryOperator::CreateNSWNeg(InvMaxMin);
> > +      }
> > +    }
> > +
> >       if (match(I0, m_Not(m_Value(X)))) {
> >         // max (not X), (not Y) --> not (min X, Y)
> >         Intrinsic::ID InvID = getInverseMinMaxIntrinsic(IID);
> >
> > diff  --git a/llvm/test/Transforms/InstCombine/minmax-intrinsics.ll
> b/llvm/test/Transforms/InstCombine/minmax-intrinsics.ll
> > index a3dbbc9dcbde..b46ddabffd95 100644
> > --- a/llvm/test/Transforms/InstCombine/minmax-intrinsics.ll
> > +++ b/llvm/test/Transforms/InstCombine/minmax-intrinsics.ll
> > @@ -1033,9 +1033,8 @@ define i8 @umin_demand_and_7_8(i8 %x) {
> >
> >   define i8 @neg_neg_nsw_smax(i8 %x, i8 %y) {
> >   ; CHECK-LABEL: @neg_neg_nsw_smax(
> > -; CHECK-NEXT:    [[NX:%.*]] = sub nsw i8 0, [[X:%.*]]
> > -; CHECK-NEXT:    [[NY:%.*]] = sub nsw i8 0, [[Y:%.*]]
> > -; CHECK-NEXT:    [[M:%.*]] = call i8 @llvm.smax.i8(i8 [[NX]], i8 [[NY]])
> > +; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8
> [[Y:%.*]])
> > +; CHECK-NEXT:    [[M:%.*]] = sub nsw i8 0, [[TMP1]]
> >   ; CHECK-NEXT:    ret i8 [[M]]
> >   ;
> >     %nx = sub nsw i8 0, %x
> > @@ -1046,9 +1045,8 @@ define i8 @neg_neg_nsw_smax(i8 %x, i8 %y) {
> >
> >   define <3 x i8> @neg_neg_nsw_smin(<3 x i8> %x, <3 x i8> %y) {
> >   ; CHECK-LABEL: @neg_neg_nsw_smin(
> > -; CHECK-NEXT:    [[NX:%.*]] = sub nsw <3 x i8> zeroinitializer,
> [[X:%.*]]
> > -; CHECK-NEXT:    [[NY:%.*]] = sub nsw <3 x i8> zeroinitializer,
> [[Y:%.*]]
> > -; CHECK-NEXT:    [[M:%.*]] = call <3 x i8> @llvm.smin.v3i8(<3 x i8>
> [[NX]], <3 x i8> [[NY]])
> > +; CHECK-NEXT:    [[TMP1:%.*]] = call <3 x i8> @llvm.smax.v3i8(<3 x i8>
> [[X:%.*]], <3 x i8> [[Y:%.*]])
> > +; CHECK-NEXT:    [[M:%.*]] = sub nsw <3 x i8> zeroinitializer, [[TMP1]]
> >   ; CHECK-NEXT:    ret <3 x i8> [[M]]
> >   ;
> >     %nx = sub nsw <3 x i8> zeroinitializer, %x
> > @@ -1061,8 +1059,8 @@ define i8 @neg_neg_nsw_smax_use0(i8 %x, i8 %y) {
> >   ; CHECK-LABEL: @neg_neg_nsw_smax_use0(
> >   ; CHECK-NEXT:    [[NX:%.*]] = sub nsw i8 0, [[X:%.*]]
> >   ; CHECK-NEXT:    call void @use(i8 [[NX]])
> > -; CHECK-NEXT:    [[NY:%.*]] = sub nsw i8 0, [[Y:%.*]]
> > -; CHECK-NEXT:    [[M:%.*]] = call i8 @llvm.smax.i8(i8 [[NX]], i8 [[NY]])
> > +; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[X]], i8
> [[Y:%.*]])
> > +; CHECK-NEXT:    [[M:%.*]] = sub nsw i8 0, [[TMP1]]
> >   ; CHECK-NEXT:    ret i8 [[M]]
> >   ;
> >     %nx = sub nsw i8 0, %x
> > @@ -1074,10 +1072,10 @@ define i8 @neg_neg_nsw_smax_use0(i8 %x, i8 %y) {
> >
> >   define i8 @neg_neg_nsw_smin_use1(i8 %x, i8 %y) {
> >   ; CHECK-LABEL: @neg_neg_nsw_smin_use1(
> > -; CHECK-NEXT:    [[NX:%.*]] = sub nsw i8 0, [[X:%.*]]
> >   ; CHECK-NEXT:    [[NY:%.*]] = sub nsw i8 0, [[Y:%.*]]
> >   ; CHECK-NEXT:    call void @use(i8 [[NY]])
> > -; CHECK-NEXT:    [[M:%.*]] = call i8 @llvm.smin.i8(i8 [[NX]], i8 [[NY]])
> > +; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8
> [[Y]])
> > +; CHECK-NEXT:    [[M:%.*]] = sub nsw i8 0, [[TMP1]]
> >   ; CHECK-NEXT:    ret i8 [[M]]
> >   ;
> >     %nx = sub nsw i8 0, %x
> > @@ -1087,6 +1085,8 @@ define i8 @neg_neg_nsw_smin_use1(i8 %x, i8 %y) {
> >     ret i8 %m
> >   }
> >
> > +; negative test - too many uses
> > +
> >   define i8 @neg_neg_nsw_smin_use2(i8 %x, i8 %y) {
> >   ; CHECK-LABEL: @neg_neg_nsw_smin_use2(
> >   ; CHECK-NEXT:    [[NX:%.*]] = sub nsw i8 0, [[X:%.*]]
> > @@ -1104,6 +1104,8 @@ define i8 @neg_neg_nsw_smin_use2(i8 %x, i8 %y) {
> >     ret i8 %m
> >   }
> >
> > +; negative test - need nsw on both ops
> > +
> >   define i8 @neg_neg_smax(i8 %x, i8 %y) {
> >   ; CHECK-LABEL: @neg_neg_smax(
> >   ; CHECK-NEXT:    [[NX:%.*]] = sub i8 0, [[X:%.*]]
> > @@ -1117,6 +1119,8 @@ define i8 @neg_neg_smax(i8 %x, i8 %y) {
> >     ret i8 %m
> >   }
> >
> > +; negative test - need nsw on both ops
> > +
> >   define i8 @neg_neg_smin(i8 %x, i8 %y) {
> >   ; CHECK-LABEL: @neg_neg_smin(
> >   ; CHECK-NEXT:    [[NX:%.*]] = sub i8 0, [[X:%.*]]
> > @@ -1130,6 +1134,8 @@ define i8 @neg_neg_smin(i8 %x, i8 %y) {
> >     ret i8 %m
> >   }
> >
> > +; negative test - need signed min/max
> > +
> >   define i8 @neg_neg_nsw_umin(i8 %x, i8 %y) {
> >   ; CHECK-LABEL: @neg_neg_nsw_umin(
> >   ; CHECK-NEXT:    [[NX:%.*]] = sub nsw i8 0, [[X:%.*]]
> >
> >
> >
> > _______________________________________________
> > llvm-commits mailing list
> > llvm-commits at lists.llvm.org
> > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210817/99cb3806/attachment.html>


More information about the llvm-commits mailing list