From 948ff87d7de80ba0e959c322f19aa928c4ae7ad4 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Tue, 7 Aug 2018 14:36:27 +0000 Subject: [PATCH] [InstSimplify] move minnum/maxnum with common op fold from instcombine llvm-svn: 339144 --- llvm/lib/Analysis/InstructionSimplify.cpp | 11 +++ .../InstCombine/InstCombineCalls.cpp | 30 -------- llvm/test/Transforms/InstCombine/maxnum.ll | 42 ---------- llvm/test/Transforms/InstCombine/minnum.ll | 42 ---------- .../InstSimplify/floating-point-arithmetic.ll | 76 +++++++++++++++---- 5 files changed, 71 insertions(+), 130 deletions(-) diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 494ca656dba1..02137a51844a 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -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(Op0)) + if (M0->getIntrinsicID() == IID && + (M0->getOperand(0) == Op1 || M0->getOperand(1) == Op1)) + return Op0; + if (auto *M1 = dyn_cast(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 748cb97d9b5c..dcd080e33058 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -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()) { diff --git a/llvm/test/Transforms/InstCombine/maxnum.ll b/llvm/test/Transforms/InstCombine/maxnum.ll index 9cb4ad67aa67..7f94a722a030 100644 --- a/llvm/test/Transforms/InstCombine/maxnum.ll +++ b/llvm/test/Transforms/InstCombine/maxnum.ll @@ -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:%.*]]) diff --git a/llvm/test/Transforms/InstCombine/minnum.ll b/llvm/test/Transforms/InstCombine/minnum.ll index 48e8ea89c6fd..94c8b5518b21 100644 --- a/llvm/test/Transforms/InstCombine/minnum.ll +++ b/llvm/test/Transforms/InstCombine/minnum.ll @@ -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:%.*]]) diff --git a/llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll b/llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll index 56f39450af9c..79eb349ed7e9 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 @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 +} +