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

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 6 14:47:58 PST 2016


I was circling back to this problem thinking this was just a failure of
InstSimplify (this was the inspiration for https://reviews.llvm.org/rL288833
/ 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/select_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/20161206/be68dc1b/attachment-0001.html>


More information about the llvm-commits mailing list