[llvm] r321882 - [InstCombine] add folds for min(~a, b) --> ~max(a, b)

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 5 11:16:09 PST 2018


Typo'd the formula in the commit title. It should be as shown in the code:
min(~a, ~b) --> ~max(a, b)
...both operands are 'not'

On Fri, Jan 5, 2018 at 12:01 PM, Sanjay Patel via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

> Author: spatel
> Date: Fri Jan  5 11:01:17 2018
> New Revision: 321882
>
> URL: http://llvm.org/viewvc/llvm-project?rev=321882&view=rev
> Log:
> [InstCombine] add folds for min(~a, b) --> ~max(a, b)
>
> Besides the bug of omitting the inverse transform of max(~a, ~b) -->
> ~min(a, b),
> the use checking and operand creation were off. We were potentially
> creating
> repeated identical instructions of existing values. This led to infinite
> looping after I added the extra folds.
>
> By using the simpler m_Not matcher and not creating new 'not' ops for a
> and b,
> we avoid that problem. It's possible that not using IsFreeToInvert() here
> is
> more limiting than the simpler matcher, but there are no tests for anything
> more exotic. It's also possible that we should relax the use checking
> further
> to handle a case like PR35834:
> https://bugs.llvm.org/show_bug.cgi?id=35834
> ...but we can make that a follow-up if it is needed.
>
> Modified:
>     llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp
>     llvm/trunk/test/Transforms/InstCombine/max-of-nots.ll
>
> Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/
> Transforms/InstCombine/InstCombineSelect.cpp?rev=
> 321882&r1=321881&r2=321882&view=diff
> ============================================================
> ==================
> --- llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp (original)
> +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp Fri Jan
> 5 11:01:17 2018
> @@ -1551,6 +1551,18 @@ Instruction *InstCombiner::visitSelectIn
>          Value *NewCast = Builder.CreateCast(CastOp, NewSI, SelType);
>          return replaceInstUsesWith(SI, NewCast);
>        }
> +
> +      // MAX(~a, ~b) -> ~MIN(a, b)
> +      // MIN(~a, ~b) -> ~MAX(a, b)
> +      Value *A, *B;
> +      if (match(LHS, m_Not(m_Value(A))) && LHS->getNumUses() <= 2 &&
> +          match(RHS, m_Not(m_Value(B))) && RHS->getNumUses() <= 2) {
> +        CmpInst::Predicate InvertedPred =
> +            getCmpPredicateForMinMax(getInverseMinMaxSelectPattern(SPF));
> +        Value *InvertedCmp = Builder.CreateICmp(InvertedPred, A, B);
> +        Value *NewSel = Builder.CreateSelect(InvertedCmp, A, B);
> +        return BinaryOperator::CreateNot(NewSel);
> +      }
>      }
>
>      if (SPF) {
> @@ -1570,28 +1582,6 @@ Instruction *InstCombiner::visitSelectIn
>            return R;
>      }
>
> -    // MAX(~a, ~b) -> ~MIN(a, b)
> -    if ((SPF == SPF_SMAX || SPF == SPF_UMAX) &&
> -        IsFreeToInvert(LHS, LHS->hasNUses(2)) &&
> -        IsFreeToInvert(RHS, RHS->hasNUses(2))) {
> -      // For this transform to be profitable, we need to eliminate at
> least two
> -      // 'not' instructions if we're going to add one 'not' instruction.
> -      int NumberOfNots =
> -          (LHS->hasNUses(2) && match(LHS, m_Not(m_Value()))) +
> -          (RHS->hasNUses(2) && match(RHS, m_Not(m_Value()))) +
> -          (SI.hasOneUse() && match(*SI.user_begin(), m_Not(m_Value())));
> -
> -      if (NumberOfNots >= 2) {
> -        Value *NewLHS = Builder.CreateNot(LHS);
> -        Value *NewRHS = Builder.CreateNot(RHS);
> -        Value *NewCmp = SPF == SPF_SMAX ? Builder.CreateICmpSLT(NewLHS,
> NewRHS)
> -                                        : Builder.CreateICmpULT(NewLHS,
> NewRHS);
> -        Value *NewSI =
> -            Builder.CreateNot(Builder.CreateSelect(NewCmp, NewLHS,
> NewRHS));
> -        return replaceInstUsesWith(SI, NewSI);
> -      }
> -    }
> -
>      // TODO.
>      // ABS(-X) -> ABS(X)
>    }
>
> Modified: llvm/trunk/test/Transforms/InstCombine/max-of-nots.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/
> Transforms/InstCombine/max-of-nots.ll?rev=321882&r1=321881&
> r2=321882&view=diff
> ============================================================
> ==================
> --- llvm/trunk/test/Transforms/InstCombine/max-of-nots.ll (original)
> +++ llvm/trunk/test/Transforms/InstCombine/max-of-nots.ll Fri Jan  5
> 11:01:17 2018
> @@ -1,6 +1,34 @@
>  ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
>  ; RUN: opt -S -instcombine < %s | FileCheck %s
>
> +define <2 x i32> @umin_of_nots(<2 x i32> %x, <2 x i32> %y) {
> +; CHECK-LABEL: @umin_of_nots(
> +; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt <2 x i32> %x, %y
> +; CHECK-NEXT:    [[TMP2:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> %x,
> <2 x i32> %y
> +; CHECK-NEXT:    [[MIN:%.*]] = xor <2 x i32> [[TMP2]], <i32 -1, i32 -1>
> +; CHECK-NEXT:    ret <2 x i32> [[MIN]]
> +;
> +  %notx = xor <2 x i32> %x, <i32 -1, i32 -1>
> +  %noty = xor <2 x i32> %y, <i32 -1, i32 -1>
> +  %cmp = icmp ult <2 x i32> %notx, %noty
> +  %min = select <2 x i1> %cmp, <2 x i32> %notx, <2 x i32> %noty
> +  ret <2 x i32> %min
> +}
> +
> +define <2 x i32> @smin_of_nots(<2 x i32> %x, <2 x i32> %y) {
> +; CHECK-LABEL: @smin_of_nots(
> +; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt <2 x i32> %x, %y
> +; CHECK-NEXT:    [[TMP2:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> %x,
> <2 x i32> %y
> +; CHECK-NEXT:    [[MIN:%.*]] = xor <2 x i32> [[TMP2]], <i32 -1, i32 -1>
> +; CHECK-NEXT:    ret <2 x i32> [[MIN]]
> +;
> +  %notx = xor <2 x i32> %x, <i32 -1, i32 -1>
> +  %noty = xor <2 x i32> %y, <i32 -1, i32 -1>
> +  %cmp = icmp sle <2 x i32> %notx, %noty
> +  %min = select <2 x i1> %cmp, <2 x i32> %notx, <2 x i32> %noty
> +  ret <2 x i32> %min
> +}
> +
>  define i32 @compute_min_2(i32 %x, i32 %y) {
>  ; CHECK-LABEL: @compute_min_2(
>  ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 %x, %y
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://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/20180105/dbff3f92/attachment.html>


More information about the llvm-commits mailing list