[InstSimplify] move minnum/maxnum with common op fold from instcombine
llvm-svn: 339144
This commit is contained in:
parent
e03993e6c7
commit
948ff87d7d
|
@ -4805,6 +4805,17 @@ static Value *simplifyBinaryIntrinsic(Function *F, Value *Op0, Value *Op1,
|
|||
if (match(Op0, m_CombineOr(m_NaN(), m_Undef()))) return Op1;
|
||||
if (match(Op1, m_CombineOr(m_NaN(), m_Undef()))) return Op0;
|
||||
|
||||
// Min/max of the same operation with common operand:
|
||||
// m(m(X, Y)), X --> m(X, Y) (4 commuted variants)
|
||||
if (auto *M0 = dyn_cast<IntrinsicInst>(Op0))
|
||||
if (M0->getIntrinsicID() == IID &&
|
||||
(M0->getOperand(0) == Op1 || M0->getOperand(1) == Op1))
|
||||
return Op0;
|
||||
if (auto *M1 = dyn_cast<IntrinsicInst>(Op1))
|
||||
if (M1->getIntrinsicID() == IID &&
|
||||
(M1->getOperand(0) == Op0 || M1->getOperand(1) == Op0))
|
||||
return Op1;
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -1143,23 +1143,7 @@ static Value *simplifyMinnumMaxnum(const IntrinsicInst &II) {
|
|||
if (C1 && C1->isNaN())
|
||||
return Arg0;
|
||||
|
||||
Value *X = nullptr;
|
||||
Value *Y = nullptr;
|
||||
if (II.getIntrinsicID() == Intrinsic::minnum) {
|
||||
// fmin(x, fmin(x, y)) -> fmin(x, y)
|
||||
// fmin(y, fmin(x, y)) -> fmin(x, y)
|
||||
if (match(Arg1, m_FMin(m_Value(X), m_Value(Y)))) {
|
||||
if (Arg0 == X || Arg0 == Y)
|
||||
return Arg1;
|
||||
}
|
||||
|
||||
// fmin(fmin(x, y), x) -> fmin(x, y)
|
||||
// fmin(fmin(x, y), y) -> fmin(x, y)
|
||||
if (match(Arg0, m_FMin(m_Value(X), m_Value(Y)))) {
|
||||
if (Arg1 == X || Arg1 == Y)
|
||||
return Arg0;
|
||||
}
|
||||
|
||||
// TODO: fmin(nnan x, inf) -> x
|
||||
// TODO: fmin(nnan ninf x, flt_max) -> x
|
||||
if (C1 && C1->isInfinity()) {
|
||||
|
@ -1169,20 +1153,6 @@ static Value *simplifyMinnumMaxnum(const IntrinsicInst &II) {
|
|||
}
|
||||
} else {
|
||||
assert(II.getIntrinsicID() == Intrinsic::maxnum);
|
||||
// fmax(x, fmax(x, y)) -> fmax(x, y)
|
||||
// fmax(y, fmax(x, y)) -> fmax(x, y)
|
||||
if (match(Arg1, m_FMax(m_Value(X), m_Value(Y)))) {
|
||||
if (Arg0 == X || Arg0 == Y)
|
||||
return Arg1;
|
||||
}
|
||||
|
||||
// fmax(fmax(x, y), x) -> fmax(x, y)
|
||||
// fmax(fmax(x, y), y) -> fmax(x, y)
|
||||
if (match(Arg0, m_FMax(m_Value(X), m_Value(Y)))) {
|
||||
if (Arg1 == X || Arg1 == Y)
|
||||
return Arg0;
|
||||
}
|
||||
|
||||
// TODO: fmax(nnan x, -inf) -> x
|
||||
// TODO: fmax(nnan ninf x, -flt_max) -> x
|
||||
if (C1 && C1->isInfinity()) {
|
||||
|
|
|
@ -145,48 +145,6 @@ define float @maxnum_f32_val_nan(float %x) {
|
|||
ret float %y
|
||||
}
|
||||
|
||||
define float @maxnum_x_maxnum_x_y(float %x, float %y) {
|
||||
; CHECK-LABEL: @maxnum_x_maxnum_x_y(
|
||||
; CHECK-NEXT: [[A:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]])
|
||||
; CHECK-NEXT: ret float [[A]]
|
||||
;
|
||||
%a = call float @llvm.maxnum.f32(float %x, float %y)
|
||||
%b = call float @llvm.maxnum.f32(float %x, float %a)
|
||||
ret float %b
|
||||
}
|
||||
|
||||
define float @maxnum_y_maxnum_x_y(float %x, float %y) {
|
||||
; CHECK-LABEL: @maxnum_y_maxnum_x_y(
|
||||
; CHECK-NEXT: [[A:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]])
|
||||
; CHECK-NEXT: ret float [[A]]
|
||||
;
|
||||
%a = call float @llvm.maxnum.f32(float %x, float %y)
|
||||
%b = call float @llvm.maxnum.f32(float %y, float %a)
|
||||
ret float %b
|
||||
}
|
||||
|
||||
define float @maxnum_z_maxnum_x_y(float %x, float %y, float %z) {
|
||||
; CHECK-LABEL: @maxnum_z_maxnum_x_y(
|
||||
; CHECK-NEXT: [[A:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]])
|
||||
; CHECK-NEXT: [[B:%.*]] = call float @llvm.maxnum.f32(float [[Z:%.*]], float [[A]])
|
||||
; CHECK-NEXT: ret float [[B]]
|
||||
;
|
||||
%a = call float @llvm.maxnum.f32(float %x, float %y)
|
||||
%b = call float @llvm.maxnum.f32(float %z, float %a)
|
||||
ret float %b
|
||||
}
|
||||
|
||||
define float @maxnum_maxnum_x_y_z(float %x, float %y, float %z) {
|
||||
; CHECK-LABEL: @maxnum_maxnum_x_y_z(
|
||||
; CHECK-NEXT: [[A:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]])
|
||||
; CHECK-NEXT: [[B:%.*]] = call float @llvm.maxnum.f32(float [[A]], float [[Z:%.*]])
|
||||
; CHECK-NEXT: ret float [[B]]
|
||||
;
|
||||
%a = call float @llvm.maxnum.f32(float %x, float %y)
|
||||
%b = call float @llvm.maxnum.f32(float %a, float %z)
|
||||
ret float %b
|
||||
}
|
||||
|
||||
define float @maxnum4(float %x, float %y, float %z, float %w) {
|
||||
; CHECK-LABEL: @maxnum4(
|
||||
; CHECK-NEXT: [[A:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]])
|
||||
|
|
|
@ -147,48 +147,6 @@ define float @minnum_f32_val_nan(float %x) {
|
|||
ret float %y
|
||||
}
|
||||
|
||||
define float @minnum_x_minnum_x_y(float %x, float %y) {
|
||||
; CHECK-LABEL: @minnum_x_minnum_x_y(
|
||||
; CHECK-NEXT: [[A:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]])
|
||||
; CHECK-NEXT: ret float [[A]]
|
||||
;
|
||||
%a = call float @llvm.minnum.f32(float %x, float %y)
|
||||
%b = call float @llvm.minnum.f32(float %x, float %a)
|
||||
ret float %b
|
||||
}
|
||||
|
||||
define float @minnum_y_minnum_x_y(float %x, float %y) {
|
||||
; CHECK-LABEL: @minnum_y_minnum_x_y(
|
||||
; CHECK-NEXT: [[A:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]])
|
||||
; CHECK-NEXT: ret float [[A]]
|
||||
;
|
||||
%a = call float @llvm.minnum.f32(float %x, float %y)
|
||||
%b = call float @llvm.minnum.f32(float %y, float %a)
|
||||
ret float %b
|
||||
}
|
||||
|
||||
define float @minnum_z_minnum_x_y(float %x, float %y, float %z) {
|
||||
; CHECK-LABEL: @minnum_z_minnum_x_y(
|
||||
; CHECK-NEXT: [[A:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]])
|
||||
; CHECK-NEXT: [[B:%.*]] = call float @llvm.minnum.f32(float [[Z:%.*]], float [[A]])
|
||||
; CHECK-NEXT: ret float [[B]]
|
||||
;
|
||||
%a = call float @llvm.minnum.f32(float %x, float %y)
|
||||
%b = call float @llvm.minnum.f32(float %z, float %a)
|
||||
ret float %b
|
||||
}
|
||||
|
||||
define float @minnum_minnum_x_y_z(float %x, float %y, float %z) {
|
||||
; CHECK-LABEL: @minnum_minnum_x_y_z(
|
||||
; CHECK-NEXT: [[A:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]])
|
||||
; CHECK-NEXT: [[B:%.*]] = call float @llvm.minnum.f32(float [[A]], float [[Z:%.*]])
|
||||
; CHECK-NEXT: ret float [[B]]
|
||||
;
|
||||
%a = call float @llvm.minnum.f32(float %x, float %y)
|
||||
%b = call float @llvm.minnum.f32(float %a, float %z)
|
||||
ret float %b
|
||||
}
|
||||
|
||||
define float @minnum4(float %x, float %y, float %z, float %w) {
|
||||
; CHECK-LABEL: @minnum4(
|
||||
; CHECK-NEXT: [[A:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]])
|
||||
|
|
|
@ -604,8 +604,7 @@ define float @maxnum_same_args(float %x) {
|
|||
define float @minnum_x_minnum_x_y(float %x, float %y) {
|
||||
; CHECK-LABEL: @minnum_x_minnum_x_y(
|
||||
; CHECK-NEXT: [[A:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]])
|
||||
; CHECK-NEXT: [[B:%.*]] = call float @llvm.minnum.f32(float [[X]], float [[A]])
|
||||
; CHECK-NEXT: ret float [[B]]
|
||||
; CHECK-NEXT: ret float [[A]]
|
||||
;
|
||||
%a = call float @llvm.minnum.f32(float %x, float %y)
|
||||
%b = call float @llvm.minnum.f32(float %x, float %a)
|
||||
|
@ -615,8 +614,7 @@ define float @minnum_x_minnum_x_y(float %x, float %y) {
|
|||
define float @minnum_y_minnum_x_y(float %x, float %y) {
|
||||
; CHECK-LABEL: @minnum_y_minnum_x_y(
|
||||
; CHECK-NEXT: [[A:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]])
|
||||
; CHECK-NEXT: [[B:%.*]] = call float @llvm.minnum.f32(float [[Y]], float [[A]])
|
||||
; CHECK-NEXT: ret float [[B]]
|
||||
; CHECK-NEXT: ret float [[A]]
|
||||
;
|
||||
%a = call float @llvm.minnum.f32(float %x, float %y)
|
||||
%b = call float @llvm.minnum.f32(float %y, float %a)
|
||||
|
@ -626,8 +624,7 @@ define float @minnum_y_minnum_x_y(float %x, float %y) {
|
|||
define float @minnum_x_y_minnum_x(float %x, float %y) {
|
||||
; CHECK-LABEL: @minnum_x_y_minnum_x(
|
||||
; CHECK-NEXT: [[A:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]])
|
||||
; CHECK-NEXT: [[B:%.*]] = call float @llvm.minnum.f32(float [[A]], float [[X]])
|
||||
; CHECK-NEXT: ret float [[B]]
|
||||
; CHECK-NEXT: ret float [[A]]
|
||||
;
|
||||
%a = call float @llvm.minnum.f32(float %x, float %y)
|
||||
%b = call float @llvm.minnum.f32(float %a, float %x)
|
||||
|
@ -637,19 +634,43 @@ define float @minnum_x_y_minnum_x(float %x, float %y) {
|
|||
define float @minnum_x_y_minnum_y(float %x, float %y) {
|
||||
; CHECK-LABEL: @minnum_x_y_minnum_y(
|
||||
; CHECK-NEXT: [[A:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]])
|
||||
; CHECK-NEXT: [[B:%.*]] = call float @llvm.minnum.f32(float [[A]], float [[Y]])
|
||||
; CHECK-NEXT: ret float [[B]]
|
||||
; CHECK-NEXT: ret float [[A]]
|
||||
;
|
||||
%a = call float @llvm.minnum.f32(float %x, float %y)
|
||||
%b = call float @llvm.minnum.f32(float %a, float %y)
|
||||
ret float %b
|
||||
}
|
||||
|
||||
; negative test
|
||||
|
||||
define float @minnum_z_minnum_x_y(float %x, float %y, float %z) {
|
||||
; CHECK-LABEL: @minnum_z_minnum_x_y(
|
||||
; CHECK-NEXT: [[A:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]])
|
||||
; CHECK-NEXT: [[B:%.*]] = call float @llvm.minnum.f32(float [[Z:%.*]], float [[A]])
|
||||
; CHECK-NEXT: ret float [[B]]
|
||||
;
|
||||
%a = call float @llvm.minnum.f32(float %x, float %y)
|
||||
%b = call float @llvm.minnum.f32(float %z, float %a)
|
||||
ret float %b
|
||||
}
|
||||
|
||||
; negative test
|
||||
|
||||
define float @minnum_x_y_minnum_z(float %x, float %y, float %z) {
|
||||
; CHECK-LABEL: @minnum_x_y_minnum_z(
|
||||
; CHECK-NEXT: [[A:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float [[Y:%.*]])
|
||||
; CHECK-NEXT: [[B:%.*]] = call float @llvm.minnum.f32(float [[A]], float [[Z:%.*]])
|
||||
; CHECK-NEXT: ret float [[B]]
|
||||
;
|
||||
%a = call float @llvm.minnum.f32(float %x, float %y)
|
||||
%b = call float @llvm.minnum.f32(float %a, float %z)
|
||||
ret float %b
|
||||
}
|
||||
|
||||
define float @maxnum_x_maxnum_x_y(float %x, float %y) {
|
||||
; CHECK-LABEL: @maxnum_x_maxnum_x_y(
|
||||
; CHECK-NEXT: [[A:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]])
|
||||
; CHECK-NEXT: [[B:%.*]] = call float @llvm.maxnum.f32(float [[X]], float [[A]])
|
||||
; CHECK-NEXT: ret float [[B]]
|
||||
; CHECK-NEXT: ret float [[A]]
|
||||
;
|
||||
%a = call float @llvm.maxnum.f32(float %x, float %y)
|
||||
%b = call float @llvm.maxnum.f32(float %x, float %a)
|
||||
|
@ -659,8 +680,7 @@ define float @maxnum_x_maxnum_x_y(float %x, float %y) {
|
|||
define float @maxnum_y_maxnum_x_y(float %x, float %y) {
|
||||
; CHECK-LABEL: @maxnum_y_maxnum_x_y(
|
||||
; CHECK-NEXT: [[A:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]])
|
||||
; CHECK-NEXT: [[B:%.*]] = call float @llvm.maxnum.f32(float [[Y]], float [[A]])
|
||||
; CHECK-NEXT: ret float [[B]]
|
||||
; CHECK-NEXT: ret float [[A]]
|
||||
;
|
||||
%a = call float @llvm.maxnum.f32(float %x, float %y)
|
||||
%b = call float @llvm.maxnum.f32(float %y, float %a)
|
||||
|
@ -670,8 +690,7 @@ define float @maxnum_y_maxnum_x_y(float %x, float %y) {
|
|||
define float @maxnum_x_y_maxnum_x(float %x, float %y) {
|
||||
; CHECK-LABEL: @maxnum_x_y_maxnum_x(
|
||||
; CHECK-NEXT: [[A:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]])
|
||||
; CHECK-NEXT: [[B:%.*]] = call float @llvm.maxnum.f32(float [[A]], float [[X]])
|
||||
; CHECK-NEXT: ret float [[B]]
|
||||
; CHECK-NEXT: ret float [[A]]
|
||||
;
|
||||
%a = call float @llvm.maxnum.f32(float %x, float %y)
|
||||
%b = call float @llvm.maxnum.f32(float %a, float %x)
|
||||
|
@ -681,11 +700,36 @@ define float @maxnum_x_y_maxnum_x(float %x, float %y) {
|
|||
define float @maxnum_x_y_maxnum_y(float %x, float %y) {
|
||||
; CHECK-LABEL: @maxnum_x_y_maxnum_y(
|
||||
; CHECK-NEXT: [[A:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]])
|
||||
; CHECK-NEXT: [[B:%.*]] = call float @llvm.maxnum.f32(float [[A]], float [[Y]])
|
||||
; CHECK-NEXT: ret float [[B]]
|
||||
; CHECK-NEXT: ret float [[A]]
|
||||
;
|
||||
%a = call float @llvm.maxnum.f32(float %x, float %y)
|
||||
%b = call float @llvm.maxnum.f32(float %a, float %y)
|
||||
ret float %b
|
||||
}
|
||||
|
||||
; negative test
|
||||
|
||||
define float @maxnum_z_maxnum_x_y(float %x, float %y, float %z) {
|
||||
; CHECK-LABEL: @maxnum_z_maxnum_x_y(
|
||||
; CHECK-NEXT: [[A:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]])
|
||||
; CHECK-NEXT: [[B:%.*]] = call float @llvm.maxnum.f32(float [[Z:%.*]], float [[A]])
|
||||
; CHECK-NEXT: ret float [[B]]
|
||||
;
|
||||
%a = call float @llvm.maxnum.f32(float %x, float %y)
|
||||
%b = call float @llvm.maxnum.f32(float %z, float %a)
|
||||
ret float %b
|
||||
}
|
||||
|
||||
; negative test
|
||||
|
||||
define float @maxnum_x_y_maxnum_z(float %x, float %y, float %z) {
|
||||
; CHECK-LABEL: @maxnum_x_y_maxnum_z(
|
||||
; CHECK-NEXT: [[A:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float [[Y:%.*]])
|
||||
; CHECK-NEXT: [[B:%.*]] = call float @llvm.maxnum.f32(float [[A]], float [[Z:%.*]])
|
||||
; CHECK-NEXT: ret float [[B]]
|
||||
;
|
||||
%a = call float @llvm.maxnum.f32(float %x, float %y)
|
||||
%b = call float @llvm.maxnum.f32(float %a, float %z)
|
||||
ret float %b
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue