From a9ab31558caa28e9619647678e9118fde737abde Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Fri, 26 Jul 2019 19:56:59 +0000 Subject: [PATCH] [InstCombine] canonicalize negated operand of fdiv This is a transform that we use with fmul, so use it for fdiv too for consistency. llvm-svn: 367146 --- llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp | 10 ++++++++++ llvm/test/Transforms/InstCombine/fdiv.ll | 9 ++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp index cc753ce..30861bf 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -1234,6 +1234,16 @@ Instruction *InstCombiner::visitFDiv(BinaryOperator &I) { return &I; } + // Sink negation: -X / Y --> -(X / Y) + // But don't transform constant expressions because there's an inverse fold. + if (match(Op0, m_OneUse(m_FNeg(m_Value(X)))) && !isa(Op0)) + return BinaryOperator::CreateFNegFMF(Builder.CreateFDivFMF(X, Op1, &I), &I); + + // Sink negation: Y / -X --> -(Y / X) + // But don't transform constant expressions because there's an inverse fold. + if (match(Op1, m_OneUse(m_FNeg(m_Value(X)))) && !isa(Op1)) + return BinaryOperator::CreateFNegFMF(Builder.CreateFDivFMF(Op0, X, &I), &I); + // X / (X * Y) --> 1.0 / Y // Reassociate to (X / X -> 1.0) is legal when NaNs are not allowed. // We can ignore the possibility that X is infinity because INF/INF is NaN. diff --git a/llvm/test/Transforms/InstCombine/fdiv.ll b/llvm/test/Transforms/InstCombine/fdiv.ll index 62ef758..1cc5052 100644 --- a/llvm/test/Transforms/InstCombine/fdiv.ll +++ b/llvm/test/Transforms/InstCombine/fdiv.ll @@ -501,8 +501,8 @@ define <2 x float> @div_constant_dividend3(<2 x float> %x) { define double @fdiv_fneg1(double %x, double %y) { ; CHECK-LABEL: @fdiv_fneg1( -; CHECK-NEXT: [[NEG:%.*]] = fsub double -0.000000e+00, [[X:%.*]] -; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[NEG]], [[Y:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = fdiv double [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: [[DIV:%.*]] = fsub double -0.000000e+00, [[TMP1]] ; CHECK-NEXT: ret double [[DIV]] ; %neg = fsub double -0.0, %x @@ -512,8 +512,8 @@ define double @fdiv_fneg1(double %x, double %y) { define <2 x float> @fdiv_fneg2(<2 x float> %x, <2 x float> %y) { ; CHECK-LABEL: @fdiv_fneg2( -; CHECK-NEXT: [[NEG:%.*]] = fsub <2 x float> , [[X:%.*]] -; CHECK-NEXT: [[DIV:%.*]] = fdiv <2 x float> [[Y:%.*]], [[NEG]] +; CHECK-NEXT: [[TMP1:%.*]] = fdiv <2 x float> [[Y:%.*]], [[X:%.*]] +; CHECK-NEXT: [[DIV:%.*]] = fsub <2 x float> , [[TMP1]] ; CHECK-NEXT: ret <2 x float> [[DIV]] ; %neg = fsub <2 x float> , %x @@ -533,4 +533,3 @@ define float @fdiv_fneg1_extra_use(float %x, float %y) { %div = fdiv float %neg, %y ret float %div } - -- 2.7.4