[llvm] r287585 - [InstCombine] canonicalize min/max constant to select's false value

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Sat Dec 10 09:55:42 PST 2016


I'm still not sure how to solve this. I think the min/max canonicalization
will enable the existing InstSimplify fold with the same odds that it might
disable it.

It works some times because InstSimplify has potentially expensive
recursive ThreadCmpOverPHI() functionality that doesn't seem to exist in
InstCombine.

The example that Volkan attached can be reduced to something like this:

@g = external global i32

define void @foo() {
bb:
  br label %for

for:
  %phi = phi i32 [ 0, %bb ], [ %min, %else ]
  %cmp = icmp slt i32 %phi, 20    ; This cmp uses the 'min' when we thread
the %min val into here.
  %min = select i1 %cmp, i32 %phi, i32 20
  br i1 %cmp, label %if, label %else

if:
  store volatile i32 %min, i32* @g
  br label %else

else:
  %ld = load volatile i32, i32* @g
  %exitcond = icmp eq i32 %ld, 4
  br i1 %exitcond, label %exit, label %for

exit:
  ret void
}

The original example and this reduction are simplified by SCCP
(Interprocedural Sparse Conditional Constant Propagation). With -O1, the
original example gets folded down to nothing. So there's a trade-off in
whether we want to add a potentially expensive InstCombine for a fold that
is already performed by another pass?



On Tue, Dec 6, 2016 at 3:47 PM, Sanjay Patel <spatel at rotateright.com> wrote:

> I was circling back to this problem thinking this was just a failure of
> InstSimplify (this was the inspiration for https://reviews.llvm.org/rL288
> 833 / https://reviews.llvm.org/rL288841 ).
> But given Eli's observation about InstSimplify's (
> https://reviews.llvm.org/rL288855 ) limitations, I wonder if we should
> just deal with this as an InstCombine problem.
>
> Example:
>
> define i1 @good(i32 %a, i32 %b) {
>   %cmp1 = icmp sgt i32 %a, 20
>   %sel = select i1 %cmp1, i32 20, i32 %a
>   %cmp2 = icmp slt i32 %sel, %a
>   ret i1 %cmp2
> }
>
> define i1 @bad(i32 %a, i32 %b) {
>   %1 = icmp slt i32 %a, 20
>   %sel = select i1 %1, i32 %a, i32 20   <--- this is currently the
> canonical form for min/max
>   %cmp2 = icmp slt i32 %sel, %a
>   ret i1 %cmp2
> }
>
> $ ./opt  -instsimplify minmaxsimp.ll -S
> define i1 @good(i32 %a, i32 %b) {
>   %cmp1 = icmp sgt i32 %a, 20
>   ret i1 %cmp1
> }
>
> define i1 @bad(i32 %a, i32 %b) {
>   %1 = icmp slt i32 %a, 20              <--- can't "simplify" because the
> icmp we want doesn't already exist?
>   %sel = select i1 %1, i32 %a, i32 20
>   %cmp2 = icmp slt i32 %sel, %a
>   ret i1 %cmp2
>
> }
>
> On Thu, Dec 1, 2016 at 2:50 PM, Volkan Keles <vkeles at apple.com> wrote:
>
>> %tmp14 can be exactly 20. The code blocks which tries to simplify
>> comparisons involving max/min in simplifyICmpWithConstant
>> (InstructionSimplify.cpp:2938) sets the variable P to ICMP_SGT. It needs to
>> be ICMP_SGE in order to yield `i1 true`.
>>
>> Volkan
>>
>> On Dec 1, 2016, at 6:50 PM, Sanjay Patel <spatel at rotateright.com> wrote:
>>
>> Hi Volkan,
>>
>> I didn't look at the attachment yet, but let me make sure that I'm
>> understanding the problem.
>> SimplifyCmpInst() can determine that %tmp14 is not greater than 20, but
>> it cannot determine that %tmp14 is less than 20? So either we're missing
>> some analysis or %tmp14 can be exactly 20, and that's throwing off the
>> analysis?
>>
>> On Thu, Dec 1, 2016 at 11:30 AM, Volkan Keles <vkeles at apple.com> wrote:
>>
>>> Hi Sanjay,
>>>
>>> InstCombiner fails to constant fold some of comparisons involving
>>> min/max if we canonicalize min/max with constant. Can you please check the
>>> attached IR?
>>>
>>> We have:
>>> %tmp11 = phi i32 [ 0, %bb ], [ %tmp14, %for.inc.73 ]
>>> %cmp31 = icmp sgt i32 %tmp11, 20
>>> %tmp14 = select i1 %cmp31, i32 20, i32 %tmp11
>>>
>>> Here, it tries to simplify the comparison instruction by checking if
>>> comparing all the incoming values yields the same value.
>>> SimplifyCmpInst(ICMP_SGT, i32 0, i32 20, ...) = i1 false
>>> SimplifyCmpInst(ICMP_SGT, %tmp14, i32 20, …) = i1 false
>>>
>>> If we canonicalize min/max with constant, the instructions will be as
>>> below.
>>> %tmp11 = phi i32 [ 0, %bb ], [ %tmp14, %for.inc.73 ]
>>> %0 = icmp slt i32 %tmp11, 20
>>> %tmp14 = select i1 %0, i32 %tmp11, i32 20
>>>
>>> If we try the same simplification with these instructions, the second
>>> call yields the comparison instruction.
>>> SimplifyCmpInst(ICMP_SLT, i32 0, i32 20, …) = i1 true
>>> SimplifyCmpInst(ICMP_SLT, %tmp14, i32 20, …) = %0 = icmp slt i32 %tmp11,
>>> 20
>>>
>>> Thank you,
>>> Volkan
>>>
>>>
>>>
>>> > On Nov 21, 2016, at 10:04 PM, Sanjay Patel via llvm-commits <
>>> llvm-commits at lists.llvm.org> wrote:
>>> >
>>> > Author: spatel
>>> > Date: Mon Nov 21 16:04:14 2016
>>> > New Revision: 287585
>>> >
>>> > URL: http://llvm.org/viewvc/llvm-project?rev=287585&view=rev
>>> > Log:
>>> > [InstCombine] canonicalize min/max constant to select's false value
>>> >
>>> > This is a first step towards canonicalization and improved
>>> folding/codegen
>>> > for integer min/max as discussed here:
>>> > http://lists.llvm.org/pipermail/llvm-dev/2016-November/106868.html
>>> >
>>> > Here, we're just matching the simplest min/max patterns and adjusting
>>> the
>>> > icmp predicate while swapping the select operands.
>>> >
>>> > I've included FIXME tests in test/Transforms/InstCombine/se
>>> lect_meta.ll
>>> > so it's easier to see how this might be extended (corresponds to the
>>> TODO
>>> > comment in the code). That's also why I'm using matchSelectPattern()
>>> > rather than a simpler check; once the backend is patched, we can just
>>> > remove some of the restrictions to allow the obfuscated min/max
>>> patterns
>>> > in the FIXME tests to be matched.
>>> >
>>> > Differential Revision: https://reviews.llvm.org/D26525
>>> >
>>> > Modified:
>>> >    llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp
>>> >    llvm/trunk/test/Transforms/InstCombine/adjust-for-minmax.ll
>>> >    llvm/trunk/test/Transforms/InstCombine/div-shift.ll
>>> >    llvm/trunk/test/Transforms/InstCombine/minmax-fold.ll
>>> >    llvm/trunk/test/Transforms/InstCombine/pr27236.ll
>>> >    llvm/trunk/test/Transforms/InstCombine/select_meta.ll
>>> >    llvm/trunk/test/Transforms/InstCombine/sext.ll
>>> >
>>> > Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp
>>> > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transform
>>> s/InstCombine/InstCombineSelect.cpp?rev=287585&r1=287584&r2=
>>> 287585&view=diff
>>> > ============================================================
>>> ==================
>>> > --- llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp
>>> (original)
>>> > +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp Mon
>>> Nov 21 16:04:14 2016
>>> > @@ -500,9 +500,51 @@ static bool adjustMinMax(SelectInst &Sel
>>> >   return true;
>>> > }
>>> >
>>> > +/// If this is an integer min/max where the select's 'true' operand
>>> is a
>>> > +/// constant, canonicalize that constant to the 'false' operand:
>>> > +/// select (icmp Pred X, C), C, X --> select (icmp Pred' X, C), X, C
>>> > +static Instruction *
>>> > +canonicalizeMinMaxWithConstant(SelectInst &Sel, ICmpInst &Cmp,
>>> > +                               InstCombiner::BuilderTy &Builder) {
>>> > +  // TODO: We should also canonicalize min/max when the select has a
>>> different
>>> > +  // constant value than the cmp constant, but we need to fix the
>>> backend first.
>>> > +  if (!Cmp.hasOneUse() || !isa<Constant>(Cmp.getOperand(1)) ||
>>> > +      !isa<Constant>(Sel.getTrueValue()) ||
>>> > +      isa<Constant>(Sel.getFalseValue()) ||
>>> > +      Cmp.getOperand(1) != Sel.getTrueValue())
>>> > +    return nullptr;
>>> > +
>>> > +  // Canonicalize the compare predicate based on whether we have min
>>> or max.
>>> > +  Value *LHS, *RHS;
>>> > +  ICmpInst::Predicate NewPred;
>>> > +  SelectPatternResult SPR = matchSelectPattern(&Sel, LHS, RHS);
>>> > +  switch (SPR.Flavor) {
>>> > +  case SPF_SMIN: NewPred = ICmpInst::ICMP_SLT; break;
>>> > +  case SPF_UMIN: NewPred = ICmpInst::ICMP_ULT; break;
>>> > +  case SPF_SMAX: NewPred = ICmpInst::ICMP_SGT; break;
>>> > +  case SPF_UMAX: NewPred = ICmpInst::ICMP_UGT; break;
>>> > +  default: return nullptr;
>>> > +  }
>>> > +
>>> > +  // Canonicalize the constant to the right side.
>>> > +  if (isa<Constant>(LHS))
>>> > +    std::swap(LHS, RHS);
>>> > +
>>> > +  Value *NewCmp = Builder.CreateICmp(NewPred, LHS, RHS);
>>> > +  SelectInst *NewSel = SelectInst::Create(NewCmp, LHS, RHS);
>>> > +  NewSel->copyMetadata(Sel);
>>> > +
>>> > +  // We swapped the select operands, so swap the metadata too.
>>> > +  NewSel->swapProfMetadata();
>>> > +  return NewSel;
>>> > +}
>>> > +
>>> > /// Visit a SelectInst that has an ICmpInst as its first operand.
>>> > Instruction *InstCombiner::foldSelectInstWithICmp(SelectInst &SI,
>>> >                                                   ICmpInst *ICI) {
>>> > +  if (Instruction *NewSel = canonicalizeMinMaxWithConstant(SI, *ICI,
>>> *Builder))
>>> > +    return NewSel;
>>> > +
>>> >   bool Changed = adjustMinMax(SI, *ICI);
>>> >
>>> >   ICmpInst::Predicate Pred = ICI->getPredicate();
>>> >
>>> > Modified: llvm/trunk/test/Transforms/InstCombine/adjust-for-minmax.ll
>>> > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transfor
>>> ms/InstCombine/adjust-for-minmax.ll?rev=287585&r1=287584&r2=
>>> 287585&view=diff
>>> > ============================================================
>>> ==================
>>> > --- llvm/trunk/test/Transforms/InstCombine/adjust-for-minmax.ll
>>> (original)
>>> > +++ llvm/trunk/test/Transforms/InstCombine/adjust-for-minmax.ll Mon
>>> Nov 21 16:04:14 2016
>>> > @@ -29,7 +29,7 @@ define i32 @smin1(i32 %n) {
>>> >   ret i32 %m
>>> > }
>>> >
>>> > -; Canonicalize icmp predicate.
>>> > +; Canonicalize min/max.
>>> >
>>> > define i32 @smax2(i32 %n) {
>>> > ; CHECK-LABEL: @smax2(
>>> > @@ -42,7 +42,7 @@ define i32 @smax2(i32 %n) {
>>> >   ret i32 %m
>>> > }
>>> >
>>> > -; Canonicalize icmp predicate.
>>> > +; Canonicalize min/max.
>>> >
>>> > define i32 @smin2(i32 %n) {
>>> > ; CHECK-LABEL: @smin2(
>>> > @@ -55,12 +55,12 @@ define i32 @smin2(i32 %n) {
>>> >   ret i32 %m
>>> > }
>>> >
>>> > -; Swap signed pred and select ops.
>>> > +; Canonicalize min/max.
>>> >
>>> > define i32 @smax3(i32 %n) {
>>> > ; CHECK-LABEL: @smax3(
>>> > -; CHECK-NEXT:    [[T:%.*]] = icmp slt i32 %n, 0
>>> > -; CHECK-NEXT:    [[M:%.*]] = select i1 [[T]], i32 0, i32 %n
>>> > +; CHECK-NEXT:    [[T:%.*]] = icmp sgt i32 %n, 0
>>> > +; CHECK-NEXT:    [[M:%.*]] = select i1 [[T]], i32 %n, i32 0
>>> > ; CHECK-NEXT:    ret i32 [[M]]
>>> > ;
>>> >   %t = icmp sgt i32 %n, -1
>>> > @@ -68,12 +68,12 @@ define i32 @smax3(i32 %n) {
>>> >   ret i32 %m
>>> > }
>>> >
>>> > -; Swap vector signed pred and select ops.
>>> > +; Canonicalize min/max.
>>> >
>>> > define <2 x i32> @smax3_vec(<2 x i32> %n) {
>>> > ; CHECK-LABEL: @smax3_vec(
>>> > -; CHECK-NEXT:    [[T:%.*]] = icmp slt <2 x i32> %n, zeroinitializer
>>> > -; CHECK-NEXT:    [[M:%.*]] = select <2 x i1> [[T]], <2 x i32>
>>> zeroinitializer, <2 x i32> %n
>>> > +; CHECK-NEXT:    [[T:%.*]] = icmp sgt <2 x i32> %n, zeroinitializer
>>> > +; CHECK-NEXT:    [[M:%.*]] = select <2 x i1> [[T]], <2 x i32> %n, <2
>>> x i32> zeroinitializer
>>> > ; CHECK-NEXT:    ret <2 x i32> [[M]]
>>> > ;
>>> >   %t = icmp sgt <2 x i32> %n, <i32 -1, i32 -1>
>>> > @@ -81,12 +81,12 @@ define <2 x i32> @smax3_vec(<2 x i32> %n
>>> >   ret <2 x i32> %m
>>> > }
>>> >
>>> > -; Swap signed pred and select ops.
>>> > +; Canonicalize min/max.
>>> >
>>> > define i32 @smin3(i32 %n) {
>>> > ; CHECK-LABEL: @smin3(
>>> > -; CHECK-NEXT:    [[T:%.*]] = icmp sgt i32 %n, 0
>>> > -; CHECK-NEXT:    [[M:%.*]] = select i1 [[T]], i32 0, i32 %n
>>> > +; CHECK-NEXT:    [[T:%.*]] = icmp slt i32 %n, 0
>>> > +; CHECK-NEXT:    [[M:%.*]] = select i1 [[T]], i32 %n, i32 0
>>> > ; CHECK-NEXT:    ret i32 [[M]]
>>> > ;
>>> >   %t = icmp slt i32 %n, 1
>>> > @@ -94,12 +94,12 @@ define i32 @smin3(i32 %n) {
>>> >   ret i32 %m
>>> > }
>>> >
>>> > -; Swap vector signed pred and select ops.
>>> > +; Canonicalize min/max.
>>> >
>>> > define <2 x i32> @smin3_vec(<2 x i32> %n) {
>>> > ; CHECK-LABEL: @smin3_vec(
>>> > -; CHECK-NEXT:    [[T:%.*]] = icmp sgt <2 x i32> %n, zeroinitializer
>>> > -; CHECK-NEXT:    [[M:%.*]] = select <2 x i1> [[T]], <2 x i32>
>>> zeroinitializer, <2 x i32> %n
>>> > +; CHECK-NEXT:    [[T:%.*]] = icmp slt <2 x i32> %n, zeroinitializer
>>> > +; CHECK-NEXT:    [[M:%.*]] = select <2 x i1> [[T]], <2 x i32> %n, <2
>>> x i32> zeroinitializer
>>> > ; CHECK-NEXT:    ret <2 x i32> [[M]]
>>> > ;
>>> >   %t = icmp slt <2 x i32> %n, <i32 1, i32 1>
>>> > @@ -107,12 +107,12 @@ define <2 x i32> @smin3_vec(<2 x i32> %n
>>> >   ret <2 x i32> %m
>>> > }
>>> >
>>> > -; Swap unsigned pred and select ops.
>>> > +; Canonicalize min/max.
>>> >
>>> > define i32 @umax3(i32 %n) {
>>> > ; CHECK-LABEL: @umax3(
>>> > -; CHECK-NEXT:    [[T:%.*]] = icmp ult i32 %n, 5
>>> > -; CHECK-NEXT:    [[M:%.*]] = select i1 [[T]], i32 5, i32 %n
>>> > +; CHECK-NEXT:    [[T:%.*]] = icmp ugt i32 %n, 5
>>> > +; CHECK-NEXT:    [[M:%.*]] = select i1 [[T]], i32 %n, i32 5
>>> > ; CHECK-NEXT:    ret i32 [[M]]
>>> > ;
>>> >   %t = icmp ugt i32 %n, 4
>>> > @@ -120,12 +120,12 @@ define i32 @umax3(i32 %n) {
>>> >   ret i32 %m
>>> > }
>>> >
>>> > -; Swap vector unsigned pred and select ops.
>>> > +; Canonicalize min/max.
>>> >
>>> > define <2 x i32> @umax3_vec(<2 x i32> %n) {
>>> > ; CHECK-LABEL: @umax3_vec(
>>> > -; CHECK-NEXT:    [[T:%.*]] = icmp ult <2 x i32> %n, <i32 5, i32 5>
>>> > -; CHECK-NEXT:    [[M:%.*]] = select <2 x i1> [[T]], <2 x i32> <i32 5,
>>> i32 5>, <2 x i32> %n
>>> > +; CHECK-NEXT:    [[T:%.*]] = icmp ugt <2 x i32> %n, <i32 5, i32 5>
>>> > +; CHECK-NEXT:    [[M:%.*]] = select <2 x i1> [[T]], <2 x i32> %n, <2
>>> x i32> <i32 5, i32 5>
>>> > ; CHECK-NEXT:    ret <2 x i32> [[M]]
>>> > ;
>>> >   %t = icmp ugt <2 x i32> %n, <i32 4, i32 4>
>>> > @@ -133,12 +133,12 @@ define <2 x i32> @umax3_vec(<2 x i32> %n
>>> >   ret <2 x i32> %m
>>> > }
>>> >
>>> > -; Swap unsigned pred and select ops.
>>> > +; Canonicalize min/max.
>>> >
>>> > define i32 @umin3(i32 %n) {
>>> > ; CHECK-LABEL: @umin3(
>>> > -; CHECK-NEXT:    [[T:%.*]] = icmp ugt i32 %n, 6
>>> > -; CHECK-NEXT:    [[M:%.*]] = select i1 [[T]], i32 6, i32 %n
>>> > +; CHECK-NEXT:    [[T:%.*]] = icmp ult i32 %n, 6
>>> > +; CHECK-NEXT:    [[M:%.*]] = select i1 [[T]], i32 %n, i32 6
>>> > ; CHECK-NEXT:    ret i32 [[M]]
>>> > ;
>>> >   %t = icmp ult i32 %n, 7
>>> > @@ -146,12 +146,12 @@ define i32 @umin3(i32 %n) {
>>> >   ret i32 %m
>>> > }
>>> >
>>> > -; Swap vector unsigned pred and select ops.
>>> > +; Canonicalize min/max.
>>> >
>>> > define <2 x i32> @umin3_vec(<2 x i32> %n) {
>>> > ; CHECK-LABEL: @umin3_vec(
>>> > -; CHECK-NEXT:    [[T:%.*]] = icmp ugt <2 x i32> %n, <i32 6, i32 6>
>>> > -; CHECK-NEXT:    [[M:%.*]] = select <2 x i1> [[T]], <2 x i32> <i32 6,
>>> i32 6>, <2 x i32> %n
>>> > +; CHECK-NEXT:    [[T:%.*]] = icmp ult <2 x i32> %n, <i32 6, i32 6>
>>> > +; CHECK-NEXT:    [[M:%.*]] = select <2 x i1> [[T]], <2 x i32> %n, <2
>>> x i32> <i32 6, i32 6>
>>> > ; CHECK-NEXT:    ret <2 x i32> [[M]]
>>> > ;
>>> >   %t = icmp ult <2 x i32> %n, <i32 7, i32 7>
>>> > @@ -159,12 +159,12 @@ define <2 x i32> @umin3_vec(<2 x i32> %n
>>> >   ret <2 x i32> %m
>>> > }
>>> >
>>> > -; Canonicalize signed pred and swap pred and select ops.
>>> > +; Canonicalize min/max.
>>> >
>>> > define i32 @smax4(i32 %n) {
>>> > ; CHECK-LABEL: @smax4(
>>> > -; CHECK-NEXT:    [[T:%.*]] = icmp slt i32 %n, 0
>>> > -; CHECK-NEXT:    [[M:%.*]] = select i1 [[T]], i32 0, i32 %n
>>> > +; CHECK-NEXT:    [[T:%.*]] = icmp sgt i32 %n, 0
>>> > +; CHECK-NEXT:    [[M:%.*]] = select i1 [[T]], i32 %n, i32 0
>>> > ; CHECK-NEXT:    ret i32 [[M]]
>>> > ;
>>> >   %t = icmp sge i32 %n, 0
>>> > @@ -172,12 +172,12 @@ define i32 @smax4(i32 %n) {
>>> >   ret i32 %m
>>> > }
>>> >
>>> > -; Canonicalize vector signed pred and swap pred and select ops.
>>> > +; Canonicalize min/max.
>>> >
>>> > define <2 x i32> @smax4_vec(<2 x i32> %n) {
>>> > ; CHECK-LABEL: @smax4_vec(
>>> > -; CHECK-NEXT:    [[T:%.*]] = icmp slt <2 x i32> %n, zeroinitializer
>>> > -; CHECK-NEXT:    [[M:%.*]] = select <2 x i1> [[T]], <2 x i32>
>>> zeroinitializer, <2 x i32> %n
>>> > +; CHECK-NEXT:    [[T:%.*]] = icmp sgt <2 x i32> %n, zeroinitializer
>>> > +; CHECK-NEXT:    [[M:%.*]] = select <2 x i1> [[T]], <2 x i32> %n, <2
>>> x i32> zeroinitializer
>>> > ; CHECK-NEXT:    ret <2 x i32> [[M]]
>>> > ;
>>> >   %t = icmp sge <2 x i32> %n, zeroinitializer
>>> > @@ -185,12 +185,12 @@ define <2 x i32> @smax4_vec(<2 x i32> %n
>>> >   ret <2 x i32> %m
>>> > }
>>> >
>>> > -; Canonicalize signed pred and swap pred and select ops.
>>> > +; Canonicalize min/max.
>>> >
>>> > define i32 @smin4(i32 %n) {
>>> > ; CHECK-LABEL: @smin4(
>>> > -; CHECK-NEXT:    [[T:%.*]] = icmp sgt i32 %n, 0
>>> > -; CHECK-NEXT:    [[M:%.*]] = select i1 [[T]], i32 0, i32 %n
>>> > +; CHECK-NEXT:    [[T:%.*]] = icmp slt i32 %n, 0
>>> > +; CHECK-NEXT:    [[M:%.*]] = select i1 [[T]], i32 %n, i32 0
>>> > ; CHECK-NEXT:    ret i32 [[M]]
>>> > ;
>>> >   %t = icmp sle i32 %n, 0
>>> > @@ -198,12 +198,12 @@ define i32 @smin4(i32 %n) {
>>> >   ret i32 %m
>>> > }
>>> >
>>> > -; Canonicalize vector signed pred and swap pred and select ops.
>>> > +; Canonicalize min/max.
>>> >
>>> > define <2 x i32> @smin4_vec(<2 x i32> %n) {
>>> > ; CHECK-LABEL: @smin4_vec(
>>> > -; CHECK-NEXT:    [[T:%.*]] = icmp sgt <2 x i32> %n, zeroinitializer
>>> > -; CHECK-NEXT:    [[M:%.*]] = select <2 x i1> [[T]], <2 x i32>
>>> zeroinitializer, <2 x i32> %n
>>> > +; CHECK-NEXT:    [[T:%.*]] = icmp slt <2 x i32> %n, zeroinitializer
>>> > +; CHECK-NEXT:    [[M:%.*]] = select <2 x i1> [[T]], <2 x i32> %n, <2
>>> x i32> zeroinitializer
>>> > ; CHECK-NEXT:    ret <2 x i32> [[M]]
>>> > ;
>>> >   %t = icmp sle <2 x i32> %n, zeroinitializer
>>> > @@ -211,12 +211,12 @@ define <2 x i32> @smin4_vec(<2 x i32> %n
>>> >   ret <2 x i32> %m
>>> > }
>>> >
>>> > -; Canonicalize unsigned pred and swap pred and select ops.
>>> > +; Canonicalize min/max.
>>> >
>>> > define i32 @umax4(i32 %n) {
>>> > ; CHECK-LABEL: @umax4(
>>> > -; CHECK-NEXT:    [[T:%.*]] = icmp ult i32 %n, 8
>>> > -; CHECK-NEXT:    [[M:%.*]] = select i1 [[T]], i32 8, i32 %n
>>> > +; CHECK-NEXT:    [[T:%.*]] = icmp ugt i32 %n, 8
>>> > +; CHECK-NEXT:    [[M:%.*]] = select i1 [[T]], i32 %n, i32 8
>>> > ; CHECK-NEXT:    ret i32 [[M]]
>>> > ;
>>> >   %t = icmp uge i32 %n, 8
>>> > @@ -224,12 +224,12 @@ define i32 @umax4(i32 %n) {
>>> >   ret i32 %m
>>> > }
>>> >
>>> > -; Canonicalize vector unsigned pred and swap pred and select ops.
>>> > +; Canonicalize min/max.
>>> >
>>> > define <2 x i32> @umax4_vec(<2 x i32> %n) {
>>> > ; CHECK-LABEL: @umax4_vec(
>>> > -; CHECK-NEXT:    [[T:%.*]] = icmp ult <2 x i32> %n, <i32 8, i32 8>
>>> > -; CHECK-NEXT:    [[M:%.*]] = select <2 x i1> [[T]], <2 x i32> <i32 8,
>>> i32 8>, <2 x i32> %n
>>> > +; CHECK-NEXT:    [[T:%.*]] = icmp ugt <2 x i32> %n, <i32 8, i32 8>
>>> > +; CHECK-NEXT:    [[M:%.*]] = select <2 x i1> [[T]], <2 x i32> %n, <2
>>> x i32> <i32 8, i32 8>
>>> > ; CHECK-NEXT:    ret <2 x i32> [[M]]
>>> > ;
>>> >   %t = icmp uge <2 x i32> %n, <i32 8, i32 8>
>>> > @@ -237,12 +237,12 @@ define <2 x i32> @umax4_vec(<2 x i32> %n
>>> >   ret <2 x i32> %m
>>> > }
>>> >
>>> > -; Canonicalize unsigned pred and swap pred and select ops.
>>> > +; Canonicalize min/max.
>>> >
>>> > define i32 @umin4(i32 %n) {
>>> > ; CHECK-LABEL: @umin4(
>>> > -; CHECK-NEXT:    [[T:%.*]] = icmp ugt i32 %n, 9
>>> > -; CHECK-NEXT:    [[M:%.*]] = select i1 [[T]], i32 9, i32 %n
>>> > +; CHECK-NEXT:    [[T:%.*]] = icmp ult i32 %n, 9
>>> > +; CHECK-NEXT:    [[M:%.*]] = select i1 [[T]], i32 %n, i32 9
>>> > ; CHECK-NEXT:    ret i32 [[M]]
>>> > ;
>>> >   %t = icmp ule i32 %n, 9
>>> > @@ -250,12 +250,12 @@ define i32 @umin4(i32 %n) {
>>> >   ret i32 %m
>>> > }
>>> >
>>> > -; Canonicalize vector unsigned pred and swap pred and select ops.
>>> > +; Canonicalize min/max.
>>> >
>>> > define <2 x i32> @umin4_vec(<2 x i32> %n) {
>>> > ; CHECK-LABEL: @umin4_vec(
>>> > -; CHECK-NEXT:    [[T:%.*]] = icmp ugt <2 x i32> %n, <i32 9, i32 9>
>>> > -; CHECK-NEXT:    [[M:%.*]] = select <2 x i1> [[T]], <2 x i32> <i32 9,
>>> i32 9>, <2 x i32> %n
>>> > +; CHECK-NEXT:    [[T:%.*]] = icmp ult <2 x i32> %n, <i32 9, i32 9>
>>> > +; CHECK-NEXT:    [[M:%.*]] = select <2 x i1> [[T]], <2 x i32> %n, <2
>>> x i32> <i32 9, i32 9>
>>> > ; CHECK-NEXT:    ret <2 x i32> [[M]]
>>> > ;
>>> >   %t = icmp ule <2 x i32> %n, <i32 9, i32 9>
>>> > @@ -266,8 +266,8 @@ define <2 x i32> @umin4_vec(<2 x i32> %n
>>> > define i64 @smax_sext(i32 %a) {
>>> > ; CHECK-LABEL: @smax_sext(
>>> > ; CHECK-NEXT:    [[A_EXT:%.*]] = sext i32 %a to i64
>>> > -; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i64 [[A_EXT]], 0
>>> > -; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[CMP]], i64 0, i64 [[A_EXT]]
>>> > +; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i64 [[A_EXT]], 0
>>> > +; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[CMP]], i64 [[A_EXT]], i64 0
>>> > ; CHECK-NEXT:    ret i64 [[MAX]]
>>> > ;
>>> >   %a_ext = sext i32 %a to i64
>>> > @@ -279,8 +279,8 @@ define i64 @smax_sext(i32 %a) {
>>> > define <2 x i64> @smax_sext_vec(<2 x i32> %a) {
>>> > ; CHECK-LABEL: @smax_sext_vec(
>>> > ; CHECK-NEXT:    [[A_EXT:%.*]] = sext <2 x i32> %a to <2 x i64>
>>> > -; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i64> [[A_EXT]],
>>> zeroinitializer
>>> > -; CHECK-NEXT:    [[MAX:%.*]] = select <2 x i1> [[CMP]], <2 x i64>
>>> zeroinitializer, <2 x i64> [[A_EXT]]
>>> > +; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt <2 x i64> [[A_EXT]],
>>> zeroinitializer
>>> > +; CHECK-NEXT:    [[MAX:%.*]] = select <2 x i1> [[CMP]], <2 x i64>
>>> [[A_EXT]], <2 x i64> zeroinitializer
>>> > ; CHECK-NEXT:    ret <2 x i64> [[MAX]]
>>> > ;
>>> >   %a_ext = sext <2 x i32> %a to <2 x i64>
>>> > @@ -292,8 +292,8 @@ define <2 x i64> @smax_sext_vec(<2 x i32
>>> > define i64 @smin_sext(i32 %a) {
>>> > ; CHECK-LABEL: @smin_sext(
>>> > ; CHECK-NEXT:    [[A_EXT:%.*]] = sext i32 %a to i64
>>> > -; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i64 [[A_EXT]], 0
>>> > -; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[CMP]], i64 0, i64 [[A_EXT]]
>>> > +; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i64 [[A_EXT]], 0
>>> > +; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[CMP]], i64 [[A_EXT]], i64 0
>>> > ; CHECK-NEXT:    ret i64 [[MIN]]
>>> > ;
>>> >   %a_ext = sext i32 %a to i64
>>> > @@ -305,8 +305,8 @@ define i64 @smin_sext(i32 %a) {
>>> > define <2 x i64>@smin_sext_vec(<2 x i32> %a) {
>>> > ; CHECK-LABEL: @smin_sext_vec(
>>> > ; CHECK-NEXT:    [[A_EXT:%.*]] = sext <2 x i32> %a to <2 x i64>
>>> > -; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt <2 x i64> [[A_EXT]],
>>> zeroinitializer
>>> > -; CHECK-NEXT:    [[MIN:%.*]] = select <2 x i1> [[CMP]], <2 x i64>
>>> zeroinitializer, <2 x i64> [[A_EXT]]
>>> > +; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i64> [[A_EXT]],
>>> zeroinitializer
>>> > +; CHECK-NEXT:    [[MIN:%.*]] = select <2 x i1> [[CMP]], <2 x i64>
>>> [[A_EXT]], <2 x i64> zeroinitializer
>>> > ; CHECK-NEXT:    ret <2 x i64> [[MIN]]
>>> > ;
>>> >   %a_ext = sext <2 x i32> %a to <2 x i64>
>>> > @@ -318,8 +318,8 @@ define <2 x i64>@smin_sext_vec(<2 x i32>
>>> > define i64 @umax_sext(i32 %a) {
>>> > ; CHECK-LABEL: @umax_sext(
>>> > ; CHECK-NEXT:    [[A_EXT:%.*]] = sext i32 %a to i64
>>> > -; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[A_EXT]], 3
>>> > -; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[CMP]], i64 3, i64 [[A_EXT]]
>>> > +; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[A_EXT]], 3
>>> > +; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[CMP]], i64 [[A_EXT]], i64 3
>>> > ; CHECK-NEXT:    ret i64 [[MAX]]
>>> > ;
>>> >   %a_ext = sext i32 %a to i64
>>> > @@ -331,8 +331,8 @@ define i64 @umax_sext(i32 %a) {
>>> > define <2 x i64> @umax_sext_vec(<2 x i32> %a) {
>>> > ; CHECK-LABEL: @umax_sext_vec(
>>> > ; CHECK-NEXT:    [[A_EXT:%.*]] = sext <2 x i32> %a to <2 x i64>
>>> > -; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i64> [[A_EXT]], <i64 3,
>>> i64 3>
>>> > -; CHECK-NEXT:    [[MAX:%.*]] = select <2 x i1> [[CMP]], <2 x i64>
>>> <i64 3, i64 3>, <2 x i64> [[A_EXT]]
>>> > +; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i64> [[A_EXT]], <i64 3,
>>> i64 3>
>>> > +; CHECK-NEXT:    [[MAX:%.*]] = select <2 x i1> [[CMP]], <2 x i64>
>>> [[A_EXT]], <2 x i64> <i64 3, i64 3>
>>> > ; CHECK-NEXT:    ret <2 x i64> [[MAX]]
>>> > ;
>>> >   %a_ext = sext <2 x i32> %a to <2 x i64>
>>> > @@ -344,8 +344,8 @@ define <2 x i64> @umax_sext_vec(<2 x i32
>>> > define i64 @umin_sext(i32 %a) {
>>> > ; CHECK-LABEL: @umin_sext(
>>> > ; CHECK-NEXT:    [[A_EXT:%.*]] = sext i32 %a to i64
>>> > -; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[A_EXT]], 2
>>> > -; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[CMP]], i64 2, i64 [[A_EXT]]
>>> > +; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[A_EXT]], 2
>>> > +; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[CMP]], i64 [[A_EXT]], i64 2
>>> > ; CHECK-NEXT:    ret i64 [[MIN]]
>>> > ;
>>> >   %a_ext = sext i32 %a to i64
>>> > @@ -357,8 +357,8 @@ define i64 @umin_sext(i32 %a) {
>>> > define <2 x i64> @umin_sext_vec(<2 x i32> %a) {
>>> > ; CHECK-LABEL: @umin_sext_vec(
>>> > ; CHECK-NEXT:    [[A_EXT:%.*]] = sext <2 x i32> %a to <2 x i64>
>>> > -; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i64> [[A_EXT]], <i64 2,
>>> i64 2>
>>> > -; CHECK-NEXT:    [[MIN:%.*]] = select <2 x i1> [[CMP]], <2 x i64>
>>> <i64 2, i64 2>, <2 x i64> [[A_EXT]]
>>> > +; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i64> [[A_EXT]], <i64 2,
>>> i64 2>
>>> > +; CHECK-NEXT:    [[MIN:%.*]] = select <2 x i1> [[CMP]], <2 x i64>
>>> [[A_EXT]], <2 x i64> <i64 2, i64 2>
>>> > ; CHECK-NEXT:    ret <2 x i64> [[MIN]]
>>> > ;
>>> >   %a_ext = sext <2 x i32> %a to <2 x i64>
>>> > @@ -422,8 +422,8 @@ define <2 x i64> @umin_sext2_vec(<2 x i3
>>> > define i64 @umax_zext(i32 %a) {
>>> > ; CHECK-LABEL: @umax_zext(
>>> > ; CHECK-NEXT:    [[A_EXT:%.*]] = zext i32 %a to i64
>>> > -; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[A_EXT]], 3
>>> > -; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[CMP]], i64 3, i64 [[A_EXT]]
>>> > +; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[A_EXT]], 3
>>> > +; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[CMP]], i64 [[A_EXT]], i64 3
>>> > ; CHECK-NEXT:    ret i64 [[MAX]]
>>> > ;
>>> >   %a_ext = zext i32 %a to i64
>>> > @@ -435,8 +435,8 @@ define i64 @umax_zext(i32 %a) {
>>> > define <2 x i64> @umax_zext_vec(<2 x i32> %a) {
>>> > ; CHECK-LABEL: @umax_zext_vec(
>>> > ; CHECK-NEXT:    [[A_EXT:%.*]] = zext <2 x i32> %a to <2 x i64>
>>> > -; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i64> [[A_EXT]], <i64 3,
>>> i64 3>
>>> > -; CHECK-NEXT:    [[MAX:%.*]] = select <2 x i1> [[CMP]], <2 x i64>
>>> <i64 3, i64 3>, <2 x i64> [[A_EXT]]
>>> > +; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i64> [[A_EXT]], <i64 3,
>>> i64 3>
>>> > +; CHECK-NEXT:    [[MAX:%.*]] = select <2 x i1> [[CMP]], <2 x i64>
>>> [[A_EXT]], <2 x i64> <i64 3, i64 3>
>>> > ; CHECK-NEXT:    ret <2 x i64> [[MAX]]
>>> > ;
>>> >   %a_ext = zext <2 x i32> %a to <2 x i64>
>>> > @@ -448,8 +448,8 @@ define <2 x i64> @umax_zext_vec(<2 x i32
>>> > define i64 @umin_zext(i32 %a) {
>>> > ; CHECK-LABEL: @umin_zext(
>>> > ; CHECK-NEXT:    [[A_EXT:%.*]] = zext i32 %a to i64
>>> > -; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i64 [[A_EXT]], 2
>>> > -; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[CMP]], i64 2, i64 [[A_EXT]]
>>> > +; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[A_EXT]], 2
>>> > +; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[CMP]], i64 [[A_EXT]], i64 2
>>> > ; CHECK-NEXT:    ret i64 [[MIN]]
>>> > ;
>>> >   %a_ext = zext i32 %a to i64
>>> > @@ -461,8 +461,8 @@ define i64 @umin_zext(i32 %a) {
>>> > define <2 x i64> @umin_zext_vec(<2 x i32> %a) {
>>> > ; CHECK-LABEL: @umin_zext_vec(
>>> > ; CHECK-NEXT:    [[A_EXT:%.*]] = zext <2 x i32> %a to <2 x i64>
>>> > -; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i64> [[A_EXT]], <i64 2,
>>> i64 2>
>>> > -; CHECK-NEXT:    [[MIN:%.*]] = select <2 x i1> [[CMP]], <2 x i64>
>>> <i64 2, i64 2>, <2 x i64> [[A_EXT]]
>>> > +; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i64> [[A_EXT]], <i64 2,
>>> i64 2>
>>> > +; CHECK-NEXT:    [[MIN:%.*]] = select <2 x i1> [[CMP]], <2 x i64>
>>> [[A_EXT]], <2 x i64> <i64 2, i64 2>
>>> > ; CHECK-NEXT:    ret <2 x i64> [[MIN]]
>>> > ;
>>> >   %a_ext = zext <2 x i32> %a to <2 x i64>
>>> >
>>> > Modified: llvm/trunk/test/Transforms/InstCombine/div-shift.ll
>>> > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transfor
>>> ms/InstCombine/div-shift.ll?rev=287585&r1=287584&r2=287585&view=diff
>>> > ============================================================
>>> ==================
>>> > --- llvm/trunk/test/Transforms/InstCombine/div-shift.ll (original)
>>> > +++ llvm/trunk/test/Transforms/InstCombine/div-shift.ll Mon Nov 21
>>> 16:04:14 2016
>>> > @@ -45,8 +45,8 @@ define i64 @t3(i64 %x, i32 %y) {
>>> >
>>> > define i32 @t4(i32 %x, i32 %y) {
>>> > ; CHECK-LABEL: @t4(
>>> > -; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 %y, 5
>>> > -; CHECK-NEXT:    [[DOTV:%.*]] = select i1 [[TMP1]], i32 5, i32 %y
>>> > +; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 %y, 5
>>> > +; CHECK-NEXT:    [[DOTV:%.*]] = select i1 [[TMP1]], i32 %y, i32 5
>>> > ; CHECK-NEXT:    [[TMP2:%.*]] = lshr i32 %x, [[DOTV]]
>>> > ; CHECK-NEXT:    ret i32 [[TMP2]]
>>> > ;
>>> >
>>> > Modified: llvm/trunk/test/Transforms/InstCombine/minmax-fold.ll
>>> > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transfor
>>> ms/InstCombine/minmax-fold.ll?rev=287585&r1=287584&r2=287585&view=diff
>>> > ============================================================
>>> ==================
>>> > --- llvm/trunk/test/Transforms/InstCombine/minmax-fold.ll (original)
>>> > +++ llvm/trunk/test/Transforms/InstCombine/minmax-fold.ll Mon Nov 21
>>> 16:04:14 2016
>>> > @@ -200,8 +200,8 @@ define <4 x float> @bitcasts_icmp(<2 x i
>>> > ; SMIN(SMIN(X, 11), 92) -> SMIN(X, 11)
>>> > define i32 @test68(i32 %x) {
>>> > ; CHECK-LABEL: @test68(
>>> > -; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 %x, 11
>>> > -; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 11, i32 %x
>>> > +; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 %x, 11
>>> > +; CHECK-NEXT:    [[COND:%.*]] = select i1 [[TMP1]], i32 %x, i32 11
>>> > ; CHECK-NEXT:    ret i32 [[COND]]
>>> > ;
>>> >   %cmp = icmp slt i32 11, %x
>>> > @@ -213,8 +213,8 @@ define i32 @test68(i32 %x) {
>>> >
>>> > define <2 x i32> @test68vec(<2 x i32> %x) {
>>> > ; CHECK-LABEL: @test68vec(
>>> > -; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt <2 x i32> %x, <i32 11, i32 11>
>>> > -; CHECK-NEXT:    [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32>
>>> <i32 11, i32 11>, <2 x i32> %x
>>> > +; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt <2 x i32> %x, <i32 11, i32
>>> 11>
>>> > +; CHECK-NEXT:    [[COND:%.*]] = select <2 x i1> [[TMP1]], <2 x i32>
>>> %x, <2 x i32> <i32 11, i32 11>
>>> > ; CHECK-NEXT:    ret <2 x i32> [[COND]]
>>> > ;
>>> >   %cmp = icmp slt <2 x i32> <i32 11, i32 11>, %x
>>> > @@ -227,8 +227,8 @@ define <2 x i32> @test68vec(<2 x i32> %x
>>> > ; MIN(MIN(X, 24), 83) -> MIN(X, 24)
>>> > define i32 @test69(i32 %x) {
>>> > ; CHECK-LABEL: @test69(
>>> > -; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 %x, 24
>>> > -; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 24, i32 %x
>>> > +; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 %x, 24
>>> > +; CHECK-NEXT:    [[COND:%.*]] = select i1 [[TMP1]], i32 %x, i32 24
>>> > ; CHECK-NEXT:    ret i32 [[COND]]
>>> > ;
>>> >   %cmp = icmp ult i32 24, %x
>>> > @@ -241,8 +241,8 @@ define i32 @test69(i32 %x) {
>>> > ; SMAX(SMAX(X, 75), 36) -> SMAX(X, 75)
>>> > define i32 @test70(i32 %x) {
>>> > ; CHECK-LABEL: @test70(
>>> > -; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 %x, 75
>>> > -; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 75, i32 %x
>>> > +; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 %x, 75
>>> > +; CHECK-NEXT:    [[COND:%.*]] = select i1 [[TMP1]], i32 %x, i32 75
>>> > ; CHECK-NEXT:    ret i32 [[COND]]
>>> > ;
>>> >   %cmp = icmp slt i32 %x, 75
>>> > @@ -255,8 +255,8 @@ define i32 @test70(i32 %x) {
>>> > ; MAX(MAX(X, 68), 47) -> MAX(X, 68)
>>> > define i32 @test71(i32 %x) {
>>> > ; CHECK-LABEL: @test71(
>>> > -; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 %x, 68
>>> > -; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 68, i32 %x
>>> > +; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 %x, 68
>>> > +; CHECK-NEXT:    [[COND:%.*]] = select i1 [[TMP1]], i32 %x, i32 68
>>> > ; CHECK-NEXT:    ret i32 [[COND]]
>>> > ;
>>> >   %cmp = icmp ult i32 %x, 68
>>> > @@ -269,8 +269,8 @@ define i32 @test71(i32 %x) {
>>> > ; SMIN(SMIN(X, 92), 11) -> SMIN(X, 11)
>>> > define i32 @test72(i32 %x) {
>>> > ; CHECK-LABEL: @test72(
>>> > -; CHECK-NEXT:    [[CMP31:%.*]] = icmp sgt i32 %x, 11
>>> > -; CHECK-NEXT:    [[RETVAL:%.*]] = select i1 [[CMP31]], i32 11, i32 %x
>>> > +; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 %x, 11
>>> > +; CHECK-NEXT:    [[RETVAL:%.*]] = select i1 [[TMP1]], i32 %x, i32 11
>>> > ; CHECK-NEXT:    ret i32 [[RETVAL]]
>>> > ;
>>> >   %cmp = icmp sgt i32 %x, 92
>>> > @@ -280,14 +280,14 @@ define i32 @test72(i32 %x) {
>>> >   ret i32 %retval
>>> > }
>>> >
>>> > -; FIXME - vector neglect: FoldOrOfICmps()
>>> > +; FIXME - vector neglect: FoldAndOfICmps() / FoldOrOfICmps()
>>> >
>>> > define <2 x i32> @test72vec(<2 x i32> %x) {
>>> > ; CHECK-LABEL: @test72vec(
>>> > -; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt <2 x i32> %x, <i32 92, i32 92>
>>> > -; CHECK-NEXT:    [[CMP31:%.*]] = icmp sgt <2 x i32> %x, <i32 11, i32
>>> 11>
>>> > -; CHECK-NEXT:    [[CMP3:%.*]] = or <2 x i1> [[CMP]], [[CMP31:%.*]]
>>> > -; CHECK-NEXT:    [[RETVAL:%.*]] = select <2 x i1> [[CMP3]], <2 x i32>
>>> <i32 11, i32 11>, <2 x i32> %x
>>> > +; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt <2 x i32> %x, <i32 92, i32
>>> 92>
>>> > +; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt <2 x i32> %x, <i32 11, i32
>>> 11>
>>> > +; CHECK-NEXT:    [[TMP3:%.*]] = and <2 x i1> [[TMP1]], [[TMP2]]
>>> > +; CHECK-NEXT:    [[RETVAL:%.*]] = select <2 x i1> [[TMP3]], <2 x i32>
>>> %x, <2 x i32> <i32 11, i32 11>
>>> > ; CHECK-NEXT:    ret <2 x i32> [[RETVAL]]
>>> > ;
>>> >   %cmp = icmp sgt <2 x i32> %x, <i32 92, i32 92>
>>> > @@ -300,8 +300,8 @@ define <2 x i32> @test72vec(<2 x i32> %x
>>> > ; MIN(MIN(X, 83), 24) -> MIN(X, 24)
>>> > define i32 @test73(i32 %x) {
>>> > ; CHECK-LABEL: @test73(
>>> > -; CHECK-NEXT:    [[CMP31:%.*]] = icmp ugt i32 %x, 24
>>> > -; CHECK-NEXT:    [[RETVAL:%.*]] = select i1 [[CMP31]], i32 24, i32 %x
>>> > +; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 %x, 24
>>> > +; CHECK-NEXT:    [[RETVAL:%.*]] = select i1 [[TMP1]], i32 %x, i32 24
>>> > ; CHECK-NEXT:    ret i32 [[RETVAL]]
>>> > ;
>>> >   %cmp = icmp ugt i32 %x, 83
>>> > @@ -314,8 +314,8 @@ define i32 @test73(i32 %x) {
>>> > ; SMAX(SMAX(X, 36), 75) -> SMAX(X, 75)
>>> > define i32 @test74(i32 %x) {
>>> > ; CHECK-LABEL: @test74(
>>> > -; CHECK-NEXT:    [[CMP31:%.*]] = icmp slt i32 %x, 75
>>> > -; CHECK-NEXT:    [[RETVAL:%.*]] = select i1 [[CMP31]], i32 75, i32 %x
>>> > +; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 %x, 75
>>> > +; CHECK-NEXT:    [[RETVAL:%.*]] = select i1 [[TMP1]], i32 %x, i32 75
>>> > ; CHECK-NEXT:    ret i32 [[RETVAL]]
>>> > ;
>>> >   %cmp = icmp slt i32 %x, 36
>>> > @@ -328,8 +328,8 @@ define i32 @test74(i32 %x) {
>>> > ; MAX(MAX(X, 47), 68) -> MAX(X, 68)
>>> > define i32 @test75(i32 %x) {
>>> > ; CHECK-LABEL: @test75(
>>> > -; CHECK-NEXT:    [[CMP31:%.*]] = icmp ult i32 %x, 68
>>> > -; CHECK-NEXT:    [[RETVAL:%.*]] = select i1 [[CMP31]], i32 68, i32 %x
>>> > +; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 %x, 68
>>> > +; CHECK-NEXT:    [[RETVAL:%.*]] = select i1 [[TMP1]], i32 %x, i32 68
>>> > ; CHECK-NEXT:    ret i32 [[RETVAL]]
>>> > ;
>>> >   %cmp = icmp ult i32 %x, 47
>>> >
>>> > Modified: llvm/trunk/test/Transforms/InstCombine/pr27236.ll
>>> > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transfor
>>> ms/InstCombine/pr27236.ll?rev=287585&r1=287584&r2=287585&view=diff
>>> > ============================================================
>>> ==================
>>> > --- llvm/trunk/test/Transforms/InstCombine/pr27236.ll (original)
>>> > +++ llvm/trunk/test/Transforms/InstCombine/pr27236.ll Mon Nov 21
>>> 16:04:14 2016
>>> > @@ -3,8 +3,8 @@
>>> >
>>> > define float @test1(i32 %scale) {
>>> > ; CHECK-LABEL: @test1(
>>> > -; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 %scale, 1
>>> > -; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 1, i32 %scale
>>> > +; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 %scale, 1
>>> > +; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 %scale, i32 1
>>> > ; CHECK-NEXT:    [[TMP3:%.*]] = sitofp i32 [[TMP2]] to float
>>> > ; CHECK-NEXT:    [[TMP4:%.*]] = icmp sgt i32 [[TMP2]], 0
>>> > ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[TMP4]], float [[TMP3]],
>>> float 0.000000e+00
>>> >
>>> > Modified: llvm/trunk/test/Transforms/InstCombine/select_meta.ll
>>> > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transfor
>>> ms/InstCombine/select_meta.ll?rev=287585&r1=287584&r2=287585&view=diff
>>> > ============================================================
>>> ==================
>>> > --- llvm/trunk/test/Transforms/InstCombine/select_meta.ll (original)
>>> > +++ llvm/trunk/test/Transforms/InstCombine/select_meta.ll Mon Nov 21
>>> 16:04:14 2016
>>> > @@ -1,4 +1,6 @@
>>> > -; NOTE: Assertions have been autogenerated by
>>> utils/update_test_checks.py and enhanced to include metadata checking.
>>> > +; NOTE: Assertions have been autogenerated by
>>> utils/update_test_checks.py
>>> > +; and enhanced to include metadata checking.
>>> > +
>>> > ; RUN: opt < %s -instcombine -S | FileCheck %s
>>> >
>>> > define i32 @foo(i32) local_unnamed_addr #0  {
>>> > @@ -51,12 +53,11 @@ define i32 @foo2(i32, i32) local_unnamed
>>> >   ret i32 %6
>>> > }
>>> >
>>> > -; condition swapped
>>> > define i64 @test43(i32 %a) nounwind {
>>> > ; CHECK-LABEL: @test43(
>>> > ; CHECK-NEXT:    [[A_EXT:%.*]] = sext i32 %a to i64
>>> > -; CHECK-NEXT:    [[IS_A_NONNEGATIVE:%.*]] = icmp slt i64 [[A_EXT]], 0
>>> > -; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[IS_A_NONNEGATIVE]], i64 0,
>>> i64 [[A_EXT]], !prof ![[MD3:[0-9]+]]
>>> > +; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i64 [[A_EXT]], 0
>>> > +; CHECK-NEXT:    [[MAX:%.*]] = select i1 [[TMP1]], i64 [[A_EXT]], i64
>>> 0, !prof ![[MD1]]
>>> > ; CHECK-NEXT:    ret i64 [[MAX]]
>>> > ;
>>> >   %a_ext = sext i32 %a to i64
>>> > @@ -136,10 +137,12 @@ define i32 @test30(i32 %x, i32 %y) {
>>> >   ret i32 %retval
>>> > }
>>> >
>>> > +; Swap predicate / metadata order
>>> > +; SMAX(SMAX(X, 75), 36) -> SMAX(X, 75)
>>> > define i32 @test70(i32 %x) {
>>> > ; CHECK-LABEL: @test70(
>>> > -; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 %x, 75
>>> > -; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 75, i32 %x,
>>> !prof ![[MD1]]
>>> > +; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 %x, 75
>>> > +; CHECK-NEXT:    [[COND:%.*]] = select i1 [[TMP1]], i32 %x, i32 75,
>>> !prof ![[MD3:[0-9]+]]
>>> > ; CHECK-NEXT:    ret i32 [[COND]]
>>> > ;
>>> >   %cmp = icmp slt i32 %x, 75
>>> > @@ -149,12 +152,12 @@ define i32 @test70(i32 %x) {
>>> >   ret i32 %retval
>>> > }
>>> >
>>> > -
>>> > +; Swap predicate / metadata order
>>> > ; SMIN(SMIN(X, 92), 11) -> SMIN(X, 11)
>>> > define i32 @test72(i32 %x) {
>>> > ; CHECK-LABEL: @test72(
>>> > -; CHECK-NEXT:    [[CMP31:%.*]] = icmp sgt i32 %x, 11
>>> > -; CHECK-NEXT:    [[RETVAL:%.*]] = select i1 [[CMP31]], i32 11, i32
>>> %x, !prof ![[MD2:[0-9]+]]
>>> > +; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 %x, 11
>>> > +; CHECK-NEXT:    [[RETVAL:%.*]] = select i1 [[TMP1]], i32 %x, i32 11,
>>> !prof ![[MD4:[0-9]+]]
>>> > ; CHECK-NEXT:    ret i32 [[RETVAL]]
>>> > ;
>>> >   %cmp = icmp sgt i32 %x, 92
>>> > @@ -164,11 +167,12 @@ define i32 @test72(i32 %x) {
>>> >   ret i32 %retval
>>> > }
>>> >
>>> > +; Swap predicate / metadata order
>>> > ; SMAX(SMAX(X, 36), 75) -> SMAX(X, 75)
>>> > define i32 @test74(i32 %x) {
>>> > ; CHECK-LABEL: @test74(
>>> > -; CHECK-NEXT:    [[CMP31:%.*]] = icmp slt i32 %x, 75
>>> > -; CHECK-NEXT:    [[RETVAL:%.*]] = select i1 [[CMP31]], i32 75, i32
>>> %x, !prof ![[MD2]]
>>> > +; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 %x, 75
>>> > +; CHECK-NEXT:    [[RETVAL:%.*]] = select i1 [[TMP1]], i32 %x, i32 75,
>>> !prof ![[MD4]]
>>> > ; CHECK-NEXT:    ret i32 [[RETVAL]]
>>> > ;
>>> >   %cmp = icmp slt i32 %x, 36
>>> > @@ -178,10 +182,122 @@ define i32 @test74(i32 %x) {
>>> >   ret i32 %retval
>>> > }
>>> >
>>> > +; FIXME:
>>> > +; The compare should change, but the metadata remains the same
>>> because the select operands are not swapped.
>>> > +define i32 @smin1(i32 %x) {
>>> > +; CHECK-LABEL: @smin1(
>>> > +; CHECK-NEXT:    [[NOT_X:%.*]] = xor i32 %x, -1
>>> > +; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 %x, 0
>>> > +; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 [[NOT_X]], i32
>>> -1, !prof ![[MD1]]
>>> > +; CHECK-NEXT:    ret i32 [[SEL]]
>>> > +;
>>> > +  %not_x = xor i32 %x, -1
>>> > +  %cmp = icmp sgt i32 %x, 0
>>> > +  %sel = select i1 %cmp, i32 %not_x, i32 -1, !prof !1
>>> > +  ret i32 %sel
>>> > +}
>>> > +
>>> > +; FIXME:
>>> > +; The compare should change, and the metadata is swapped because the
>>> select operands are swapped.
>>> > +define i32 @smin2(i32 %x) {
>>> > +; CHECK-LABEL: @smin2(
>>> > +; CHECK-NEXT:    [[NOT_X:%.*]] = xor i32 %x, -1
>>> > +; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 %x, 0
>>> > +; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -1, i32
>>> [[NOT_X]], !prof ![[MD1]]
>>> > +; CHECK-NEXT:    ret i32 [[SEL]]
>>> > +;
>>> > +  %not_x = xor i32 %x, -1
>>> > +  %cmp = icmp slt i32 %x, 0
>>> > +  %sel = select i1 %cmp, i32 -1, i32 %not_x, !prof !1
>>> > +  ret i32 %sel
>>> > +}
>>> > +
>>> > +; FIXME:
>>> > +; The compare should change, but the metadata remains the same
>>> because the select operands are not swapped.
>>> > +define i32 @smax1(i32 %x) {
>>> > +; CHECK-LABEL: @smax1(
>>> > +; CHECK-NEXT:    [[NOT_X:%.*]] = xor i32 %x, -1
>>> > +; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 %x, 0
>>> > +; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 [[NOT_X]], i32
>>> -1, !prof ![[MD1]]
>>> > +; CHECK-NEXT:    ret i32 [[SEL]]
>>> > +;
>>> > +  %not_x = xor i32 %x, -1
>>> > +  %cmp = icmp slt i32 %x, 0
>>> > +  %sel = select i1 %cmp, i32 %not_x, i32 -1, !prof !1
>>> > +  ret i32 %sel
>>> > +}
>>> > +
>>> > +; FIXME:
>>> > +; The compare should change, and the metadata is swapped because the
>>> select operands are swapped.
>>> > +define i32 @smax2(i32 %x) {
>>> > +; CHECK-LABEL: @smax2(
>>> > +; CHECK-NEXT:    [[NOT_X:%.*]] = xor i32 %x, -1
>>> > +; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 %x, 0
>>> > +; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -1, i32
>>> [[NOT_X]], !prof ![[MD1]]
>>> > +; CHECK-NEXT:    ret i32 [[SEL]]
>>> > +;
>>> > +  %not_x = xor i32 %x, -1
>>> > +  %cmp = icmp sgt i32 %x, 0
>>> > +  %sel = select i1 %cmp, i32 -1, i32 %not_x, !prof !1
>>> > +  ret i32 %sel
>>> > +}
>>> > +
>>> > +; FIXME:
>>> > +; The compare should change, but the metadata remains the same
>>> because the select operands are not swapped.
>>> > +define i32 @umin1(i32 %x) {
>>> > +; CHECK-LABEL: @umin1(
>>> > +; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 %x, -1
>>> > +; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 %x, i32 -
>>> 2147483648, !prof ![[MD1]]
>>> > +; CHECK-NEXT:    ret i32 [[SEL]]
>>> > +;
>>> > +  %cmp = icmp sgt i32 %x, -1
>>> > +  %sel = select i1 %cmp, i32 %x, i32 -2147483648, !prof !1
>>> > +  ret i32 %sel
>>> > +}
>>> > +
>>> > +; FIXME:
>>> > +; The compare should change, and the metadata is swapped because the
>>> select operands are swapped.
>>> > +define i32 @umin2(i32 %x) {
>>> > +; CHECK-LABEL: @umin2(
>>> > +; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 %x, 0
>>> > +; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 2147483647,
>>> i32 %x, !prof ![[MD1]]
>>> > +; CHECK-NEXT:    ret i32 [[SEL]]
>>> > +;
>>> > +  %cmp = icmp slt i32 %x, 0
>>> > +  %sel = select i1 %cmp, i32 2147483647, i32 %x, !prof !1
>>> > +  ret i32 %sel
>>> > +}
>>> > +
>>> > +; FIXME:
>>> > +; The compare should change, but the metadata remains the same
>>> because the select operands are not swapped.
>>> > +define i32 @umax1(i32 %x) {
>>> > +; CHECK-LABEL: @umax1(
>>> > +; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 %x, 0
>>> > +; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 %x, i32
>>> 2147483647, !prof ![[MD1]]
>>> > +; CHECK-NEXT:    ret i32 [[SEL]]
>>> > +;
>>> > +  %cmp = icmp slt i32 %x, 0
>>> > +  %sel = select i1 %cmp, i32 %x, i32 2147483647, !prof !1
>>> > +  ret i32 %sel
>>> > +}
>>> > +
>>> > +; FIXME:
>>> > +; The compare should change, and the metadata is swapped because the
>>> select operands are swapped.
>>> > +define i32 @umax2(i32 %x) {
>>> > +; CHECK-LABEL: @umax2(
>>> > +; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 %x, -1
>>> > +; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 -2147483648,
>>> i32 %x, !prof ![[MD1]]
>>> > +; CHECK-NEXT:    ret i32 [[SEL]]
>>> > +;
>>> > +  %cmp = icmp sgt i32 %x, -1
>>> > +  %sel = select i1 %cmp, i32 -2147483648, i32 %x, !prof !1
>>> > +  ret i32 %sel
>>> > +}
>>> > +
>>> > !1 = !{!"branch_weights", i32 2, i32 10}
>>> > !2 = !{!"branch_weights", i32 3, i32 10}
>>> >
>>> > ; CHECK-DAG: ![[MD1]] = !{!"branch_weights", i32 2, i32 10}
>>> > -; CHECK-DAG: ![[MD2]] = !{!"branch_weights", i32 3, i32 10}
>>> > ; CHECK-DAG: ![[MD3]] = !{!"branch_weights", i32 10, i32 2}
>>> > +; CHECK-DAG: ![[MD4]] = !{!"branch_weights", i32 10, i32 3}
>>> >
>>> >
>>> > Modified: llvm/trunk/test/Transforms/InstCombine/sext.ll
>>> > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transfor
>>> ms/InstCombine/sext.ll?rev=287585&r1=287584&r2=287585&view=diff
>>> > ============================================================
>>> ==================
>>> > --- llvm/trunk/test/Transforms/InstCombine/sext.ll (original)
>>> > +++ llvm/trunk/test/Transforms/InstCombine/sext.ll Mon Nov 21
>>> 16:04:14 2016
>>> > @@ -229,10 +229,10 @@ define i32 @test17(i1 %x) {
>>> >
>>> > define i32 @test18(i16 %x) {
>>> > ; CHECK-LABEL: @test18(
>>> > -; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i16 %x, 0
>>> > -; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i16 0, i16 %x
>>> > -; CHECK-NEXT:    [[TMP1:%.*]] = zext i16 [[SEL]] to i32
>>> > -; CHECK-NEXT:    ret i32 [[TMP1]]
>>> > +; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i16 %x, 0
>>> > +; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[TMP1]], i16 %x, i16 0
>>> > +; CHECK-NEXT:    [[TMP2:%.*]] = zext i16 [[SEL]] to i32
>>> > +; CHECK-NEXT:    ret i32 [[TMP2]]
>>> > ;
>>> >   %cmp = icmp slt i16 %x, 0
>>> >   %sel = select i1 %cmp, i16 0, i16 %x
>>> >
>>> >
>>> > _______________________________________________
>>> > 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/20161210/981d6e0d/attachment.html>


More information about the llvm-commits mailing list