[AMDGPU] Fix decoding of SETREG MSBs (#187578)

Decoding of the immediate was wrong with non-zero offset
and did not factor MSB fixup offset handling.
This commit is contained in:
Stanislav Mekhanoshin 2026-03-19 14:08:03 -07:00 committed by GitHub
parent 33cfe2843b
commit 59bc629bf3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 45 additions and 2 deletions

View File

@ -3618,9 +3618,12 @@ convertSetRegImmToVgprMSBs(unsigned Imm, unsigned Simm16,
auto [HwRegId, Offset, Size] = Hwreg::HwregEncoding::decode(Simm16);
if (HwRegId != Hwreg::ID_MODE ||
(!HasSetregVGPRMSBFixup && (Offset + Size) <= VGPRMSBShift))
(!HasSetregVGPRMSBFixup && (Offset + Size) < VGPRMSBShift))
return {};
Imm = ((Imm >> Offset) & Hwreg::VGPR_MSB_MASK) >> VGPRMSBShift;
// If there is SetregVGPRMSBFixup then Offset is ignored.
if (!HasSetregVGPRMSBFixup)
Imm <<= Offset;
Imm = (Imm & Hwreg::VGPR_MSB_MASK) >> VGPRMSBShift;
if (!HasSetregVGPRMSBFixup)
Imm &= llvm::maskTrailingOnes<unsigned>(Size);
return llvm::rotr<uint8_t>(static_cast<uint8_t>(Imm), /*R=*/2);

View File

@ -315,3 +315,43 @@ body: |
$vgpr512 = V_MOV_B32_e32 $vgpr513, implicit $exec
S_ENDPGM 0
...
# ASM-LABEL: {{^}}multiple_setreg:
# ASM: s_set_vgpr_msb 0x41 ; msbs: dst=1 src0=1 src1=0 src2=0
# ASM: v_mov_b32_e32 v0 /*v256*/, v1 /*v257*/
# ASM: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 0, 4), 0x5005 ; msbs: dst=1 src0=1 src1=0 src2=0
# ASM: v_mov_b32_e32 v0 /*v256*/, v1 /*v257*/
# ASM: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 0, 4), 0x5005 ; msbs: dst=1 src0=1 src1=0 src2=0
# ASM: v_mov_b32_e32 v0 /*v256*/, v1 /*v257*/
# ASM: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 0x5001 ; msbs: dst=1 src0=1 src1=0 src2=0
# ASM: v_mov_b32_e32 v0 /*v256*/, v1 /*v257*/
# DIS-LABEL: <multiple_setreg>:
# DIS: v_mov_b32_e32 v0 /*v256*/, v1 /*v257*/
# DIS: v_mov_b32_e32 v0 /*v256*/, v1 /*v257*/
# DIS: v_mov_b32_e32 v0 /*v256*/, v1 /*v257*/
# DIS: v_mov_b32_e32 v0 /*v256*/, v1 /*v257*/
---
name: multiple_setreg
tracksRegLiveness: true
body: |
bb.0:
; CHECK-LABEL: name: multiple_setreg
; CHECK: S_SET_VGPR_MSB 65, implicit-def $mode
; CHECK-NEXT: $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec
; CHECK-NEXT: S_SETREG_IMM32_B32 20485, 6145, implicit-def $mode, implicit $mode
; CHECK-NEXT: $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec
; CHECK-NEXT: S_SETREG_IMM32_B32 20485, 6145, implicit-def $mode, implicit $mode
; CHECK-NEXT: $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec
; CHECK-NEXT: S_SETREG_IMM32_B32 20481, 1601, implicit-def $mode, implicit $mode
; CHECK-NEXT: $vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec
; CHECK-NEXT: S_ENDPGM 0
$vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec
S_SETREG_IMM32_B32 5, 6145, implicit-def $mode, implicit $mode
$vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec
S_SETREG_IMM32_B32 5, 6145, implicit-def $mode, implicit $mode
$vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec
S_SETREG_IMM32_B32 1, 1601, implicit-def $mode, implicit $mode
$vgpr256 = V_MOV_B32_e32 $vgpr257, implicit $exec
S_ENDPGM 0
...