[llvm] [AMDGPU][GlobalISel] Fix wrong half selection in wave.shuffle lowering (PR #210661)

via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 20 01:34:08 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-amdgpu

Author: Arseniy Obolenskiy (aobolensk)

<details>
<summary>Changes</summary>

selectWaveShuffleIntrin XORed ThreadID with the shifted index instead of the original index, picking the wrong lane half on wave64 targets without wave wide bpermute (GFX10/GFX11)

---
Full diff: https://github.com/llvm/llvm-project/pull/210661.diff


2 Files Affected:

- (modified) llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp (+10-1) 
- (modified) llvm/test/CodeGen/AMDGPU/llvm.amdgcn.wave.shuffle.ll (+7-6) 


``````````diff
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp b/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp
index a2497e5e4189c..32b7507842842 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp
@@ -4167,6 +4167,15 @@ bool AMDGPUInstructionSelector::selectWaveShuffleIntrin(
         .addReg(UndefValReg)
         .addReg(UndefExecReg);
 
+    Register PoisonUnshiftedIdxReg = MRI->createVirtualRegister(DstRC);
+    BuildMI(*MBB, MI, DL, TII.get(AMDGPU::V_SET_INACTIVE_B32),
+            PoisonUnshiftedIdxReg)
+        .addImm(0)
+        .addReg(IdxReg)
+        .addImm(0)
+        .addReg(UndefValReg)
+        .addReg(UndefExecReg);
+
     // Get permutation of each half, then we'll select which one to use
     Register SameSidePermReg = MRI->createVirtualRegister(DstRC);
     BuildMI(*MBB, MI, DL, TII.get(AMDGPU::DS_BPERMUTE_B32), SameSidePermReg)
@@ -4200,7 +4209,7 @@ bool AMDGPUInstructionSelector::selectWaveShuffleIntrin(
     Register XORReg = MRI->createVirtualRegister(DstRC);
     BuildMI(*MBB, MI, DL, TII.get(AMDGPU::V_XOR_B32_e64), XORReg)
         .addReg(ThreadIDReg)
-        .addReg(PoisonIdxReg);
+        .addReg(PoisonUnshiftedIdxReg);
 
     Register ANDReg = MRI->createVirtualRegister(DstRC);
     BuildMI(*MBB, MI, DL, TII.get(AMDGPU::V_AND_B32_e64), ANDReg)
diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.wave.shuffle.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.wave.shuffle.ll
index 818002d566b74..7116f937b6d8a 100644
--- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.wave.shuffle.ll
+++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.wave.shuffle.ll
@@ -187,23 +187,24 @@ define float @test_wave_shuffle_float(float %val, i32 %idx) {
 ; GFX11-W64-GISEL-NEXT:    s_xor_saveexec_b64 s[0:1], -1
 ; GFX11-W64-GISEL-NEXT:    scratch_store_b32 off, v2, s32 ; 4-byte Folded Spill
 ; GFX11-W64-GISEL-NEXT:    s_mov_b64 exec, s[0:1]
-; GFX11-W64-GISEL-NEXT:    v_lshlrev_b32_e32 v1, 2, v1
+; GFX11-W64-GISEL-NEXT:    v_lshlrev_b32_e32 v3, 2, v1
 ; GFX11-W64-GISEL-NEXT:    ; kill: def $vgpr0 killed $vgpr0 killed $exec
-; GFX11-W64-GISEL-NEXT:    ; kill: def $vgpr1 killed $vgpr1 killed $exec
+; GFX11-W64-GISEL-NEXT:    ; kill: def $vgpr3 killed $vgpr3 killed $exec
 ; GFX11-W64-GISEL-NEXT:    s_or_saveexec_b64 s[0:1], -1
 ; GFX11-W64-GISEL-NEXT:    v_permlane64_b32 v2, v0
-; GFX11-W64-GISEL-NEXT:    ds_bpermute_b32 v2, v1, v2
+; GFX11-W64-GISEL-NEXT:    ds_bpermute_b32 v2, v3, v2
 ; GFX11-W64-GISEL-NEXT:    s_mov_b64 exec, s[0:1]
+; GFX11-W64-GISEL-NEXT:    ds_bpermute_b32 v0, v3, v0
 ; GFX11-W64-GISEL-NEXT:    v_mbcnt_lo_u32_b32 v3, -1, 0
-; GFX11-W64-GISEL-NEXT:    ds_bpermute_b32 v0, v1, v0
+; GFX11-W64-GISEL-NEXT:    ; kill: def $vgpr1 killed $vgpr1 killed $exec
+; GFX11-W64-GISEL-NEXT:    s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_2) | instid1(VALU_DEP_2)
 ; GFX11-W64-GISEL-NEXT:    v_xor_b32_e32 v1, v3, v1
 ; GFX11-W64-GISEL-NEXT:    s_waitcnt lgkmcnt(1)
 ; GFX11-W64-GISEL-NEXT:    v_mov_b32_e32 v3, v2
-; GFX11-W64-GISEL-NEXT:    s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_1)
 ; GFX11-W64-GISEL-NEXT:    v_and_b32_e32 v1, 32, v1
+; GFX11-W64-GISEL-NEXT:    s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_1) | instid1(VALU_DEP_3)
 ; GFX11-W64-GISEL-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
 ; GFX11-W64-GISEL-NEXT:    s_waitcnt lgkmcnt(0)
-; GFX11-W64-GISEL-NEXT:    s_delay_alu instid0(VALU_DEP_3)
 ; GFX11-W64-GISEL-NEXT:    v_cndmask_b32_e32 v0, v3, v0, vcc
 ; GFX11-W64-GISEL-NEXT:    s_xor_saveexec_b64 s[0:1], -1
 ; GFX11-W64-GISEL-NEXT:    scratch_load_b32 v2, off, s32 ; 4-byte Folded Reload

``````````

</details>


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


More information about the llvm-commits mailing list