diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h index f22acba65cc2..a30fc97e98ef 100644 --- a/llvm/include/llvm/IR/PatternMatch.h +++ b/llvm/include/llvm/IR/PatternMatch.h @@ -1349,8 +1349,6 @@ m_c_Xor(const LHS &L, const RHS &R) { return m_CombineOr(m_Xor(L, R), m_Xor(R, L)); } -// TODO: Add the related UMax and UMin commuted matchers. - /// Matches an SMin with LHS and RHS in either order. template inline match_combine_or, @@ -1365,6 +1363,20 @@ inline match_combine_or, m_c_SMax(const LHS &L, const RHS &R) { return m_CombineOr(m_SMax(L, R), m_SMax(R, L)); } +/// Matches a UMin with LHS and RHS in either order. +template +inline match_combine_or, + MaxMin_match> +m_c_UMin(const LHS &L, const RHS &R) { + return m_CombineOr(m_UMin(L, R), m_UMin(R, L)); +} +/// Matches a UMax with LHS and RHS in either order. +template +inline match_combine_or, + MaxMin_match> +m_c_UMax(const LHS &L, const RHS &R) { + return m_CombineOr(m_UMax(L, R), m_UMax(R, L)); +} } // end namespace PatternMatch } // end namespace llvm diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index b986d80ac74c..012bfc7b4944 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -3030,52 +3030,87 @@ Instruction *InstCombiner::foldICmpBinOp(ICmpInst &I) { return nullptr; } -/// Fold icmp Pred smin|smax(X, Y), X. -static Instruction *foldICmpWithSMinMax(ICmpInst &Cmp) { +/// Fold icmp Pred min|max(X, Y), X. +static Instruction *foldICmpWithMinMax(ICmpInst &Cmp) { ICmpInst::Predicate Pred = Cmp.getPredicate(); Value *Op0 = Cmp.getOperand(0); Value *X = Cmp.getOperand(1); - // TODO: This should be expanded to handle umax/umin. - - // Canonicalize minimum operand to LHS of the icmp. + // Canonicalize minimum or maximum operand to LHS of the icmp. if (match(X, m_c_SMin(m_Specific(Op0), m_Value())) || - match(X, m_c_SMax(m_Specific(Op0), m_Value()))) { + match(X, m_c_SMax(m_Specific(Op0), m_Value())) || + match(X, m_c_UMin(m_Specific(Op0), m_Value())) || + match(X, m_c_UMax(m_Specific(Op0), m_Value()))) { std::swap(Op0, X); Pred = Cmp.getSwappedPredicate(); } Value *Y; if (match(Op0, m_c_SMin(m_Specific(X), m_Value(Y)))) { - // smin(X, Y) == X --> X <= Y - // smin(X, Y) >= X --> X <= Y + // smin(X, Y) == X --> X s<= Y + // smin(X, Y) s>= X --> X s<= Y if (Pred == CmpInst::ICMP_EQ || Pred == CmpInst::ICMP_SGE) return new ICmpInst(ICmpInst::ICMP_SLE, X, Y); - // smin(X, Y) != X --> X > Y - // smin(X, Y) < X --> X > Y + // smin(X, Y) != X --> X s> Y + // smin(X, Y) s< X --> X s> Y if (Pred == CmpInst::ICMP_NE || Pred == CmpInst::ICMP_SLT) return new ICmpInst(ICmpInst::ICMP_SGT, X, Y); // These cases should be handled in InstSimplify: - // smin(X, Y) <= X --> true - // smin(X, Y) > X --> false + // smin(X, Y) s<= X --> true + // smin(X, Y) s> X --> false return nullptr; } + if (match(Op0, m_c_SMax(m_Specific(X), m_Value(Y)))) { - // smax(X, Y) == X --> X >= Y - // smax(X, Y) <= X --> X >= Y + // smax(X, Y) == X --> X s>= Y + // smax(X, Y) s<= X --> X s>= Y if (Pred == CmpInst::ICMP_EQ || Pred == CmpInst::ICMP_SLE) return new ICmpInst(ICmpInst::ICMP_SGE, X, Y); - // smax(X, Y) != X --> X < Y - // smax(X, Y) > X --> X < Y + // smax(X, Y) != X --> X s< Y + // smax(X, Y) s> X --> X s< Y if (Pred == CmpInst::ICMP_NE || Pred == CmpInst::ICMP_SGT) return new ICmpInst(ICmpInst::ICMP_SLT, X, Y); // These cases should be handled in InstSimplify: - // smax(X, Y) >= X --> true - // smax(X, Y) < X --> false + // smax(X, Y) s>= X --> true + // smax(X, Y) s< X --> false + return nullptr; + } + + if (match(Op0, m_c_UMin(m_Specific(X), m_Value(Y)))) { + // umin(X, Y) == X --> X u<= Y + // umin(X, Y) u>= X --> X u<= Y + if (Pred == CmpInst::ICMP_EQ || Pred == CmpInst::ICMP_UGE) + return new ICmpInst(ICmpInst::ICMP_ULE, X, Y); + + // umin(X, Y) != X --> X u> Y + // umin(X, Y) u< X --> X u> Y + if (Pred == CmpInst::ICMP_NE || Pred == CmpInst::ICMP_ULT) + return new ICmpInst(ICmpInst::ICMP_UGT, X, Y); + + // These cases should be handled in InstSimplify: + // umin(X, Y) u<= X --> true + // umin(X, Y) u> X --> false + return nullptr; + } + + if (match(Op0, m_c_UMax(m_Specific(X), m_Value(Y)))) { + // umax(X, Y) == X --> X u>= Y + // umax(X, Y) u<= X --> X u>= Y + if (Pred == CmpInst::ICMP_EQ || Pred == CmpInst::ICMP_ULE) + return new ICmpInst(ICmpInst::ICMP_UGE, X, Y); + + // umax(X, Y) != X --> X u< Y + // umax(X, Y) u> X --> X u< Y + if (Pred == CmpInst::ICMP_NE || Pred == CmpInst::ICMP_UGT) + return new ICmpInst(ICmpInst::ICMP_ULT, X, Y); + + // These cases should be handled in InstSimplify: + // umax(X, Y) u>= X --> true + // umax(X, Y) u< X --> false return nullptr; } @@ -4329,7 +4364,7 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) { if (Instruction *Res = foldICmpBinOp(I)) return Res; - if (Instruction *Res = foldICmpWithSMinMax(I)) + if (Instruction *Res = foldICmpWithMinMax(I)) return Res; { diff --git a/llvm/test/Transforms/InstCombine/umax-icmp.ll b/llvm/test/Transforms/InstCombine/umax-icmp.ll index 270b1ef25384..eabd41ceb62a 100644 --- a/llvm/test/Transforms/InstCombine/umax-icmp.ll +++ b/llvm/test/Transforms/InstCombine/umax-icmp.ll @@ -12,9 +12,7 @@ define i1 @eq_umax1(i32 %x, i32 %y) { ; CHECK-LABEL: @eq_umax1( -; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 %x, %y -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32 %x, i32 %y -; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[SEL]], %x +; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 %x, %y ; CHECK-NEXT: ret i1 [[CMP2]] ; %cmp1 = icmp ugt i32 %x, %y @@ -27,9 +25,7 @@ define i1 @eq_umax1(i32 %x, i32 %y) { define i1 @eq_umax2(i32 %x, i32 %y) { ; CHECK-LABEL: @eq_umax2( -; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 %y, %x -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32 %y, i32 %x -; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[SEL]], %x +; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 %x, %y ; CHECK-NEXT: ret i1 [[CMP2]] ; %cmp1 = icmp ugt i32 %y, %x @@ -43,9 +39,7 @@ define i1 @eq_umax2(i32 %x, i32 %y) { define i1 @eq_umax3(i32 %a, i32 %y) { ; CHECK-LABEL: @eq_umax3( ; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3 -; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 [[X]], %y -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32 [[X]], i32 %y -; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[X]], [[SEL]] +; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[X]], %y ; CHECK-NEXT: ret i1 [[CMP2]] ; %x = add i32 %a, 3 ; thwart complexity-based canonicalization @@ -60,9 +54,7 @@ define i1 @eq_umax3(i32 %a, i32 %y) { define i1 @eq_umax4(i32 %a, i32 %y) { ; CHECK-LABEL: @eq_umax4( ; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3 -; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[X]], %y -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32 %y, i32 [[X]] -; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[X]], [[SEL]] +; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[X]], %y ; CHECK-NEXT: ret i1 [[CMP2]] ; %x = add i32 %a, 3 ; thwart complexity-based canonicalization @@ -76,9 +68,7 @@ define i1 @eq_umax4(i32 %a, i32 %y) { define i1 @ule_umax1(i32 %x, i32 %y) { ; CHECK-LABEL: @ule_umax1( -; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 %x, %y -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32 %x, i32 %y -; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[SEL]], %x +; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 %x, %y ; CHECK-NEXT: ret i1 [[CMP2]] ; %cmp1 = icmp ugt i32 %x, %y @@ -91,9 +81,7 @@ define i1 @ule_umax1(i32 %x, i32 %y) { define i1 @ule_umax2(i32 %x, i32 %y) { ; CHECK-LABEL: @ule_umax2( -; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 %y, %x -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32 %y, i32 %x -; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[SEL]], %x +; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 %x, %y ; CHECK-NEXT: ret i1 [[CMP2]] ; %cmp1 = icmp ugt i32 %y, %x @@ -107,9 +95,7 @@ define i1 @ule_umax2(i32 %x, i32 %y) { define i1 @ule_umax3(i32 %a, i32 %y) { ; CHECK-LABEL: @ule_umax3( ; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3 -; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 [[X]], %y -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32 [[X]], i32 %y -; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[X]], [[SEL]] +; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[X]], %y ; CHECK-NEXT: ret i1 [[CMP2]] ; %x = add i32 %a, 3 ; thwart complexity-based canonicalization @@ -124,9 +110,7 @@ define i1 @ule_umax3(i32 %a, i32 %y) { define i1 @ule_umax4(i32 %a, i32 %y) { ; CHECK-LABEL: @ule_umax4( ; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3 -; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[X]], %y -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32 %y, i32 [[X]] -; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[X]], [[SEL]] +; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[X]], %y ; CHECK-NEXT: ret i1 [[CMP2]] ; %x = add i32 %a, 3 ; thwart complexity-based canonicalization @@ -140,9 +124,7 @@ define i1 @ule_umax4(i32 %a, i32 %y) { define i1 @ne_umax1(i32 %x, i32 %y) { ; CHECK-LABEL: @ne_umax1( -; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 %x, %y -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32 %x, i32 %y -; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[SEL]], %x +; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 %x, %y ; CHECK-NEXT: ret i1 [[CMP2]] ; %cmp1 = icmp ugt i32 %x, %y @@ -169,9 +151,7 @@ define i1 @ne_umax2(i32 %x, i32 %y) { define i1 @ne_umax3(i32 %a, i32 %y) { ; CHECK-LABEL: @ne_umax3( ; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3 -; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 [[X]], %y -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32 [[X]], i32 %y -; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[X]], [[SEL]] +; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[X]], %y ; CHECK-NEXT: ret i1 [[CMP2]] ; %x = add i32 %a, 3 ; thwart complexity-based canonicalization @@ -200,9 +180,7 @@ define i1 @ne_umax4(i32 %a, i32 %y) { define i1 @ugt_umax1(i32 %x, i32 %y) { ; CHECK-LABEL: @ugt_umax1( -; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 %x, %y -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32 %x, i32 %y -; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[SEL]], %x +; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 %x, %y ; CHECK-NEXT: ret i1 [[CMP2]] ; %cmp1 = icmp ugt i32 %x, %y @@ -229,9 +207,7 @@ define i1 @ugt_umax2(i32 %x, i32 %y) { define i1 @ugt_umax3(i32 %a, i32 %y) { ; CHECK-LABEL: @ugt_umax3( ; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3 -; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 [[X]], %y -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32 [[X]], i32 %y -; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[X]], [[SEL]] +; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[X]], %y ; CHECK-NEXT: ret i1 [[CMP2]] ; %x = add i32 %a, 3 ; thwart complexity-based canonicalization diff --git a/llvm/test/Transforms/InstCombine/umin-icmp.ll b/llvm/test/Transforms/InstCombine/umin-icmp.ll index f9d814d0d997..47954be5ab4f 100644 --- a/llvm/test/Transforms/InstCombine/umin-icmp.ll +++ b/llvm/test/Transforms/InstCombine/umin-icmp.ll @@ -4,7 +4,7 @@ ; If we have a umin feeding an unsigned or equality icmp that shares an ; operand with the umin, the compare should always be folded. ; Test all 4 foldable predicates (eq,ne,uge,ult) * 4 commutation -; possibilities for each predicate. Note that folds to true/false +; possibilities for each predicate. Note that folds to true/false ; (predicate is ule/ugt) or folds to an existing instruction should be ; handled by InstSimplify. @@ -12,9 +12,7 @@ define i1 @eq_umin1(i32 %x, i32 %y) { ; CHECK-LABEL: @eq_umin1( -; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 %x, %y -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32 %x, i32 %y -; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[SEL]], %x +; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 %x, %y ; CHECK-NEXT: ret i1 [[CMP2]] ; %cmp1 = icmp ult i32 %x, %y @@ -27,9 +25,7 @@ define i1 @eq_umin1(i32 %x, i32 %y) { define i1 @eq_umin2(i32 %x, i32 %y) { ; CHECK-LABEL: @eq_umin2( -; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 %y, %x -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32 %y, i32 %x -; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[SEL]], %x +; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 %x, %y ; CHECK-NEXT: ret i1 [[CMP2]] ; %cmp1 = icmp ult i32 %y, %x @@ -43,9 +39,7 @@ define i1 @eq_umin2(i32 %x, i32 %y) { define i1 @eq_umin3(i32 %a, i32 %y) { ; CHECK-LABEL: @eq_umin3( ; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3 -; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[X]], %y -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32 [[X]], i32 %y -; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[X]], [[SEL]] +; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[X]], %y ; CHECK-NEXT: ret i1 [[CMP2]] ; %x = add i32 %a, 3 ; thwart complexity-based canonicalization @@ -60,9 +54,7 @@ define i1 @eq_umin3(i32 %a, i32 %y) { define i1 @eq_umin4(i32 %a, i32 %y) { ; CHECK-LABEL: @eq_umin4( ; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3 -; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 [[X]], %y -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32 %y, i32 [[X]] -; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[X]], [[SEL]] +; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[X]], %y ; CHECK-NEXT: ret i1 [[CMP2]] ; %x = add i32 %a, 3 ; thwart complexity-based canonicalization @@ -76,9 +68,7 @@ define i1 @eq_umin4(i32 %a, i32 %y) { define i1 @uge_umin1(i32 %x, i32 %y) { ; CHECK-LABEL: @uge_umin1( -; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 %x, %y -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32 %x, i32 %y -; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[SEL]], %x +; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 %x, %y ; CHECK-NEXT: ret i1 [[CMP2]] ; %cmp1 = icmp ult i32 %x, %y @@ -91,9 +81,7 @@ define i1 @uge_umin1(i32 %x, i32 %y) { define i1 @uge_umin2(i32 %x, i32 %y) { ; CHECK-LABEL: @uge_umin2( -; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 %y, %x -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32 %y, i32 %x -; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[SEL]], %x +; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 %x, %y ; CHECK-NEXT: ret i1 [[CMP2]] ; %cmp1 = icmp ult i32 %y, %x @@ -107,9 +95,7 @@ define i1 @uge_umin2(i32 %x, i32 %y) { define i1 @uge_umin3(i32 %a, i32 %y) { ; CHECK-LABEL: @uge_umin3( ; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3 -; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[X]], %y -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32 [[X]], i32 %y -; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[X]], [[SEL]] +; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[X]], %y ; CHECK-NEXT: ret i1 [[CMP2]] ; %x = add i32 %a, 3 ; thwart complexity-based canonicalization @@ -124,9 +110,7 @@ define i1 @uge_umin3(i32 %a, i32 %y) { define i1 @uge_umin4(i32 %a, i32 %y) { ; CHECK-LABEL: @uge_umin4( ; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3 -; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 [[X]], %y -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32 %y, i32 [[X]] -; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[X]], [[SEL]] +; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[X]], %y ; CHECK-NEXT: ret i1 [[CMP2]] ; %x = add i32 %a, 3 ; thwart complexity-based canonicalization @@ -140,9 +124,7 @@ define i1 @uge_umin4(i32 %a, i32 %y) { define i1 @ne_umin1(i32 %x, i32 %y) { ; CHECK-LABEL: @ne_umin1( -; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 %x, %y -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32 %x, i32 %y -; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[SEL]], %x +; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 %x, %y ; CHECK-NEXT: ret i1 [[CMP2]] ; %cmp1 = icmp ult i32 %x, %y @@ -169,9 +151,7 @@ define i1 @ne_umin2(i32 %x, i32 %y) { define i1 @ne_umin3(i32 %a, i32 %y) { ; CHECK-LABEL: @ne_umin3( ; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3 -; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[X]], %y -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32 [[X]], i32 %y -; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[X]], [[SEL]] +; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[X]], %y ; CHECK-NEXT: ret i1 [[CMP2]] ; %x = add i32 %a, 3 ; thwart complexity-based canonicalization @@ -200,9 +180,7 @@ define i1 @ne_umin4(i32 %a, i32 %y) { define i1 @ult_umin1(i32 %x, i32 %y) { ; CHECK-LABEL: @ult_umin1( -; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 %x, %y -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32 %x, i32 %y -; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[SEL]], %x +; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 %x, %y ; CHECK-NEXT: ret i1 [[CMP2]] ; %cmp1 = icmp ult i32 %x, %y @@ -229,9 +207,7 @@ define i1 @ult_umin2(i32 %x, i32 %y) { define i1 @ult_umin3(i32 %a, i32 %y) { ; CHECK-LABEL: @ult_umin3( ; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3 -; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[X]], %y -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32 [[X]], i32 %y -; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[X]], [[SEL]] +; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[X]], %y ; CHECK-NEXT: ret i1 [[CMP2]] ; %x = add i32 %a, 3 ; thwart complexity-based canonicalization