[InstSimplify] move minnum/maxnum with common op fold from instcombine
llvm-svn: 339144
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 494ca65..02137a5 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -4805,6 +4805,17 @@
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;
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 748cb97..dcd080e 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -1143,23 +1143,7 @@
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 @@
}
} 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()) {
diff --git a/llvm/test/Transforms/InstCombine/maxnum.ll b/llvm/test/Transforms/InstCombine/maxnum.ll
index 9cb4ad6..7f94a72 100644
--- a/llvm/test/Transforms/InstCombine/maxnum.ll
+++ b/llvm/test/Transforms/InstCombine/maxnum.ll
@@ -145,48 +145,6 @@
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:%.*]])
diff --git a/llvm/test/Transforms/InstCombine/minnum.ll b/llvm/test/Transforms/InstCombine/minnum.ll
index 48e8ea8..94c8b55 100644
--- a/llvm/test/Transforms/InstCombine/minnum.ll
+++ b/llvm/test/Transforms/InstCombine/minnum.ll
@@ -147,48 +147,6 @@
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:%.*]])
diff --git a/llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll b/llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll
index 56f3945..79eb349 100644
--- a/llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll
+++ b/llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll
@@ -604,8 +604,7 @@
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_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_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_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_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_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_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
+}
+