forked from OSchip/llvm-project
[InstCombine] add folds for icmp (umin|umax X, Y), X
This is a follow-up to: https://reviews.llvm.org/rL289855 (https://reviews.llvm.org/D27531) https://reviews.llvm.org/rL290111 llvm-svn: 290118
This commit is contained in:
parent
f5bb1d6c4e
commit
dd46b52942
|
@ -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 <typename LHS, typename RHS>
|
||||
inline match_combine_or<MaxMin_match<ICmpInst, LHS, RHS, smin_pred_ty>,
|
||||
|
@ -1365,6 +1363,20 @@ inline match_combine_or<MaxMin_match<ICmpInst, LHS, RHS, smax_pred_ty>,
|
|||
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 <typename LHS, typename RHS>
|
||||
inline match_combine_or<MaxMin_match<ICmpInst, LHS, RHS, umin_pred_ty>,
|
||||
MaxMin_match<ICmpInst, RHS, LHS, umin_pred_ty>>
|
||||
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 <typename LHS, typename RHS>
|
||||
inline match_combine_or<MaxMin_match<ICmpInst, LHS, RHS, umax_pred_ty>,
|
||||
MaxMin_match<ICmpInst, RHS, LHS, umax_pred_ty>>
|
||||
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
|
||||
|
|
|
@ -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;
|
||||
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue