[llvm] 1a35a3f - [AMDGPU] Use two v_xor_b32 instructions in fneg v2f32 selection pattern (#195585)
via llvm-commits
llvm-commits at lists.llvm.org
Mon May 4 07:43:31 PDT 2026
Author: Changpeng Fang
Date: 2026-05-04T07:43:25-07:00
New Revision: 1a35a3fda67f3673c84320440777e9b6a8640d5e
URL: https://github.com/llvm/llvm-project/commit/1a35a3fda67f3673c84320440777e9b6a8640d5e
DIFF: https://github.com/llvm/llvm-project/commit/1a35a3fda67f3673c84320440777e9b6a8640d5e.diff
LOG: [AMDGPU] Use two v_xor_b32 instructions in fneg v2f32 selection pattern (#195585)
'fneg x' and 'fadd 0.0, -x' are not strictly identical. For example,
'fneg 0.0' may result in '-0.0' but 'fadd 0.0, -0.0' may not.
Added:
Modified:
llvm/lib/Target/AMDGPU/SIInstructions.td
llvm/test/CodeGen/AMDGPU/fneg-fabs-v2f32.ll
llvm/test/CodeGen/AMDGPU/packed-fp32.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/AMDGPU/SIInstructions.td b/llvm/lib/Target/AMDGPU/SIInstructions.td
index 4b31c5d54a3ec..d1033c81a9361 100644
--- a/llvm/lib/Target/AMDGPU/SIInstructions.td
+++ b/llvm/lib/Target/AMDGPU/SIInstructions.td
@@ -2312,9 +2312,11 @@ def : GCNPat <
def : GCNPat <
(DivergentUnaryFrag<fneg> (v2f32 VReg_64:$src)),
- (V_PK_ADD_F32 !or(SRCMODS.OP_SEL_1, SRCMODS.NEG, SRCMODS.NEG_HI), VReg_64:$src,
- !or(SRCMODS.OP_SEL_1, SRCMODS.NEG, SRCMODS.NEG_HI), (i64 0),
- 0, 0, 0, 0, 0)
+ (REG_SEQUENCE VReg_64,
+ (V_XOR_B32_e64 (i32 (EXTRACT_SUBREG VReg_64:$src, sub0)),
+ (i32 (S_MOV_B32 (i32 0x80000000)))), sub0,
+ (V_XOR_B32_e64 (i32 (EXTRACT_SUBREG VReg_64:$src, sub1)),
+ (i32 (S_MOV_B32 (i32 0x80000000)))), sub1)
> {
let SubtargetPredicate = HasPackedFP32Ops;
}
diff --git a/llvm/test/CodeGen/AMDGPU/fneg-fabs-v2f32.ll b/llvm/test/CodeGen/AMDGPU/fneg-fabs-v2f32.ll
index a1bd37e68646c..aee9cf7ec1933 100644
--- a/llvm/test/CodeGen/AMDGPU/fneg-fabs-v2f32.ll
+++ b/llvm/test/CodeGen/AMDGPU/fneg-fabs-v2f32.ll
@@ -10,20 +10,23 @@ define <2 x float> @fneg_v2f32_v(<2 x float> %first) {
; GFX90A-LABEL: fneg_v2f32_v:
; GFX90A: ; %bb.0: ; %bb
; GFX90A-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX90A-NEXT: v_pk_add_f32 v[0:1], v[0:1], 0 neg_lo:[1,1] neg_hi:[1,1]
+; GFX90A-NEXT: v_xor_b32_e32 v1, 0x80000000, v1
+; GFX90A-NEXT: v_xor_b32_e32 v0, 0x80000000, v0
; GFX90A-NEXT: s_setpc_b64 s[30:31]
;
; GFX950-LABEL: fneg_v2f32_v:
; GFX950: ; %bb.0: ; %bb
; GFX950-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX950-NEXT: v_pk_add_f32 v[0:1], v[0:1], 0 neg_lo:[1,1] neg_hi:[1,1]
+; GFX950-NEXT: v_xor_b32_e32 v1, 0x80000000, v1
+; GFX950-NEXT: v_xor_b32_e32 v0, 0x80000000, v0
; GFX950-NEXT: s_setpc_b64 s[30:31]
;
; GFX1250-LABEL: fneg_v2f32_v:
; GFX1250: ; %bb.0: ; %bb
; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0
; GFX1250-NEXT: s_wait_kmcnt 0x0
-; GFX1250-NEXT: v_pk_add_f32 v[0:1], v[0:1], 0 neg_lo:[1,1] neg_hi:[1,1]
+; GFX1250-NEXT: v_xor_b32_e32 v0, 0x80000000, v0
+; GFX1250-NEXT: v_xor_b32_e32 v1, 0x80000000, v1
; GFX1250-NEXT: s_set_pc_i64 s[30:31]
bb:
%neg = fneg <2 x float> %first
@@ -77,7 +80,8 @@ define <2 x float> @fneg_fabs_v2f32_v(<2 x float> %first) {
; GFX90A-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX90A-NEXT: v_and_b32_e32 v1, 0x7fffffff, v1
; GFX90A-NEXT: v_and_b32_e32 v0, 0x7fffffff, v0
-; GFX90A-NEXT: v_pk_add_f32 v[0:1], v[0:1], 0 neg_lo:[1,1] neg_hi:[1,1]
+; GFX90A-NEXT: v_xor_b32_e32 v1, 0x80000000, v1
+; GFX90A-NEXT: v_xor_b32_e32 v0, 0x80000000, v0
; GFX90A-NEXT: s_setpc_b64 s[30:31]
;
; GFX950-LABEL: fneg_fabs_v2f32_v:
@@ -85,17 +89,19 @@ define <2 x float> @fneg_fabs_v2f32_v(<2 x float> %first) {
; GFX950-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GFX950-NEXT: v_and_b32_e32 v1, 0x7fffffff, v1
; GFX950-NEXT: v_and_b32_e32 v0, 0x7fffffff, v0
-; GFX950-NEXT: v_pk_add_f32 v[0:1], v[0:1], 0 neg_lo:[1,1] neg_hi:[1,1]
+; GFX950-NEXT: v_xor_b32_e32 v1, 0x80000000, v1
+; GFX950-NEXT: v_xor_b32_e32 v0, 0x80000000, v0
; GFX950-NEXT: s_setpc_b64 s[30:31]
;
; GFX1250-LABEL: fneg_fabs_v2f32_v:
; GFX1250: ; %bb.0: ; %bb
; GFX1250-NEXT: s_wait_loadcnt_dscnt 0x0
; GFX1250-NEXT: s_wait_kmcnt 0x0
-; GFX1250-NEXT: v_and_b32_e32 v1, 0x7fffffff, v1
; GFX1250-NEXT: v_and_b32_e32 v0, 0x7fffffff, v0
-; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_1)
-; GFX1250-NEXT: v_pk_add_f32 v[0:1], v[0:1], 0 neg_lo:[1,1] neg_hi:[1,1]
+; GFX1250-NEXT: v_and_b32_e32 v1, 0x7fffffff, v1
+; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
+; GFX1250-NEXT: v_xor_b32_e32 v0, 0x80000000, v0
+; GFX1250-NEXT: v_xor_b32_e32 v1, 0x80000000, v1
; GFX1250-NEXT: s_set_pc_i64 s[30:31]
bb:
%abs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %first)
diff --git a/llvm/test/CodeGen/AMDGPU/packed-fp32.ll b/llvm/test/CodeGen/AMDGPU/packed-fp32.ll
index 9cf59be504cc5..6ff0ada56469a 100644
--- a/llvm/test/CodeGen/AMDGPU/packed-fp32.ll
+++ b/llvm/test/CodeGen/AMDGPU/packed-fp32.ll
@@ -3750,7 +3750,8 @@ define amdgpu_kernel void @fneg_v2f32_vec(ptr addrspace(1) %a) {
; PACKED-SDAG-NEXT: s_waitcnt lgkmcnt(0)
; PACKED-SDAG-NEXT: global_load_dwordx2 v[0:1], v2, s[0:1]
; PACKED-SDAG-NEXT: s_waitcnt vmcnt(0)
-; PACKED-SDAG-NEXT: v_pk_add_f32 v[0:1], v[0:1], 0 neg_lo:[1,1] neg_hi:[1,1]
+; PACKED-SDAG-NEXT: v_xor_b32_e32 v1, 0x80000000, v1
+; PACKED-SDAG-NEXT: v_xor_b32_e32 v0, 0x80000000, v0
; PACKED-SDAG-NEXT: global_store_dwordx2 v2, v[0:1], s[0:1]
; PACKED-SDAG-NEXT: s_endpgm
;
@@ -3774,7 +3775,8 @@ define amdgpu_kernel void @fneg_v2f32_vec(ptr addrspace(1) %a) {
; GFX1250-SDAG-NEXT: s_wait_kmcnt 0x0
; GFX1250-SDAG-NEXT: global_load_b64 v[0:1], v2, s[0:1] scale_offset
; GFX1250-SDAG-NEXT: s_wait_loadcnt 0x0
-; GFX1250-SDAG-NEXT: v_pk_add_f32 v[0:1], v[0:1], 0 neg_lo:[1,1] neg_hi:[1,1]
+; GFX1250-SDAG-NEXT: v_xor_b32_e32 v1, 0x80000000, v1
+; GFX1250-SDAG-NEXT: v_xor_b32_e32 v0, 0x80000000, v0
; GFX1250-SDAG-NEXT: global_store_b64 v2, v[0:1], s[0:1] scale_offset
; GFX1250-SDAG-NEXT: s_endpgm
;
More information about the llvm-commits
mailing list