[InstSimplify] move minnum/maxnum with common op fold from instcombine

llvm-svn: 339144
This commit is contained in:
Sanjay Patel 2018-08-07 14:36:27 +00:00
parent e03993e6c7
commit 948ff87d7d
5 changed files with 71 additions and 130 deletions

View File

@ -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;

View File

@ -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()) {

View File

@ -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:%.*]])

View File

@ -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:%.*]])

View File

@ -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
}