From f40aeae3876391dff8a00c3822b4acfbdefcc081 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 28 Jul 2019 17:10:06 +0000 Subject: [PATCH] [InstCombine] fold fsub+fneg with fdiv/fmul between The backend already does this via isNegatibleForFree(), but we may want to alter the fneg IR canonicalizations that currently exist, so we need to try harder to fold fneg in IR to avoid regressions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@367194 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/InstCombine/InstCombineAddSub.cpp | 15 +++++++++++++++ test/Transforms/InstCombine/fsub.ll | 16 ++++++++-------- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/lib/Transforms/InstCombine/InstCombineAddSub.cpp index 891370e2c76..9363a5e63e9 100644 --- a/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -1964,6 +1964,21 @@ Instruction *InstCombiner::visitFSub(BinaryOperator &I) { if (match(Op1, m_OneUse(m_FPExt(m_FNeg(m_Value(Y)))))) return BinaryOperator::CreateFAddFMF(Op0, Builder.CreateFPExt(Y, Ty), &I); + // Similar to above, but look through fmul/fdiv of the negated value: + // Op0 - (-X * Y) --> Op0 + (X * Y) + // Op0 - (Y * -X) --> Op0 + (X * Y) + if (match(Op1, m_OneUse(m_c_FMul(m_FNeg(m_Value(X)), m_Value(Y))))) { + Value *FMul = Builder.CreateFMulFMF(X, Y, &I); + return BinaryOperator::CreateFAddFMF(Op0, FMul, &I); + } + // Op0 - (-X / Y) --> Op0 + (X / Y) + // Op0 - (X / -Y) --> Op0 + (X / Y) + if (match(Op1, m_OneUse(m_FDiv(m_FNeg(m_Value(X)), m_Value(Y)))) || + match(Op1, m_OneUse(m_FDiv(m_Value(X), m_FNeg(m_Value(Y)))))) { + Value *FDiv = Builder.CreateFDivFMF(X, Y, &I); + return BinaryOperator::CreateFAddFMF(Op0, FDiv, &I); + } + // Handle special cases for FSub with selects feeding the operation if (Value *V = SimplifySelectsFeedingBinaryOp(I, Op0, Op1)) return replaceInstUsesWith(I, V); diff --git a/test/Transforms/InstCombine/fsub.ll b/test/Transforms/InstCombine/fsub.ll index 57148cf5642..a08a2944d62 100644 --- a/test/Transforms/InstCombine/fsub.ll +++ b/test/Transforms/InstCombine/fsub.ll @@ -518,8 +518,8 @@ define float @fsub_fdiv_fneg1_extra_use2(float %x, float %y, float %z) { ; CHECK-LABEL: @fsub_fdiv_fneg1_extra_use2( ; CHECK-NEXT: [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]] ; CHECK-NEXT: call void @use(float [[NEG]]) -; CHECK-NEXT: [[DIV:%.*]] = fdiv float [[NEG]], [[Y:%.*]] -; CHECK-NEXT: [[R:%.*]] = fsub float [[Z:%.*]], [[DIV]] +; CHECK-NEXT: [[TMP1:%.*]] = fdiv float [[X]], [[Y:%.*]] +; CHECK-NEXT: [[R:%.*]] = fadd float [[TMP1]], [[Z:%.*]] ; CHECK-NEXT: ret float [[R]] ; %neg = fsub float -0.000000e+00, %x @@ -533,8 +533,8 @@ define float @fsub_fdiv_fneg2_extra_use2(float %x, float %y, float %z) { ; CHECK-LABEL: @fsub_fdiv_fneg2_extra_use2( ; CHECK-NEXT: [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]] ; CHECK-NEXT: call void @use(float [[NEG]]) -; CHECK-NEXT: [[DIV:%.*]] = fdiv float [[Y:%.*]], [[NEG]] -; CHECK-NEXT: [[R:%.*]] = fsub float [[Z:%.*]], [[DIV]] +; CHECK-NEXT: [[TMP1:%.*]] = fdiv float [[Y:%.*]], [[X]] +; CHECK-NEXT: [[R:%.*]] = fadd float [[TMP1]], [[Z:%.*]] ; CHECK-NEXT: ret float [[R]] ; %neg = fsub float -0.000000e+00, %x @@ -548,8 +548,8 @@ define <2 x float> @fsub_fmul_fneg1_extra_use2(<2 x float> %x, <2 x float> %y, < ; CHECK-LABEL: @fsub_fmul_fneg1_extra_use2( ; CHECK-NEXT: [[NEG:%.*]] = fsub <2 x float> , [[X:%.*]] ; CHECK-NEXT: call void @use_vec(<2 x float> [[NEG]]) -; CHECK-NEXT: [[MUL:%.*]] = fmul <2 x float> [[NEG]], [[Y:%.*]] -; CHECK-NEXT: [[R:%.*]] = fsub <2 x float> [[Z:%.*]], [[MUL]] +; CHECK-NEXT: [[TMP1:%.*]] = fmul <2 x float> [[X]], [[Y:%.*]] +; CHECK-NEXT: [[R:%.*]] = fadd <2 x float> [[TMP1]], [[Z:%.*]] ; CHECK-NEXT: ret <2 x float> [[R]] ; %neg = fsub <2 x float> , %x @@ -563,8 +563,8 @@ define float @fsub_fmul_fneg2_extra_use2(float %x, float %y, float %z) { ; CHECK-LABEL: @fsub_fmul_fneg2_extra_use2( ; CHECK-NEXT: [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]] ; CHECK-NEXT: call void @use(float [[NEG]]) -; CHECK-NEXT: [[MUL:%.*]] = fmul float [[NEG]], [[Y:%.*]] -; CHECK-NEXT: [[R:%.*]] = fsub float [[Z:%.*]], [[MUL]] +; CHECK-NEXT: [[TMP1:%.*]] = fmul float [[X]], [[Y:%.*]] +; CHECK-NEXT: [[R:%.*]] = fadd float [[TMP1]], [[Z:%.*]] ; CHECK-NEXT: ret float [[R]] ; %neg = fsub float -0.000000e+00, %x