[llvm] [AMDGPU] Fix lowerFCOPYSIGN dropping the sign bit when narrowing the sign operand (PR #203492)

via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 12 03:11:49 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-amdgpu

Author: Arseniy Obolenskiy (aobolensk)

<details>
<summary>Changes</summary>

TRUNCATE of the v2i32-bitcast sign kept the low 16 bits of each lane but dropped f32 sign bit at bit 3

Shift right by 16 first so the sign bit lands in the f16 sign position

---

Patch is 23.57 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/203492.diff


3 Files Affected:

- (modified) llvm/lib/Target/AMDGPU/SIISelLowering.cpp (+6-2) 
- (modified) llvm/test/CodeGen/AMDGPU/fcopysign.bf16.ll (+58-52) 
- (modified) llvm/test/CodeGen/AMDGPU/fcopysign.f16.ll (+48-46) 


``````````diff
diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
index eb3b869990cdd..b2e96b26282b5 100644
--- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
@@ -8873,11 +8873,15 @@ SDValue SITargetLowering::lowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const {
     return Op;
 
   // fcopysign v2f16:mag, v2f32:sign ->
-  //   fcopysign v2f16:mag, bitcast (trunc (bitcast sign to v2i32) to v2i16)
+  //   fcopysign v2f16:mag,
+  //     bitcast (trunc (srl (bitcast sign to v2i32), 16) to v2i16)
 
   SDLoc SL(Op);
   SDValue SignAsInt32 = DAG.getNode(ISD::BITCAST, SL, MVT::v2i32, Sign);
-  SDValue SignAsInt16 = DAG.getNode(ISD::TRUNCATE, SL, MVT::v2i16, SignAsInt32);
+  SDValue ShiftAmt = DAG.getConstant(16, SL, MVT::v2i32);
+  SDValue SignShifted =
+      DAG.getNode(ISD::SRL, SL, MVT::v2i32, SignAsInt32, ShiftAmt);
+  SDValue SignAsInt16 = DAG.getNode(ISD::TRUNCATE, SL, MVT::v2i16, SignShifted);
 
   SDValue SignAsHalf16 = DAG.getNode(ISD::BITCAST, SL, MagVT, SignAsInt16);
 
diff --git a/llvm/test/CodeGen/AMDGPU/fcopysign.bf16.ll b/llvm/test/CodeGen/AMDGPU/fcopysign.bf16.ll
index 3f6750546618f..b0fc2d07b5404 100644
--- a/llvm/test/CodeGen/AMDGPU/fcopysign.bf16.ll
+++ b/llvm/test/CodeGen/AMDGPU/fcopysign.bf16.ll
@@ -3911,9 +3911,8 @@ define <2 x bfloat> @v_copysign_out_v2bf16_mag_v2bf16_sign_v2f64(<2 x bfloat> %m
 ; GFX8-LABEL: v_copysign_out_v2bf16_mag_v2bf16_sign_v2f64:
 ; GFX8:       ; %bb.0:
 ; GFX8-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX8-NEXT:    v_lshlrev_b32_e32 v1, 16, v4
-; GFX8-NEXT:    v_and_b32_e32 v2, 0x8000, v2
-; GFX8-NEXT:    v_or_b32_e32 v1, v2, v1
+; GFX8-NEXT:    s_mov_b32 s4, 0x3020706
+; GFX8-NEXT:    v_perm_b32 v1, v2, v4, s4
 ; GFX8-NEXT:    s_mov_b32 s4, 0x7fff7fff
 ; GFX8-NEXT:    v_bfi_b32 v0, s4, v0, v1
 ; GFX8-NEXT:    s_setpc_b64 s[30:31]
@@ -3921,7 +3920,7 @@ define <2 x bfloat> @v_copysign_out_v2bf16_mag_v2bf16_sign_v2f64(<2 x bfloat> %m
 ; GFX9-LABEL: v_copysign_out_v2bf16_mag_v2bf16_sign_v2f64:
 ; GFX9:       ; %bb.0:
 ; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT:    s_mov_b32 s4, 0x5040100
+; GFX9-NEXT:    s_mov_b32 s4, 0x7060302
 ; GFX9-NEXT:    v_perm_b32 v1, v4, v2, s4
 ; GFX9-NEXT:    s_mov_b32 s4, 0x7fff7fff
 ; GFX9-NEXT:    v_bfi_b32 v0, s4, v0, v1
@@ -3930,22 +3929,22 @@ define <2 x bfloat> @v_copysign_out_v2bf16_mag_v2bf16_sign_v2f64(<2 x bfloat> %m
 ; GFX10-LABEL: v_copysign_out_v2bf16_mag_v2bf16_sign_v2f64:
 ; GFX10:       ; %bb.0:
 ; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX10-NEXT:    v_perm_b32 v1, v4, v2, 0x5040100
+; GFX10-NEXT:    v_perm_b32 v1, v4, v2, 0x7060302
 ; GFX10-NEXT:    v_bfi_b32 v0, 0x7fff7fff, v0, v1
 ; GFX10-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11TRUE16-LABEL: v_copysign_out_v2bf16_mag_v2bf16_sign_v2f64:
 ; GFX11TRUE16:       ; %bb.0:
 ; GFX11TRUE16-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11TRUE16-NEXT:    v_mov_b16_e32 v2.h, v4.l
+; GFX11TRUE16-NEXT:    v_mov_b16_e32 v4.l, v2.h
 ; GFX11TRUE16-NEXT:    s_delay_alu instid0(VALU_DEP_1)
-; GFX11TRUE16-NEXT:    v_bfi_b32 v0, 0x7fff7fff, v0, v2
+; GFX11TRUE16-NEXT:    v_bfi_b32 v0, 0x7fff7fff, v0, v4
 ; GFX11TRUE16-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11FAKE16-LABEL: v_copysign_out_v2bf16_mag_v2bf16_sign_v2f64:
 ; GFX11FAKE16:       ; %bb.0:
 ; GFX11FAKE16-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11FAKE16-NEXT:    v_perm_b32 v1, v4, v2, 0x5040100
+; GFX11FAKE16-NEXT:    v_perm_b32 v1, v4, v2, 0x7060302
 ; GFX11FAKE16-NEXT:    s_delay_alu instid0(VALU_DEP_1)
 ; GFX11FAKE16-NEXT:    v_bfi_b32 v0, 0x7fff7fff, v0, v1
 ; GFX11FAKE16-NEXT:    s_setpc_b64 s[30:31]
@@ -4802,19 +4801,20 @@ define amdgpu_ps i32 @s_copysign_out_v2bf16_mag_v2bf16_sign_v2f64(<2 x bfloat> i
 ;
 ; GFX8-LABEL: s_copysign_out_v2bf16_mag_v2bf16_sign_v2f64:
 ; GFX8:       ; %bb.0:
-; GFX8-NEXT:    s_lshl_b32 s1, s4, 16
-; GFX8-NEXT:    s_and_b32 s2, s2, 0x8000
-; GFX8-NEXT:    s_or_b32 s1, s2, s1
-; GFX8-NEXT:    s_mov_b32 s2, 0x7fff7fff
+; GFX8-NEXT:    s_lshr_b32 s3, s4, 16
+; GFX8-NEXT:    s_lshr_b64 s[2:3], s[2:3], 16
+; GFX8-NEXT:    s_mov_b32 s1, 0x7fff7fff
 ; GFX8-NEXT:    v_mov_b32_e32 v0, s0
-; GFX8-NEXT:    v_mov_b32_e32 v1, s1
-; GFX8-NEXT:    v_bfi_b32 v0, s2, v0, v1
+; GFX8-NEXT:    v_mov_b32_e32 v1, s2
+; GFX8-NEXT:    v_bfi_b32 v0, s1, v0, v1
 ; GFX8-NEXT:    v_readfirstlane_b32 s0, v0
 ; GFX8-NEXT:    ; return to shader part epilog
 ;
 ; GFX9-LABEL: s_copysign_out_v2bf16_mag_v2bf16_sign_v2f64:
 ; GFX9:       ; %bb.0:
-; GFX9-NEXT:    s_pack_ll_b32_b16 s1, s2, s4
+; GFX9-NEXT:    s_lshr_b32 s1, s4, 16
+; GFX9-NEXT:    s_lshr_b32 s2, s2, 16
+; GFX9-NEXT:    s_pack_ll_b32_b16 s1, s2, s1
 ; GFX9-NEXT:    s_mov_b32 s2, 0x7fff7fff
 ; GFX9-NEXT:    v_mov_b32_e32 v0, s0
 ; GFX9-NEXT:    v_mov_b32_e32 v1, s1
@@ -4824,7 +4824,9 @@ define amdgpu_ps i32 @s_copysign_out_v2bf16_mag_v2bf16_sign_v2f64(<2 x bfloat> i
 ;
 ; GFX10-LABEL: s_copysign_out_v2bf16_mag_v2bf16_sign_v2f64:
 ; GFX10:       ; %bb.0:
-; GFX10-NEXT:    s_pack_ll_b32_b16 s1, s2, s4
+; GFX10-NEXT:    s_lshr_b32 s1, s4, 16
+; GFX10-NEXT:    s_lshr_b32 s2, s2, 16
+; GFX10-NEXT:    s_pack_ll_b32_b16 s1, s2, s1
 ; GFX10-NEXT:    v_mov_b32_e32 v0, s1
 ; GFX10-NEXT:    v_bfi_b32 v0, 0x7fff7fff, s0, v0
 ; GFX10-NEXT:    v_readfirstlane_b32 s0, v0
@@ -4832,11 +4834,13 @@ define amdgpu_ps i32 @s_copysign_out_v2bf16_mag_v2bf16_sign_v2f64(<2 x bfloat> i
 ;
 ; GFX11-LABEL: s_copysign_out_v2bf16_mag_v2bf16_sign_v2f64:
 ; GFX11:       ; %bb.0:
-; GFX11-NEXT:    s_pack_ll_b32_b16 s1, s2, s4
-; GFX11-NEXT:    s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT:    s_lshr_b32 s1, s4, 16
+; GFX11-NEXT:    s_lshr_b32 s2, s2, 16
+; GFX11-NEXT:    s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)
+; GFX11-NEXT:    s_pack_ll_b32_b16 s1, s2, s1
 ; GFX11-NEXT:    v_mov_b32_e32 v0, s1
+; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
 ; GFX11-NEXT:    v_bfi_b32 v0, 0x7fff7fff, s0, v0
-; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_1)
 ; GFX11-NEXT:    v_readfirstlane_b32 s0, v0
 ; GFX11-NEXT:    ; return to shader part epilog
   %sign.trunc = fptrunc <2 x double> %sign to <2 x bfloat>
@@ -7152,21 +7156,18 @@ define <4 x bfloat> @v_copysign_out_v4bf16_mag_v4bf16_sign_v4f64(<4 x bfloat> %m
 ; GFX8-LABEL: v_copysign_out_v4bf16_mag_v4bf16_sign_v4f64:
 ; GFX8:       ; %bb.0:
 ; GFX8-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX8-NEXT:    v_lshlrev_b32_e32 v2, 16, v5
-; GFX8-NEXT:    v_and_b32_e32 v3, 0x8000, v3
-; GFX8-NEXT:    v_or_b32_e32 v2, v3, v2
-; GFX8-NEXT:    s_mov_b32 s4, 0x7fff7fff
-; GFX8-NEXT:    v_bfi_b32 v0, s4, v0, v2
-; GFX8-NEXT:    v_lshlrev_b32_e32 v2, 16, v9
-; GFX8-NEXT:    v_and_b32_e32 v3, 0x8000, v7
-; GFX8-NEXT:    v_or_b32_e32 v2, v3, v2
-; GFX8-NEXT:    v_bfi_b32 v1, s4, v1, v2
+; GFX8-NEXT:    s_mov_b32 s4, 0x3020706
+; GFX8-NEXT:    v_perm_b32 v2, v3, v5, s4
+; GFX8-NEXT:    s_mov_b32 s5, 0x7fff7fff
+; GFX8-NEXT:    v_bfi_b32 v0, s5, v0, v2
+; GFX8-NEXT:    v_perm_b32 v2, v7, v9, s4
+; GFX8-NEXT:    v_bfi_b32 v1, s5, v1, v2
 ; GFX8-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX9-LABEL: v_copysign_out_v4bf16_mag_v4bf16_sign_v4f64:
 ; GFX9:       ; %bb.0:
 ; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT:    s_mov_b32 s4, 0x5040100
+; GFX9-NEXT:    s_mov_b32 s4, 0x7060302
 ; GFX9-NEXT:    v_perm_b32 v2, v5, v3, s4
 ; GFX9-NEXT:    s_mov_b32 s5, 0x7fff7fff
 ; GFX9-NEXT:    v_bfi_b32 v0, s5, v0, v2
@@ -7177,8 +7178,8 @@ define <4 x bfloat> @v_copysign_out_v4bf16_mag_v4bf16_sign_v4f64(<4 x bfloat> %m
 ; GFX10-LABEL: v_copysign_out_v4bf16_mag_v4bf16_sign_v4f64:
 ; GFX10:       ; %bb.0:
 ; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX10-NEXT:    v_perm_b32 v2, v5, v3, 0x5040100
-; GFX10-NEXT:    v_perm_b32 v3, v9, v7, 0x5040100
+; GFX10-NEXT:    v_perm_b32 v2, v5, v3, 0x7060302
+; GFX10-NEXT:    v_perm_b32 v3, v9, v7, 0x7060302
 ; GFX10-NEXT:    v_bfi_b32 v0, 0x7fff7fff, v0, v2
 ; GFX10-NEXT:    v_bfi_b32 v1, 0x7fff7fff, v1, v3
 ; GFX10-NEXT:    s_setpc_b64 s[30:31]
@@ -7186,18 +7187,18 @@ define <4 x bfloat> @v_copysign_out_v4bf16_mag_v4bf16_sign_v4f64(<4 x bfloat> %m
 ; GFX11TRUE16-LABEL: v_copysign_out_v4bf16_mag_v4bf16_sign_v4f64:
 ; GFX11TRUE16:       ; %bb.0:
 ; GFX11TRUE16-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11TRUE16-NEXT:    v_mov_b16_e32 v3.h, v5.l
-; GFX11TRUE16-NEXT:    v_mov_b16_e32 v7.h, v9.l
+; GFX11TRUE16-NEXT:    v_mov_b16_e32 v5.l, v3.h
+; GFX11TRUE16-NEXT:    v_mov_b16_e32 v9.l, v7.h
 ; GFX11TRUE16-NEXT:    s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
-; GFX11TRUE16-NEXT:    v_bfi_b32 v0, 0x7fff7fff, v0, v3
-; GFX11TRUE16-NEXT:    v_bfi_b32 v1, 0x7fff7fff, v1, v7
+; GFX11TRUE16-NEXT:    v_bfi_b32 v0, 0x7fff7fff, v0, v5
+; GFX11TRUE16-NEXT:    v_bfi_b32 v1, 0x7fff7fff, v1, v9
 ; GFX11TRUE16-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11FAKE16-LABEL: v_copysign_out_v4bf16_mag_v4bf16_sign_v4f64:
 ; GFX11FAKE16:       ; %bb.0:
 ; GFX11FAKE16-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11FAKE16-NEXT:    v_perm_b32 v2, v5, v3, 0x5040100
-; GFX11FAKE16-NEXT:    v_perm_b32 v3, v9, v7, 0x5040100
+; GFX11FAKE16-NEXT:    v_perm_b32 v2, v5, v3, 0x7060302
+; GFX11FAKE16-NEXT:    v_perm_b32 v3, v9, v7, 0x7060302
 ; GFX11FAKE16-NEXT:    s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
 ; GFX11FAKE16-NEXT:    v_bfi_b32 v0, 0x7fff7fff, v0, v2
 ; GFX11FAKE16-NEXT:    v_bfi_b32 v1, 0x7fff7fff, v1, v3
@@ -7934,9 +7935,9 @@ define amdgpu_ps i32 @s_copysign_v2bf16_0_v2f64(<2 x double> inreg %sign) {
 ;
 ; GFX8-LABEL: s_copysign_v2bf16_0_v2f64:
 ; GFX8:       ; %bb.0:
-; GFX8-NEXT:    s_lshl_b32 s0, s3, 16
-; GFX8-NEXT:    s_and_b32 s1, s1, 0x8000
-; GFX8-NEXT:    s_or_b32 s0, s1, s0
+; GFX8-NEXT:    s_mov_b32 s0, s1
+; GFX8-NEXT:    s_lshr_b32 s1, s3, 16
+; GFX8-NEXT:    s_lshr_b64 s[0:1], s[0:1], 16
 ; GFX8-NEXT:    s_mov_b32 s1, 0x7fff7fff
 ; GFX8-NEXT:    v_mov_b32_e32 v0, s0
 ; GFX8-NEXT:    v_bfi_b32 v0, s1, 0, v0
@@ -7945,20 +7946,26 @@ define amdgpu_ps i32 @s_copysign_v2bf16_0_v2f64(<2 x double> inreg %sign) {
 ;
 ; GFX9-LABEL: s_copysign_v2bf16_0_v2f64:
 ; GFX9:       ; %bb.0:
-; GFX9-NEXT:    s_pack_ll_b32_b16 s0, s1, s3
+; GFX9-NEXT:    s_lshr_b32 s0, s3, 16
+; GFX9-NEXT:    s_lshr_b32 s1, s1, 16
+; GFX9-NEXT:    s_pack_ll_b32_b16 s0, s1, s0
 ; GFX9-NEXT:    s_and_b32 s0, 0x80008000, s0
 ; GFX9-NEXT:    ; return to shader part epilog
 ;
 ; GFX10-LABEL: s_copysign_v2bf16_0_v2f64:
 ; GFX10:       ; %bb.0:
-; GFX10-NEXT:    s_pack_ll_b32_b16 s0, s1, s3
+; GFX10-NEXT:    s_lshr_b32 s0, s3, 16
+; GFX10-NEXT:    s_lshr_b32 s1, s1, 16
+; GFX10-NEXT:    s_pack_ll_b32_b16 s0, s1, s0
 ; GFX10-NEXT:    s_and_b32 s0, 0x80008000, s0
 ; GFX10-NEXT:    ; return to shader part epilog
 ;
 ; GFX11-LABEL: s_copysign_v2bf16_0_v2f64:
 ; GFX11:       ; %bb.0:
-; GFX11-NEXT:    s_pack_ll_b32_b16 s0, s1, s3
-; GFX11-NEXT:    s_delay_alu instid0(SALU_CYCLE_1)
+; GFX11-NEXT:    s_lshr_b32 s0, s3, 16
+; GFX11-NEXT:    s_lshr_b32 s1, s1, 16
+; GFX11-NEXT:    s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)
+; GFX11-NEXT:    s_pack_ll_b32_b16 s0, s1, s0
 ; GFX11-NEXT:    s_and_b32 s0, 0x80008000, s0
 ; GFX11-NEXT:    ; return to shader part epilog
   %sign.trunc = fptrunc <2 x double> %sign to <2 x bfloat>
@@ -7989,9 +7996,8 @@ define <2 x bfloat> @v_copysign_v2bf16_0_v2bf64(<2 x double> %sign) {
 ; GFX8-LABEL: v_copysign_v2bf16_0_v2bf64:
 ; GFX8:       ; %bb.0:
 ; GFX8-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX8-NEXT:    v_lshlrev_b32_e32 v0, 16, v3
-; GFX8-NEXT:    v_and_b32_e32 v1, 0x8000, v1
-; GFX8-NEXT:    v_or_b32_e32 v0, v1, v0
+; GFX8-NEXT:    s_mov_b32 s4, 0x3020706
+; GFX8-NEXT:    v_perm_b32 v0, v1, v3, s4
 ; GFX8-NEXT:    s_mov_b32 s4, 0x7fff7fff
 ; GFX8-NEXT:    v_bfi_b32 v0, s4, 0, v0
 ; GFX8-NEXT:    s_setpc_b64 s[30:31]
@@ -7999,7 +8005,7 @@ define <2 x bfloat> @v_copysign_v2bf16_0_v2bf64(<2 x double> %sign) {
 ; GFX9-LABEL: v_copysign_v2bf16_0_v2bf64:
 ; GFX9:       ; %bb.0:
 ; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT:    s_mov_b32 s4, 0x5040100
+; GFX9-NEXT:    s_mov_b32 s4, 0x7060302
 ; GFX9-NEXT:    v_perm_b32 v0, v3, v1, s4
 ; GFX9-NEXT:    v_and_b32_e32 v0, 0x80008000, v0
 ; GFX9-NEXT:    s_setpc_b64 s[30:31]
@@ -8007,22 +8013,22 @@ define <2 x bfloat> @v_copysign_v2bf16_0_v2bf64(<2 x double> %sign) {
 ; GFX10-LABEL: v_copysign_v2bf16_0_v2bf64:
 ; GFX10:       ; %bb.0:
 ; GFX10-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX10-NEXT:    v_perm_b32 v0, v3, v1, 0x5040100
+; GFX10-NEXT:    v_perm_b32 v0, v3, v1, 0x7060302
 ; GFX10-NEXT:    v_and_b32_e32 v0, 0x80008000, v0
 ; GFX10-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11TRUE16-LABEL: v_copysign_v2bf16_0_v2bf64:
 ; GFX11TRUE16:       ; %bb.0:
 ; GFX11TRUE16-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11TRUE16-NEXT:    v_mov_b16_e32 v1.h, v3.l
+; GFX11TRUE16-NEXT:    v_mov_b16_e32 v3.l, v1.h
 ; GFX11TRUE16-NEXT:    s_delay_alu instid0(VALU_DEP_1)
-; GFX11TRUE16-NEXT:    v_and_b32_e32 v0, 0x80008000, v1
+; GFX11TRUE16-NEXT:    v_and_b32_e32 v0, 0x80008000, v3
 ; GFX11TRUE16-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11FAKE16-LABEL: v_copysign_v2bf16_0_v2bf64:
 ; GFX11FAKE16:       ; %bb.0:
 ; GFX11FAKE16-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11FAKE16-NEXT:    v_perm_b32 v0, v3, v1, 0x5040100
+; GFX11FAKE16-NEXT:    v_perm_b32 v0, v3, v1, 0x7060302
 ; GFX11FAKE16-NEXT:    s_delay_alu instid0(VALU_DEP_1)
 ; GFX11FAKE16-NEXT:    v_and_b32_e32 v0, 0x80008000, v0
 ; GFX11FAKE16-NEXT:    s_setpc_b64 s[30:31]
diff --git a/llvm/test/CodeGen/AMDGPU/fcopysign.f16.ll b/llvm/test/CodeGen/AMDGPU/fcopysign.f16.ll
index 0ae807783a151..3dace636df09b 100644
--- a/llvm/test/CodeGen/AMDGPU/fcopysign.f16.ll
+++ b/llvm/test/CodeGen/AMDGPU/fcopysign.f16.ll
@@ -3456,9 +3456,8 @@ define <2 x half> @v_copysign_out_v2f16_mag_v2f16_sign_v2f64(<2 x half> %mag, <2
 ; VI-LABEL: v_copysign_out_v2f16_mag_v2f16_sign_v2f64:
 ; VI:       ; %bb.0:
 ; VI-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; VI-NEXT:    v_lshlrev_b32_e32 v1, 16, v4
-; VI-NEXT:    v_and_b32_e32 v2, 0x8000, v2
-; VI-NEXT:    v_or_b32_e32 v1, v2, v1
+; VI-NEXT:    s_mov_b32 s4, 0x3020706
+; VI-NEXT:    v_perm_b32 v1, v2, v4, s4
 ; VI-NEXT:    s_mov_b32 s4, 0x7fff7fff
 ; VI-NEXT:    v_bfi_b32 v0, s4, v0, v1
 ; VI-NEXT:    s_setpc_b64 s[30:31]
@@ -3466,7 +3465,7 @@ define <2 x half> @v_copysign_out_v2f16_mag_v2f16_sign_v2f64(<2 x half> %mag, <2
 ; GFX9-LABEL: v_copysign_out_v2f16_mag_v2f16_sign_v2f64:
 ; GFX9:       ; %bb.0:
 ; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT:    s_mov_b32 s4, 0x5040100
+; GFX9-NEXT:    s_mov_b32 s4, 0x7060302
 ; GFX9-NEXT:    v_perm_b32 v1, v4, v2, s4
 ; GFX9-NEXT:    s_mov_b32 s4, 0x7fff7fff
 ; GFX9-NEXT:    v_bfi_b32 v0, s4, v0, v1
@@ -3475,15 +3474,15 @@ define <2 x half> @v_copysign_out_v2f16_mag_v2f16_sign_v2f64(<2 x half> %mag, <2
 ; GFX11-TRUE16-LABEL: v_copysign_out_v2f16_mag_v2f16_sign_v2f64:
 ; GFX11-TRUE16:       ; %bb.0:
 ; GFX11-TRUE16-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-TRUE16-NEXT:    v_mov_b16_e32 v2.h, v4.l
+; GFX11-TRUE16-NEXT:    v_mov_b16_e32 v4.l, v2.h
 ; GFX11-TRUE16-NEXT:    s_delay_alu instid0(VALU_DEP_1)
-; GFX11-TRUE16-NEXT:    v_bfi_b32 v0, 0x7fff7fff, v0, v2
+; GFX11-TRUE16-NEXT:    v_bfi_b32 v0, 0x7fff7fff, v0, v4
 ; GFX11-TRUE16-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-FAKE16-LABEL: v_copysign_out_v2f16_mag_v2f16_sign_v2f64:
 ; GFX11-FAKE16:       ; %bb.0:
 ; GFX11-FAKE16-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-FAKE16-NEXT:    v_perm_b32 v1, v4, v2, 0x5040100
+; GFX11-FAKE16-NEXT:    v_perm_b32 v1, v4, v2, 0x7060302
 ; GFX11-FAKE16-NEXT:    s_delay_alu instid0(VALU_DEP_1)
 ; GFX11-FAKE16-NEXT:    v_bfi_b32 v0, 0x7fff7fff, v0, v1
 ; GFX11-FAKE16-NEXT:    s_setpc_b64 s[30:31]
@@ -4226,19 +4225,20 @@ define amdgpu_ps i32 @s_copysign_out_v2f16_mag_v2f16_sign_v2f64(<2 x half> inreg
 ;
 ; VI-LABEL: s_copysign_out_v2f16_mag_v2f16_sign_v2f64:
 ; VI:       ; %bb.0:
-; VI-NEXT:    s_lshl_b32 s1, s4, 16
-; VI-NEXT:    s_and_b32 s2, s2, 0x8000
-; VI-NEXT:    s_or_b32 s1, s2, s1
-; VI-NEXT:    s_mov_b32 s2, 0x7fff7fff
+; VI-NEXT:    s_lshr_b32 s3, s4, 16
+; VI-NEXT:    s_lshr_b64 s[2:3], s[2:3], 16
+; VI-NEXT:    s_mov_b32 s1, 0x7fff7fff
 ; VI-NEXT:    v_mov_b32_e32 v0, s0
-; VI-NEXT:    v_mov_b32_e32 v1, s1
-; VI-NEXT:    v_bfi_b32 v0, s2, v0, v1
+; VI-NEXT:    v_mov_b32_e32 v1, s2
+; VI-NEXT:    v_bfi_b32 v0, s1, v0, v1
 ; VI-NEXT:    v_readfirstlane_b32 s0, v0
 ; VI-NEXT:    ; return to shader part epilog
 ;
 ; GFX9-LABEL: s_copysign_out_v2f16_mag_v2f16_sign_v2f64:
 ; GFX9:       ; %bb.0:
-; GFX9-NEXT:    s_pack_ll_b32_b16 s1, s2, s4
+; GFX9-NEXT:    s_lshr_b32 s1, s4, 16
+; GFX9-NEXT:    s_lshr_b32 s2, s2, 16
+; GFX9-NEXT:    s_pack_ll_b32_b16 s1, s2, s1
 ; GFX9-NEXT:    s_mov_b32 s2, 0x7fff7fff
 ; GFX9-NEXT:    v_mov_b32_e32 v0, s0
 ; GFX9-NEXT:    v_mov_b32_e32 v1, s1
@@ -4248,11 +4248,13 @@ define amdgpu_ps i32 @s_copysign_out_v2f16_mag_v2f16_sign_v2f64(<2 x half> inreg
 ;
 ; GFX11-LABEL: s_copysign_out_v2f16_mag_v2f16_sign_v2f64:
 ; GFX11:       ; %bb.0:
-; GFX11-NEXT:    s_pack_ll_b32_b16 s1, s2, s4
-; GFX11-NEXT:    s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(VALU_DEP_1)
+; GFX11-NEXT:    s_lshr_b32 s1, s4, 16
+; GFX11-NEXT:    s_lshr_b32 s2, s2, 16
+; GFX11-NEXT:    s_delay_alu instid0(SALU_CYCLE_1) | instskip(NEXT) | instid1(SALU_CYCLE_1)
+; GFX11-NEXT:    s_pack_ll_b32_b16 s1, s2, s1
 ; GFX11-NEXT:    v_mov_b32_e32 v0, s1
+; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1)
 ; GFX11-NEXT:    v_bfi_b32 v0, 0x7fff7fff, s0, v0
-; GFX11-NEXT:    s_delay_alu instid0(VALU_DEP_1)
 ; GFX11-NEXT:    v_readfirstlane_b32 s0, v0
 ; GFX11-NEXT:    ; return to shader part epilog
   %sign.trunc = fptrunc <2 x double> %sign to <2 x half>
@@ -6576,21 +6578,18 @@ define <4 x half> @v_copysign_out_v4f16_mag_v4f16_sign_v4f64(<4 x half> %mag, <4
 ; VI-LABEL: v_copysign_out_v4f16_mag_v4f16_sign_v4f64:
 ; VI:       ; %bb.0:
 ; VI-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; VI-NEXT:    v_lshlrev_b32_e32 v2, 16, v5
-; VI-NEXT:    v_and_b32_e32 v3, 0x8000, v3
-; VI-NEXT:    v_or_b32_e32 v2, v3, v2
-; VI-NEXT:    s_mov_b32 s4, 0x7fff7fff
-; VI-NEXT:    v_bfi_b32 v0, s4, v0, v2
-; VI-NEXT:    v_lshlrev_b32_e32 v2, 16, v9
-; VI-NEXT:    v_and_b32_e32 v3, 0x8000, v7
-; VI-NEXT:    v_or_b32_e32 v2, v3, v2
-; VI-NEXT:    v_bfi_b32 v1, s4, v1, v2
+; VI-NEXT:    s_mov_b32 s4, 0x3020706
+; VI-NEXT:    v_perm_b32 v2, v3, v5, s4
+; VI-NEXT:    s_mov_b32 s5, 0x7fff7fff
+; VI-NEXT:    v_bfi_b32 v0, s5, v0, v2
+; VI-NEXT:    v_perm_b32 v2, v7, v9, s4
+; VI-NEXT:    v_bfi_b32 v1, s5, v1, v2
 ; VI-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX9-LABEL: v_copysign_out_v4f16_mag_v4f16_sign_v4f64:
 ; GFX9:       ; %bb.0:
 ; GFX9-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX9-NEXT:    s_mov_b32 s4, 0x5040100
+; GFX9-NEXT:    s_mov_b32 s4, 0x7060302
 ; GFX9-NEXT:    v_perm_b32 v2, v5, v3, s4
 ; GFX9-NEXT:    s_mov_b32 s5, 0x7fff7fff
 ; GFX9-NEXT:    v_bfi_b32 v0, s5, v0, v2
@@ -6601,18 +6600,18 @@ define <4 x half> @v_copysign_out_v4f16_mag_v4f16_sign_v4f64(<4 x half> %mag, <4
 ; GFX11-TRUE16-LABEL: v_copysign_out_v4f16_mag_v4f16_sign_v4f64:
 ; GFX11-TRUE16:       ; %bb.0:
 ; GFX11-TRUE16-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-TRUE16-NEXT:    v_mov_b16_e32 v3.h, v5.l
-; GFX11-TRUE16-NEXT:    v_mov_b16_e32 v7.h, v9.l
+; GFX11-TRUE16-NEXT:    v_mov_b16_e32 v5.l, v3.h
+; GFX11-TRUE16-NEXT:    v_mov_b16_e32 v9.l, v7.h
 ; GFX11-TRUE16-NEXT:    s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2)
-; GFX11-TRUE16-NEXT:    v_bfi_b32 v0, 0x7fff7fff, v0, v3
-; GFX11-TRUE16-NEXT:    v_bfi_b32 v1, 0x7fff7fff, v1, v7
+; GFX11-TRUE16-NEXT:    v_bfi_b32 v0, 0x7fff7fff, v0, v5
+; GFX11-TRUE16-NEXT:    v_bfi_b32 v1, 0x7fff7fff, v1, v9
 ; GFX11-TRUE16-NEXT:    s_setpc_b64 s[30:31]
 ;
 ; GFX11-FAKE16-LABEL: v_copysign_out_v4f16_mag_v4f16_sign_v4f64:
 ; GFX11-FAKE16:       ; %bb.0:
 ; GFX11-FAKE16-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
-; GFX11-FAKE16-NEXT:    v_perm_b32 v2, v5, v3, 0x5040100
-; GFX11-FAKE16-NEXT:    v_perm_b32 v3, v9, v7, 0x5040100
+; GFX11-FAKE16-NEXT:    v_perm_b32 v2, v5, v3, 0x7060302
+; GFX11-FAKE16-NEXT:    v_per...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/203492


More information about the llvm-commits mailing list