From fa68d93d54b0cc8f8ecb550641236955d38ae9c1 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Thu, 11 Aug 2022 11:40:54 -0400 Subject: [PATCH] [InstCombine] fold reassociative fadd with negated operand We manage to iteratively achieve this result with no extra uses, and the reassociate pass can also do this, but this pattern falls through the cracks in the example from issue #57053. --- llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp | 5 +++++ llvm/test/Transforms/InstCombine/fadd.ll | 15 ++++++--------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp index 13a0386..528c74a 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -1665,6 +1665,11 @@ Instruction *InstCombinerImpl::visitFAdd(BinaryOperator &I) { return BinaryOperator::CreateFMulFMF(X, NewMulC, &I); } + // (-X - Y) + (X + Z) --> Z - Y + if (match(&I, m_c_FAdd(m_FSub(m_FNeg(m_Value(X)), m_Value(Y)), + m_c_FAdd(m_Deferred(X), m_Value(Z))))) + return BinaryOperator::CreateFSubFMF(Z, Y, &I); + if (Value *V = FAddCombine(Builder).simplify(&I)) return replaceInstUsesWith(I, V); } diff --git a/llvm/test/Transforms/InstCombine/fadd.ll b/llvm/test/Transforms/InstCombine/fadd.ll index 275cecd..32ecd8cf 100644 --- a/llvm/test/Transforms/InstCombine/fadd.ll +++ b/llvm/test/Transforms/InstCombine/fadd.ll @@ -534,9 +534,7 @@ define float @fadd_fneg_reass_commute0(float %x, float %y, float %z) { ; CHECK-LABEL: @fadd_fneg_reass_commute0( ; CHECK-NEXT: [[N:%.*]] = fneg reassoc nsz float [[X:%.*]] ; CHECK-NEXT: call void @use(float [[N]]) -; CHECK-NEXT: [[S:%.*]] = fsub reassoc nsz float [[N]], [[Y:%.*]] -; CHECK-NEXT: [[A:%.*]] = fadd reassoc nsz float [[X]], [[Z:%.*]] -; CHECK-NEXT: [[R:%.*]] = fadd reassoc nsz float [[S]], [[A]] +; CHECK-NEXT: [[R:%.*]] = fsub reassoc nsz float [[Z:%.*]], [[Y:%.*]] ; CHECK-NEXT: ret float [[R]] ; %n = fneg reassoc nsz float %x @@ -553,8 +551,7 @@ define float @fadd_fneg_reass_commute1(float %x, float %y, float %z) { ; CHECK-NEXT: call void @use(float [[N]]) ; CHECK-NEXT: [[S:%.*]] = fsub float [[N]], [[Y:%.*]] ; CHECK-NEXT: call void @use(float [[S]]) -; CHECK-NEXT: [[A:%.*]] = fadd float [[X]], [[Z:%.*]] -; CHECK-NEXT: [[R:%.*]] = fadd reassoc nsz float [[A]], [[S]] +; CHECK-NEXT: [[R:%.*]] = fsub reassoc nsz float [[Z:%.*]], [[Y]] ; CHECK-NEXT: ret float [[R]] ; %n = fneg float %x @@ -574,7 +571,7 @@ define float @fadd_fneg_reass_commute2(float %x, float %y, float %z) { ; CHECK-NEXT: call void @use(float [[S]]) ; CHECK-NEXT: [[A:%.*]] = fadd float [[Z:%.*]], [[X]] ; CHECK-NEXT: call void @use(float [[A]]) -; CHECK-NEXT: [[R:%.*]] = fadd fast float [[S]], [[A]] +; CHECK-NEXT: [[R:%.*]] = fsub fast float [[Z]], [[Y]] ; CHECK-NEXT: ret float [[R]] ; %n = fneg float %x @@ -591,9 +588,7 @@ define <2 x float> @fadd_fneg_reass_commute3(<2 x float> %x, <2 x float> %y, <2 ; CHECK-LABEL: @fadd_fneg_reass_commute3( ; CHECK-NEXT: [[N:%.*]] = fneg reassoc nsz <2 x float> [[X:%.*]] ; CHECK-NEXT: call void @use_vec(<2 x float> [[N]]) -; CHECK-NEXT: [[S:%.*]] = fsub reassoc nsz <2 x float> [[N]], [[Y:%.*]] -; CHECK-NEXT: [[A:%.*]] = fadd reassoc nsz <2 x float> [[Z:%.*]], [[X]] -; CHECK-NEXT: [[R:%.*]] = fadd reassoc nsz <2 x float> [[A]], [[S]] +; CHECK-NEXT: [[R:%.*]] = fsub reassoc nsz <2 x float> [[Z:%.*]], [[Y:%.*]] ; CHECK-NEXT: ret <2 x float> [[R]] ; %n = fneg reassoc nsz <2 x float> %x @@ -604,6 +599,8 @@ define <2 x float> @fadd_fneg_reass_commute3(<2 x float> %x, <2 x float> %y, <2 ret <2 x float> %r } +; negative test - need reassoc (+ nsz) + define float @fadd_fneg_commute0(float %x, float %y, float %z) { ; CHECK-LABEL: @fadd_fneg_commute0( ; CHECK-NEXT: [[N:%.*]] = fneg float [[X:%.*]] -- 2.7.4