diff --git a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp index cc753ce0531..30861bfe6c5 100644 --- a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ b/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/test/Transforms/InstCombine/fdiv.ll b/test/Transforms/InstCombine/fdiv.ll index 62ef758d9e3..1cc50528305 100644 --- a/test/Transforms/InstCombine/fdiv.ll +++ b/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 } -