[llvm] [AMDGPU] Fix fneg fold with multi use fadd/fma (PR #217573)
Arseniy Obolenskiy via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 20 05:26:30 PDT 2026
https://github.com/aobolensk updated https://github.com/llvm/llvm-project/pull/217573
>From 8e3929c22a528e273c23f8668f52f7437baf01ce Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Thu, 20 Aug 2026 12:13:00 +0200
Subject: [PATCH] [AMDGPU] Fix fneg fold with multi use fadd/fma
nsz on the fneg does not apply to the fadd/fma other users
---
llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp | 8 +++-
llvm/test/CodeGen/AMDGPU/fneg-combines.new.ll | 43 +++++++++++++++++++
2 files changed, 49 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
index 3f93ca66dca17..d492e3b04cdfa 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp
@@ -5227,10 +5227,14 @@ SDValue AMDGPUTargetLowering::performFNegCombine(SDNode *N,
if (!shouldFoldFNegIntoSrc(N, N0))
return SDValue();
+ bool MayIgnoreSignedZeroForAllUses =
+ mayIgnoreSignedZero(N0) ||
+ (N0.hasOneUse() && mayIgnoreSignedZero(SDValue(N, 0)));
+
SDLoc SL(N);
switch (Opc) {
case ISD::FADD: {
- if (!mayIgnoreSignedZero(N0) && !N->getFlags().hasNoSignedZeros())
+ if (!MayIgnoreSignedZeroForAllUses)
return SDValue();
// (fneg (fadd x, y)) -> (fadd (fneg x), (fneg y))
@@ -5278,7 +5282,7 @@ SDValue AMDGPUTargetLowering::performFNegCombine(SDNode *N,
case ISD::FMA:
case ISD::FMAD: {
// TODO: handle llvm.amdgcn.fma.legacy
- if (!mayIgnoreSignedZero(N0) && !N->getFlags().hasNoSignedZeros())
+ if (!MayIgnoreSignedZeroForAllUses)
return SDValue();
// (fneg (fma x, y, z)) -> (fma x, (fneg y), (fneg z))
diff --git a/llvm/test/CodeGen/AMDGPU/fneg-combines.new.ll b/llvm/test/CodeGen/AMDGPU/fneg-combines.new.ll
index 6fd6e0d072e36..8e214b1d78e4b 100644
--- a/llvm/test/CodeGen/AMDGPU/fneg-combines.new.ll
+++ b/llvm/test/CodeGen/AMDGPU/fneg-combines.new.ll
@@ -4612,6 +4612,49 @@ bb:
ret float %i1
}
+define { float, float } @v_fneg_add_multi_use_add_f32_fneg_nsz(float %a, float %b) #0 {
+; GCN-LABEL: v_fneg_add_multi_use_add_f32_fneg_nsz:
+; GCN: ; %bb.0:
+; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT: v_add_f32_e32 v1, v0, v1
+; GCN-NEXT: v_xor_b32_e32 v0, 0x80000000, v1
+; GCN-NEXT: v_mul_f32_e32 v1, 4.0, v1
+; GCN-NEXT: s_setpc_b64 s[30:31]
+ %add = fadd float %a, %b
+ %fneg = fneg nsz float %add
+ %use1 = fmul float %add, 4.0
+ %insert.0 = insertvalue { float, float } poison, float %fneg, 0
+ %insert.1 = insertvalue { float, float } %insert.0, float %use1, 1
+ ret { float, float } %insert.1
+}
+
+define float @v_fneg_add_f32_fneg_nsz(float %a, float %b) #0 {
+; GCN-LABEL: v_fneg_add_f32_fneg_nsz:
+; GCN: ; %bb.0:
+; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT: v_sub_f32_e64 v0, -v0, v1
+; GCN-NEXT: s_setpc_b64 s[30:31]
+ %add = fadd float %a, %b
+ %fneg = fneg nsz float %add
+ ret float %fneg
+}
+
+define { float, float } @v_fneg_fma_multi_use_fma_f32_fneg_nsz(float %a, float %b, float %c) #0 {
+; GCN-LABEL: v_fneg_fma_multi_use_fma_f32_fneg_nsz:
+; GCN: ; %bb.0:
+; GCN-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GCN-NEXT: v_fma_f32 v1, v0, v1, v2
+; GCN-NEXT: v_xor_b32_e32 v0, 0x80000000, v1
+; GCN-NEXT: v_mul_f32_e32 v1, 4.0, v1
+; GCN-NEXT: s_setpc_b64 s[30:31]
+ %fma = call float @llvm.fma.f32(float %a, float %b, float %c)
+ %fneg = fneg nsz float %fma
+ %use1 = fmul float %fma, 4.0
+ %insert.0 = insertvalue { float, float } poison, float %fneg, 0
+ %insert.1 = insertvalue { float, float } %insert.0, float %use1, 1
+ ret { float, float } %insert.1
+}
+
declare i32 @llvm.amdgcn.workitem.id.x() #1
declare float @llvm.fma.f32(float, float, float) #1
declare <2 x float> @llvm.fma.v2f32(<2 x float>, <2 x float>, <2 x float>)
More information about the llvm-commits
mailing list