[llvm] 1470ce4 - [InstSimplify] fold min/max with matching min/max operands
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 11 08:24:23 PDT 2020
Author: Sanjay Patel
Date: 2020-08-11T11:23:15-04:00
New Revision: 1470ce4a76fc56729fb15dab0ca9877e25d26d58
URL: https://github.com/llvm/llvm-project/commit/1470ce4a76fc56729fb15dab0ca9877e25d26d58
DIFF: https://github.com/llvm/llvm-project/commit/1470ce4a76fc56729fb15dab0ca9877e25d26d58.diff
LOG: [InstSimplify] fold min/max with matching min/max operands
I think this is the last remaining translation of an existing
instcombine transform for the corresponding cmp+sel idiom.
This interpretation is more general though - we can remove
mismatched signed/unsigned combinations in addition to the
more obvious cases.
min/max(X, Y) must produce X or Y as the result, so this is
just another clause in the existing transform that was already
matching a min/max of min/max.
Added:
Modified:
llvm/include/llvm/IR/PatternMatch.h
llvm/lib/Analysis/InstructionSimplify.cpp
llvm/test/Transforms/InstSimplify/maxmin_intrinsics.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h
index 6333613eb065..78a311de0657 100644
--- a/llvm/include/llvm/IR/PatternMatch.h
+++ b/llvm/include/llvm/IR/PatternMatch.h
@@ -1714,6 +1714,17 @@ inline MaxMin_match<ICmpInst, LHS, RHS, umin_pred_ty> m_UMin(const LHS &L,
return MaxMin_match<ICmpInst, LHS, RHS, umin_pred_ty>(L, R);
}
+template <typename LHS, typename RHS>
+inline match_combine_or<
+ match_combine_or<MaxMin_match<ICmpInst, LHS, RHS, smax_pred_ty>,
+ MaxMin_match<ICmpInst, LHS, RHS, smin_pred_ty>>,
+ match_combine_or<MaxMin_match<ICmpInst, LHS, RHS, umax_pred_ty>,
+ MaxMin_match<ICmpInst, LHS, RHS, umin_pred_ty>>>
+m_MaxOrMin(const LHS &L, const RHS &R) {
+ return m_CombineOr(m_CombineOr(m_SMax(L, R), m_SMin(L, R)),
+ m_CombineOr(m_UMax(L, R), m_UMin(L, R)));
+}
+
/// Match an 'ordered' floating point maximum function.
/// Floating point has one special value 'NaN'. Therefore, there is no total
/// order. However, if we can ignore the 'NaN' value (for example, because of a
@@ -2106,6 +2117,17 @@ m_c_UMax(const LHS &L, const RHS &R) {
return MaxMin_match<ICmpInst, LHS, RHS, umax_pred_ty, true>(L, R);
}
+template <typename LHS, typename RHS>
+inline match_combine_or<
+ match_combine_or<MaxMin_match<ICmpInst, LHS, RHS, smax_pred_ty, true>,
+ MaxMin_match<ICmpInst, LHS, RHS, smin_pred_ty, true>>,
+ match_combine_or<MaxMin_match<ICmpInst, LHS, RHS, umax_pred_ty, true>,
+ MaxMin_match<ICmpInst, LHS, RHS, umin_pred_ty, true>>>
+m_c_MaxOrMin(const LHS &L, const RHS &R) {
+ return m_CombineOr(m_CombineOr(m_c_SMax(L, R), m_c_SMin(L, R)),
+ m_CombineOr(m_c_UMax(L, R), m_c_UMin(L, R)));
+}
+
/// Matches FAdd with LHS and RHS in either order.
template <typename LHS, typename RHS>
inline BinaryOp_match<LHS, RHS, Instruction::FAdd, true>
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index cc81b32b3ce6..20d0184a718f 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -5220,29 +5220,26 @@ static APInt getMaxMinLimit(Intrinsic::ID IID, unsigned BitWidth) {
}
}
-static bool isMinMax(Intrinsic::ID IID) {
- return IID == Intrinsic::smax || IID == Intrinsic::smin ||
- IID == Intrinsic::umax || IID == Intrinsic::umin;
-}
-
/// Given a min/max intrinsic, see if it can be removed based on having an
/// operand that is another min/max intrinsic with shared operand(s). The caller
/// is expected to swap the operand arguments to handle commutation.
static Value *foldMinMaxSharedOp(Intrinsic::ID IID, Value *Op0, Value *Op1) {
- assert(isMinMax(IID) && "Expected min/max intrinsic");
- auto *InnerMM = dyn_cast<IntrinsicInst>(Op0);
- if (!InnerMM)
+ Value *X, *Y;
+ if (!match(Op0, m_MaxOrMin(m_Value(X), m_Value(Y))))
return nullptr;
- Intrinsic::ID InnerID = InnerMM->getIntrinsicID();
- if (!isMinMax(InnerID))
+
+ auto *MM0 = dyn_cast<IntrinsicInst>(Op0);
+ if (!MM0)
return nullptr;
+ Intrinsic::ID IID0 = MM0->getIntrinsicID();
- if (Op1 == InnerMM->getOperand(0) || Op1 == InnerMM->getOperand(1)) {
+ if (Op1 == X || Op1 == Y ||
+ match(Op1, m_c_MaxOrMin(m_Specific(X), m_Specific(Y)))) {
// max (max X, Y), X --> max X, Y
- if (InnerID == IID)
- return InnerMM;
+ if (IID0 == IID)
+ return MM0;
// max (min X, Y), X --> X
- if (InnerID == getMaxMinOpposite(IID))
+ if (IID0 == getMaxMinOpposite(IID))
return Op1;
}
return nullptr;
diff --git a/llvm/test/Transforms/InstSimplify/maxmin_intrinsics.ll b/llvm/test/Transforms/InstSimplify/maxmin_intrinsics.ll
index 51b71d287b11..3f8d529fbce1 100644
--- a/llvm/test/Transforms/InstSimplify/maxmin_intrinsics.ll
+++ b/llvm/test/Transforms/InstSimplify/maxmin_intrinsics.ll
@@ -1089,9 +1089,7 @@ define i1 @umax_eq_commute(i8 %x, i8 %y) {
define i8 @smax_smax_smax(i8 %x, i8 %y) {
; CHECK-LABEL: @smax_smax_smax(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smax.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smax.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 [[M1]]
;
%m1 = call i8 @llvm.smax.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.smax.i8(i8 %y, i8 %x)
@@ -1102,9 +1100,7 @@ define i8 @smax_smax_smax(i8 %x, i8 %y) {
define i8 @smax_smax_smin(i8 %x, i8 %y) {
; CHECK-LABEL: @smax_smax_smin(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smin.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smax.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 [[M1]]
;
%m1 = call i8 @llvm.smax.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.smin.i8(i8 %y, i8 %x)
@@ -1115,9 +1111,7 @@ define i8 @smax_smax_smin(i8 %x, i8 %y) {
define i8 @smax_smax_umax(i8 %x, i8 %y) {
; CHECK-LABEL: @smax_smax_umax(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umax.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smax.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 [[M1]]
;
%m1 = call i8 @llvm.smax.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.umax.i8(i8 %y, i8 %x)
@@ -1128,9 +1122,7 @@ define i8 @smax_smax_umax(i8 %x, i8 %y) {
define i8 @smax_smax_umin(i8 %x, i8 %y) {
; CHECK-LABEL: @smax_smax_umin(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umin.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smax.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 [[M1]]
;
%m1 = call i8 @llvm.smax.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.umin.i8(i8 %y, i8 %x)
@@ -1140,10 +1132,8 @@ define i8 @smax_smax_umin(i8 %x, i8 %y) {
define i8 @smax_smin_smax(i8 %x, i8 %y) {
; CHECK-LABEL: @smax_smin_smax(
-; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smax.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smax.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smax.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
+; CHECK-NEXT: ret i8 [[M2]]
;
%m1 = call i8 @llvm.smin.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.smax.i8(i8 %y, i8 %x)
@@ -1153,10 +1143,8 @@ define i8 @smax_smin_smax(i8 %x, i8 %y) {
define i8 @smax_smin_smin(i8 %x, i8 %y) {
; CHECK-LABEL: @smax_smin_smin(
-; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smin.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smax.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smin.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
+; CHECK-NEXT: ret i8 [[M2]]
;
%m1 = call i8 @llvm.smin.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.smin.i8(i8 %y, i8 %x)
@@ -1166,10 +1154,8 @@ define i8 @smax_smin_smin(i8 %x, i8 %y) {
define i8 @smax_smin_umax(i8 %x, i8 %y) {
; CHECK-LABEL: @smax_smin_umax(
-; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umax.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smax.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umax.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
+; CHECK-NEXT: ret i8 [[M2]]
;
%m1 = call i8 @llvm.smin.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.umax.i8(i8 %y, i8 %x)
@@ -1179,10 +1165,8 @@ define i8 @smax_smin_umax(i8 %x, i8 %y) {
define i8 @smax_smin_umin(i8 %x, i8 %y) {
; CHECK-LABEL: @smax_smin_umin(
-; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umin.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smax.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umin.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
+; CHECK-NEXT: ret i8 [[M2]]
;
%m1 = call i8 @llvm.smin.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.umin.i8(i8 %y, i8 %x)
@@ -1192,10 +1176,8 @@ define i8 @smax_smin_umin(i8 %x, i8 %y) {
define i8 @smax_umax_smax(i8 %x, i8 %y) {
; CHECK-LABEL: @smax_umax_smax(
-; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smax.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smax.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smax.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
+; CHECK-NEXT: ret i8 [[M2]]
;
%m1 = call i8 @llvm.umax.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.smax.i8(i8 %y, i8 %x)
@@ -1206,9 +1188,7 @@ define i8 @smax_umax_smax(i8 %x, i8 %y) {
define i8 @smax_umax_smin(i8 %x, i8 %y) {
; CHECK-LABEL: @smax_umax_smin(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smin.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smax.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 [[M1]]
;
%m1 = call i8 @llvm.umax.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.smin.i8(i8 %y, i8 %x)
@@ -1216,6 +1196,8 @@ define i8 @smax_umax_smin(i8 %x, i8 %y) {
ret i8 %r
}
+; This could simplify (commuted min/max op).
+
define i8 @smax_umax_umax(i8 %x, i8 %y) {
; CHECK-LABEL: @smax_umax_umax(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
@@ -1229,6 +1211,8 @@ define i8 @smax_umax_umax(i8 %x, i8 %y) {
ret i8 %r
}
+; This could combine - smax(x,y) - but does not simplify.
+
define i8 @smax_umax_umin(i8 %x, i8 %y) {
; CHECK-LABEL: @smax_umax_umin(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
@@ -1244,10 +1228,8 @@ define i8 @smax_umax_umin(i8 %x, i8 %y) {
define i8 @smax_umin_smax(i8 %x, i8 %y) {
; CHECK-LABEL: @smax_umin_smax(
-; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smax.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smax.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smax.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
+; CHECK-NEXT: ret i8 [[M2]]
;
%m1 = call i8 @llvm.umin.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.smax.i8(i8 %y, i8 %x)
@@ -1258,9 +1240,7 @@ define i8 @smax_umin_smax(i8 %x, i8 %y) {
define i8 @smax_umin_smin(i8 %x, i8 %y) {
; CHECK-LABEL: @smax_umin_smin(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smin.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smax.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 [[M1]]
;
%m1 = call i8 @llvm.umin.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.smin.i8(i8 %y, i8 %x)
@@ -1268,6 +1248,8 @@ define i8 @smax_umin_smin(i8 %x, i8 %y) {
ret i8 %r
}
+; This could combine - smax(x,y) - but does not simplify.
+
define i8 @smax_umin_umax(i8 %x, i8 %y) {
; CHECK-LABEL: @smax_umin_umax(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
@@ -1281,6 +1263,8 @@ define i8 @smax_umin_umax(i8 %x, i8 %y) {
ret i8 %r
}
+; This could simplify (commuted min/max op).
+
define i8 @smax_umin_umin(i8 %x, i8 %y) {
; CHECK-LABEL: @smax_umin_umin(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
@@ -1296,10 +1280,8 @@ define i8 @smax_umin_umin(i8 %x, i8 %y) {
define i8 @smin_smax_smax(i8 %x, i8 %y) {
; CHECK-LABEL: @smin_smax_smax(
-; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smax.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smin.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smax.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
+; CHECK-NEXT: ret i8 [[M2]]
;
%m1 = call i8 @llvm.smax.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.smax.i8(i8 %y, i8 %x)
@@ -1309,10 +1291,8 @@ define i8 @smin_smax_smax(i8 %x, i8 %y) {
define i8 @smin_smax_smin(i8 %x, i8 %y) {
; CHECK-LABEL: @smin_smax_smin(
-; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smin.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smin.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smin.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
+; CHECK-NEXT: ret i8 [[M2]]
;
%m1 = call i8 @llvm.smax.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.smin.i8(i8 %y, i8 %x)
@@ -1322,10 +1302,8 @@ define i8 @smin_smax_smin(i8 %x, i8 %y) {
define i8 @smin_smax_umax(i8 %x, i8 %y) {
; CHECK-LABEL: @smin_smax_umax(
-; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umax.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smin.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umax.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
+; CHECK-NEXT: ret i8 [[M2]]
;
%m1 = call i8 @llvm.smax.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.umax.i8(i8 %y, i8 %x)
@@ -1335,10 +1313,8 @@ define i8 @smin_smax_umax(i8 %x, i8 %y) {
define i8 @smin_smax_umin(i8 %x, i8 %y) {
; CHECK-LABEL: @smin_smax_umin(
-; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umin.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smin.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umin.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
+; CHECK-NEXT: ret i8 [[M2]]
;
%m1 = call i8 @llvm.smax.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.umin.i8(i8 %y, i8 %x)
@@ -1349,9 +1325,7 @@ define i8 @smin_smax_umin(i8 %x, i8 %y) {
define i8 @smin_smin_smax(i8 %x, i8 %y) {
; CHECK-LABEL: @smin_smin_smax(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smax.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smin.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 [[M1]]
;
%m1 = call i8 @llvm.smin.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.smax.i8(i8 %y, i8 %x)
@@ -1362,9 +1336,7 @@ define i8 @smin_smin_smax(i8 %x, i8 %y) {
define i8 @smin_smin_smin(i8 %x, i8 %y) {
; CHECK-LABEL: @smin_smin_smin(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smin.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smin.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 [[M1]]
;
%m1 = call i8 @llvm.smin.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.smin.i8(i8 %y, i8 %x)
@@ -1375,9 +1347,7 @@ define i8 @smin_smin_smin(i8 %x, i8 %y) {
define i8 @smin_smin_umax(i8 %x, i8 %y) {
; CHECK-LABEL: @smin_smin_umax(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umax.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smin.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 [[M1]]
;
%m1 = call i8 @llvm.smin.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.umax.i8(i8 %y, i8 %x)
@@ -1388,9 +1358,7 @@ define i8 @smin_smin_umax(i8 %x, i8 %y) {
define i8 @smin_smin_umin(i8 %x, i8 %y) {
; CHECK-LABEL: @smin_smin_umin(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umin.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smin.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 [[M1]]
;
%m1 = call i8 @llvm.smin.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.umin.i8(i8 %y, i8 %x)
@@ -1401,9 +1369,7 @@ define i8 @smin_smin_umin(i8 %x, i8 %y) {
define i8 @smin_umax_smax(i8 %x, i8 %y) {
; CHECK-LABEL: @smin_umax_smax(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smax.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smin.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 [[M1]]
;
%m1 = call i8 @llvm.umax.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.smax.i8(i8 %y, i8 %x)
@@ -1413,10 +1379,8 @@ define i8 @smin_umax_smax(i8 %x, i8 %y) {
define i8 @smin_umax_smin(i8 %x, i8 %y) {
; CHECK-LABEL: @smin_umax_smin(
-; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smin.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smin.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smin.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
+; CHECK-NEXT: ret i8 [[M2]]
;
%m1 = call i8 @llvm.umax.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.smin.i8(i8 %y, i8 %x)
@@ -1424,6 +1388,8 @@ define i8 @smin_umax_smin(i8 %x, i8 %y) {
ret i8 %r
}
+; This could simplify (commuted min/max op).
+
define i8 @smin_umax_umax(i8 %x, i8 %y) {
; CHECK-LABEL: @smin_umax_umax(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
@@ -1437,6 +1403,8 @@ define i8 @smin_umax_umax(i8 %x, i8 %y) {
ret i8 %r
}
+; This could combine - smin(x,y) - but does not simplify.
+
define i8 @smin_umax_umin(i8 %x, i8 %y) {
; CHECK-LABEL: @smin_umax_umin(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
@@ -1453,9 +1421,7 @@ define i8 @smin_umax_umin(i8 %x, i8 %y) {
define i8 @smin_umin_smax(i8 %x, i8 %y) {
; CHECK-LABEL: @smin_umin_smax(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smax.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smin.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 [[M1]]
;
%m1 = call i8 @llvm.umin.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.smax.i8(i8 %y, i8 %x)
@@ -1465,10 +1431,8 @@ define i8 @smin_umin_smax(i8 %x, i8 %y) {
define i8 @smin_umin_smin(i8 %x, i8 %y) {
; CHECK-LABEL: @smin_umin_smin(
-; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smin.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smin.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smin.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
+; CHECK-NEXT: ret i8 [[M2]]
;
%m1 = call i8 @llvm.umin.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.smin.i8(i8 %y, i8 %x)
@@ -1476,6 +1440,8 @@ define i8 @smin_umin_smin(i8 %x, i8 %y) {
ret i8 %r
}
+; This could combine - smin(x,y) - but does not simplify.
+
define i8 @smin_umin_umax(i8 %x, i8 %y) {
; CHECK-LABEL: @smin_umin_umax(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
@@ -1489,6 +1455,8 @@ define i8 @smin_umin_umax(i8 %x, i8 %y) {
ret i8 %r
}
+; This could simplify (commuted min/max op).
+
define i8 @smin_umin_umin(i8 %x, i8 %y) {
; CHECK-LABEL: @smin_umin_umin(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
@@ -1502,6 +1470,8 @@ define i8 @smin_umin_umin(i8 %x, i8 %y) {
ret i8 %r
}
+; This could simplify (commuted min/max op).
+
define i8 @umax_smax_smax(i8 %x, i8 %y) {
; CHECK-LABEL: @umax_smax_smax(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
@@ -1515,6 +1485,8 @@ define i8 @umax_smax_smax(i8 %x, i8 %y) {
ret i8 %r
}
+; This could combine - umax(x,y) - but does not simplify.
+
define i8 @umax_smax_smin(i8 %x, i8 %y) {
; CHECK-LABEL: @umax_smax_smin(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
@@ -1530,10 +1502,8 @@ define i8 @umax_smax_smin(i8 %x, i8 %y) {
define i8 @umax_smax_umax(i8 %x, i8 %y) {
; CHECK-LABEL: @umax_smax_umax(
-; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umax.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umax.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umax.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
+; CHECK-NEXT: ret i8 [[M2]]
;
%m1 = call i8 @llvm.smax.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.umax.i8(i8 %y, i8 %x)
@@ -1544,9 +1514,7 @@ define i8 @umax_smax_umax(i8 %x, i8 %y) {
define i8 @umax_smax_umin(i8 %x, i8 %y) {
; CHECK-LABEL: @umax_smax_umin(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umin.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umax.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 [[M1]]
;
%m1 = call i8 @llvm.smax.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.umin.i8(i8 %y, i8 %x)
@@ -1554,6 +1522,8 @@ define i8 @umax_smax_umin(i8 %x, i8 %y) {
ret i8 %r
}
+; This could combine - umax(x,y) - but does not simplify.
+
define i8 @umax_smin_smax(i8 %x, i8 %y) {
; CHECK-LABEL: @umax_smin_smax(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
@@ -1567,6 +1537,8 @@ define i8 @umax_smin_smax(i8 %x, i8 %y) {
ret i8 %r
}
+; This could simplify (commuted min/max op).
+
define i8 @umax_smin_smin(i8 %x, i8 %y) {
; CHECK-LABEL: @umax_smin_smin(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
@@ -1582,10 +1554,8 @@ define i8 @umax_smin_smin(i8 %x, i8 %y) {
define i8 @umax_smin_umax(i8 %x, i8 %y) {
; CHECK-LABEL: @umax_smin_umax(
-; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umax.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umax.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umax.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
+; CHECK-NEXT: ret i8 [[M2]]
;
%m1 = call i8 @llvm.smin.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.umax.i8(i8 %y, i8 %x)
@@ -1596,9 +1566,7 @@ define i8 @umax_smin_umax(i8 %x, i8 %y) {
define i8 @umax_smin_umin(i8 %x, i8 %y) {
; CHECK-LABEL: @umax_smin_umin(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umin.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umax.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 [[M1]]
;
%m1 = call i8 @llvm.smin.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.umin.i8(i8 %y, i8 %x)
@@ -1609,9 +1577,7 @@ define i8 @umax_smin_umin(i8 %x, i8 %y) {
define i8 @umax_umax_smax(i8 %x, i8 %y) {
; CHECK-LABEL: @umax_umax_smax(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smax.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umax.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 [[M1]]
;
%m1 = call i8 @llvm.umax.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.smax.i8(i8 %y, i8 %x)
@@ -1622,9 +1588,7 @@ define i8 @umax_umax_smax(i8 %x, i8 %y) {
define i8 @umax_umax_smin(i8 %x, i8 %y) {
; CHECK-LABEL: @umax_umax_smin(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smin.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umax.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 [[M1]]
;
%m1 = call i8 @llvm.umax.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.smin.i8(i8 %y, i8 %x)
@@ -1635,9 +1599,7 @@ define i8 @umax_umax_smin(i8 %x, i8 %y) {
define i8 @umax_umax_umax(i8 %x, i8 %y) {
; CHECK-LABEL: @umax_umax_umax(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umax.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umax.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 [[M1]]
;
%m1 = call i8 @llvm.umax.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.umax.i8(i8 %y, i8 %x)
@@ -1648,9 +1610,7 @@ define i8 @umax_umax_umax(i8 %x, i8 %y) {
define i8 @umax_umax_umin(i8 %x, i8 %y) {
; CHECK-LABEL: @umax_umax_umin(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umin.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umax.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 [[M1]]
;
%m1 = call i8 @llvm.umax.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.umin.i8(i8 %y, i8 %x)
@@ -1660,10 +1620,8 @@ define i8 @umax_umax_umin(i8 %x, i8 %y) {
define i8 @umax_umin_smax(i8 %x, i8 %y) {
; CHECK-LABEL: @umax_umin_smax(
-; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smax.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umax.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smax.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
+; CHECK-NEXT: ret i8 [[M2]]
;
%m1 = call i8 @llvm.umin.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.smax.i8(i8 %y, i8 %x)
@@ -1673,10 +1631,8 @@ define i8 @umax_umin_smax(i8 %x, i8 %y) {
define i8 @umax_umin_smin(i8 %x, i8 %y) {
; CHECK-LABEL: @umax_umin_smin(
-; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smin.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umax.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smin.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
+; CHECK-NEXT: ret i8 [[M2]]
;
%m1 = call i8 @llvm.umin.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.smin.i8(i8 %y, i8 %x)
@@ -1686,10 +1642,8 @@ define i8 @umax_umin_smin(i8 %x, i8 %y) {
define i8 @umax_umin_umax(i8 %x, i8 %y) {
; CHECK-LABEL: @umax_umin_umax(
-; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umax.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umax.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umax.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
+; CHECK-NEXT: ret i8 [[M2]]
;
%m1 = call i8 @llvm.umin.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.umax.i8(i8 %y, i8 %x)
@@ -1699,10 +1653,8 @@ define i8 @umax_umin_umax(i8 %x, i8 %y) {
define i8 @umax_umin_umin(i8 %x, i8 %y) {
; CHECK-LABEL: @umax_umin_umin(
-; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umin.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umax.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umin.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
+; CHECK-NEXT: ret i8 [[M2]]
;
%m1 = call i8 @llvm.umin.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.umin.i8(i8 %y, i8 %x)
@@ -1710,6 +1662,8 @@ define i8 @umax_umin_umin(i8 %x, i8 %y) {
ret i8 %r
}
+; This could simplify (commuted min/max op).
+
define i8 @umin_smax_smax(i8 %x, i8 %y) {
; CHECK-LABEL: @umin_smax_smax(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
@@ -1723,6 +1677,8 @@ define i8 @umin_smax_smax(i8 %x, i8 %y) {
ret i8 %r
}
+; This could combine - umin(x,y) - but does not simplify.
+
define i8 @umin_smax_smin(i8 %x, i8 %y) {
; CHECK-LABEL: @umin_smax_smin(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
@@ -1739,9 +1695,7 @@ define i8 @umin_smax_smin(i8 %x, i8 %y) {
define i8 @umin_smax_umax(i8 %x, i8 %y) {
; CHECK-LABEL: @umin_smax_umax(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umax.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umin.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 [[M1]]
;
%m1 = call i8 @llvm.smax.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.umax.i8(i8 %y, i8 %x)
@@ -1751,10 +1705,8 @@ define i8 @umin_smax_umax(i8 %x, i8 %y) {
define i8 @umin_smax_umin(i8 %x, i8 %y) {
; CHECK-LABEL: @umin_smax_umin(
-; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umin.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umin.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umin.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
+; CHECK-NEXT: ret i8 [[M2]]
;
%m1 = call i8 @llvm.smax.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.umin.i8(i8 %y, i8 %x)
@@ -1762,6 +1714,8 @@ define i8 @umin_smax_umin(i8 %x, i8 %y) {
ret i8 %r
}
+; This could combine - umin(x,y) - but does not simplify.
+
define i8 @umin_smin_smax(i8 %x, i8 %y) {
; CHECK-LABEL: @umin_smin_smax(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
@@ -1775,6 +1729,8 @@ define i8 @umin_smin_smax(i8 %x, i8 %y) {
ret i8 %r
}
+; This could simplify (commuted min/max op).
+
define i8 @umin_smin_smin(i8 %x, i8 %y) {
; CHECK-LABEL: @umin_smin_smin(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
@@ -1791,9 +1747,7 @@ define i8 @umin_smin_smin(i8 %x, i8 %y) {
define i8 @umin_smin_umax(i8 %x, i8 %y) {
; CHECK-LABEL: @umin_smin_umax(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umax.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umin.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 [[M1]]
;
%m1 = call i8 @llvm.smin.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.umax.i8(i8 %y, i8 %x)
@@ -1803,10 +1757,8 @@ define i8 @umin_smin_umax(i8 %x, i8 %y) {
define i8 @umin_smin_umin(i8 %x, i8 %y) {
; CHECK-LABEL: @umin_smin_umin(
-; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umin.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umin.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umin.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
+; CHECK-NEXT: ret i8 [[M2]]
;
%m1 = call i8 @llvm.smin.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.umin.i8(i8 %y, i8 %x)
@@ -1816,10 +1768,8 @@ define i8 @umin_smin_umin(i8 %x, i8 %y) {
define i8 @umin_umax_smax(i8 %x, i8 %y) {
; CHECK-LABEL: @umin_umax_smax(
-; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smax.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umin.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smax.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
+; CHECK-NEXT: ret i8 [[M2]]
;
%m1 = call i8 @llvm.umax.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.smax.i8(i8 %y, i8 %x)
@@ -1829,10 +1779,8 @@ define i8 @umin_umax_smax(i8 %x, i8 %y) {
define i8 @umin_umax_smin(i8 %x, i8 %y) {
; CHECK-LABEL: @umin_umax_smin(
-; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smin.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umin.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smin.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
+; CHECK-NEXT: ret i8 [[M2]]
;
%m1 = call i8 @llvm.umax.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.smin.i8(i8 %y, i8 %x)
@@ -1842,10 +1790,8 @@ define i8 @umin_umax_smin(i8 %x, i8 %y) {
define i8 @umin_umax_umax(i8 %x, i8 %y) {
; CHECK-LABEL: @umin_umax_umax(
-; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umax.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umin.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umax.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
+; CHECK-NEXT: ret i8 [[M2]]
;
%m1 = call i8 @llvm.umax.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.umax.i8(i8 %y, i8 %x)
@@ -1855,10 +1801,8 @@ define i8 @umin_umax_umax(i8 %x, i8 %y) {
define i8 @umin_umax_umin(i8 %x, i8 %y) {
; CHECK-LABEL: @umin_umax_umin(
-; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umin.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umin.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umin.i8(i8 [[Y:%.*]], i8 [[X:%.*]])
+; CHECK-NEXT: ret i8 [[M2]]
;
%m1 = call i8 @llvm.umax.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.umin.i8(i8 %y, i8 %x)
@@ -1869,9 +1813,7 @@ define i8 @umin_umax_umin(i8 %x, i8 %y) {
define i8 @umin_umin_smax(i8 %x, i8 %y) {
; CHECK-LABEL: @umin_umin_smax(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smax.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umin.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 [[M1]]
;
%m1 = call i8 @llvm.umin.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.smax.i8(i8 %y, i8 %x)
@@ -1882,9 +1824,7 @@ define i8 @umin_umin_smax(i8 %x, i8 %y) {
define i8 @umin_umin_smin(i8 %x, i8 %y) {
; CHECK-LABEL: @umin_umin_smin(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.smin.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umin.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 [[M1]]
;
%m1 = call i8 @llvm.umin.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.smin.i8(i8 %y, i8 %x)
@@ -1895,9 +1835,7 @@ define i8 @umin_umin_smin(i8 %x, i8 %y) {
define i8 @umin_umin_umax(i8 %x, i8 %y) {
; CHECK-LABEL: @umin_umin_umax(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umax.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umin.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 [[M1]]
;
%m1 = call i8 @llvm.umin.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.umax.i8(i8 %y, i8 %x)
@@ -1908,9 +1846,7 @@ define i8 @umin_umin_umax(i8 %x, i8 %y) {
define i8 @umin_umin_umin(i8 %x, i8 %y) {
; CHECK-LABEL: @umin_umin_umin(
; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT: [[M2:%.*]] = call i8 @llvm.umin.i8(i8 [[Y]], i8 [[X]])
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umin.i8(i8 [[M1]], i8 [[M2]])
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 [[M1]]
;
%m1 = call i8 @llvm.umin.i8(i8 %x, i8 %y)
%m2 = call i8 @llvm.umin.i8(i8 %y, i8 %x)
More information about the llvm-commits
mailing list