Skip to content

Commit f16d872

Browse files
authored
[AMDGPU] Add asm comments if setreg changes MSBs (#185774)
1 parent 925566e commit f16d872

File tree

5 files changed

+86
-6
lines changed

5 files changed

+86
-6
lines changed

llvm/lib/Target/AMDGPU/AMDGPUMCInstLower.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -436,11 +436,19 @@ void AMDGPUAsmPrinter::emitInstruction(const MachineInstr *MI) {
436436
MF->getInfo<SIMachineFunctionInfo>(),
437437
*OutStreamer);
438438

439-
if (isVerbose() && MI->getOpcode() == AMDGPU::S_SET_VGPR_MSB) {
440-
unsigned V = MI->getOperand(0).getImm() & 0xff;
441-
OutStreamer->AddComment(
442-
" msbs: dst=" + Twine(V >> 6) + " src0=" + Twine(V & 3) +
443-
" src1=" + Twine((V >> 2) & 3) + " src2=" + Twine((V >> 4) & 3));
439+
if (isVerbose() && (MI->getOpcode() == AMDGPU::S_SET_VGPR_MSB ||
440+
(MI->getOpcode() == AMDGPU::S_SETREG_IMM32_B32 &&
441+
STI.has1024AddressableVGPRs()))) {
442+
std::optional<unsigned> V;
443+
if (MI->getOpcode() == AMDGPU::S_SETREG_IMM32_B32)
444+
V = AMDGPU::convertSetRegImmToVgprMSBs(*MI,
445+
STI.hasSetregVGPRMSBFixup());
446+
else
447+
V = MI->getOperand(0).getImm() & 0xff;
448+
if (V.has_value())
449+
OutStreamer->AddComment(
450+
" msbs: dst=" + Twine(*V >> 6) + " src0=" + Twine(*V & 3) +
451+
" src1=" + Twine((*V >> 2) & 3) + " src2=" + Twine((*V >> 4) & 3));
444452
}
445453

446454
MCInst TmpInst;

llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3589,6 +3589,25 @@ MCRegister getVGPRWithMSBs(MCRegister Reg, unsigned MSBs,
35893589
return RC->getRegister(Idx);
35903590
}
35913591

3592+
std::optional<unsigned> convertSetRegImmToVgprMSBs(const MachineInstr &MI,
3593+
bool HasSetregVGPRMSBFixup) {
3594+
assert(MI.getOpcode() == AMDGPU::S_SETREG_IMM32_B32);
3595+
3596+
constexpr unsigned VGPRMSBShift =
3597+
llvm::countr_zero_constexpr<unsigned>(AMDGPU::Hwreg::DST_VGPR_MSB);
3598+
3599+
auto [HwRegId, Offset, Size] =
3600+
Hwreg::HwregEncoding::decode(MI.getOperand(1).getImm());
3601+
if (HwRegId != Hwreg::ID_MODE ||
3602+
(!HasSetregVGPRMSBFixup && (Offset + Size) <= VGPRMSBShift))
3603+
return {};
3604+
unsigned Imm = MI.getOperand(0).getImm();
3605+
Imm = ((Imm >> Offset) & Hwreg::VGPR_MSB_MASK) >> VGPRMSBShift;
3606+
if (!HasSetregVGPRMSBFixup)
3607+
Imm &= llvm::maskTrailingOnes<unsigned>(Size);
3608+
return llvm::rotr<uint8_t>(static_cast<uint8_t>(Imm), /*R=*/2);
3609+
}
3610+
35923611
std::pair<const AMDGPU::OpName *, const AMDGPU::OpName *>
35933612
getVGPRLoweringOperandTables(const MCInstrDesc &Desc) {
35943613
static const AMDGPU::OpName VOPOps[4] = {

llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ struct Align;
3131
class Argument;
3232
class Function;
3333
class GlobalValue;
34+
class MachineInstr;
3435
class MCInstrInfo;
3536
class MCRegisterClass;
3637
class MCRegisterInfo;
@@ -1990,6 +1991,12 @@ unsigned getVGPREncodingMSBs(MCRegister Reg, const MCRegisterInfo &MRI);
19901991
MCRegister getVGPRWithMSBs(MCRegister Reg, unsigned MSBs,
19911992
const MCRegisterInfo &MRI);
19921993

1994+
/// \returns VGPR MSBs encoded in a S_SETREG_IMM32_B32 \p MI if it sets
1995+
/// it. If \p HasSetregVGPRMSBFixup is true then size of the ID_MODE mask is
1996+
/// ignored.
1997+
std::optional<unsigned> convertSetRegImmToVgprMSBs(const MachineInstr &MI,
1998+
bool HasSetregVGPRMSBFixup);
1999+
19932000
// Returns a table for the opcode with a given \p Desc to map the VGPR MSB
19942001
// set by the S_SET_VGPR_MSB to one of 4 sources. In case of VOPD returns 2
19952002
// maps, one for X and one for Y component.

llvm/test/CodeGen/AMDGPU/code-size-estimate.ll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,8 @@ define amdgpu_ps float @s_fmaak_f32(float inreg %x, float inreg %y) {
581581
;
582582
; GFX1250-LABEL: s_fmaak_f32:
583583
; GFX1250: ; %bb.0:
584-
; GFX1250-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; encoding: [0x41,0x06,0x80,0xb9,0x01,0x00,0x00,0x00]
584+
; GFX1250-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
585+
; GFX1250-NEXT: ; encoding: [0x41,0x06,0x80,0xb9,0x01,0x00,0x00,0x00]
585586
; GFX1250-NEXT: s_fmaak_f32 s0, s0, s1, 0x43800000 ; encoding: [0x00,0x01,0x80,0xa2,0x00,0x00,0x80,0x43]
586587
; GFX1250-NEXT: s_delay_alu instid0(SALU_CYCLE_3) ; encoding: [0x0b,0x00,0x87,0xbf]
587588
; GFX1250-NEXT: v_mov_b32_e32 v0, s0 ; encoding: [0x00,0x02,0x00,0x7e]

llvm/test/CodeGen/AMDGPU/vgpr-setreg-mode-swar.mir

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
22
# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1250 -run-pass=amdgpu-lower-vgpr-encoding -o - %s | FileCheck %s
3+
# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1250 -start-before=amdgpu-lower-vgpr-encoding -o - %s | FileCheck --check-prefix=ASM %s
34

45
---
56
# Case 1a: Size < 12 (size=4), imm32[12:19]=0
@@ -8,6 +9,10 @@
89
# vgpr256/257 (both MSB=1): S_SET_VGPR_MSB mode = (1 << 0) | (1 << 6) = 65
910
# Setreg (Size=4 <= 12) resets the mode scope and clears bits[12:19] to 0.
1011
# No VGPR instruction follows, so bits[12:19] remain 0. Setreg imm = 5.
12+
13+
# ASM-LABEL: {{^}}setreg_size_lt_12:
14+
# ASM: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 0, 4), 5 ; msbs: dst=0 src0=0 src1=0 src2=0
15+
1116
name: setreg_size_lt_12
1217
tracksRegLiveness: true
1318
body: |
@@ -27,6 +32,10 @@ body: |
2732
# Case 1b: Size == 12 (boundary), imm32[12:19]=0
2833
# Setreg (Size=12 <= 12) resets the mode scope and clears bits[12:19] to 0.
2934
# No VGPR instruction follows, so bits[12:19] remain 0. Setreg imm = 0xABC = 2748.
35+
36+
# ASM-LABEL: {{^}}setreg_size_eq_12:
37+
# ASM: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 0, 12), 0xabc ; msbs: dst=0 src0=0 src1=0 src2=0
38+
3039
name: setreg_size_eq_12
3140
tracksRegLiveness: true
3241
body: |
@@ -46,6 +55,10 @@ body: |
4655
# Case 1c: Size <= 12 with existing non-zero bits in imm32[12:19]
4756
# imm32 = 0x23005 (bits 12:19 = 0x23). Setreg resets mode scope and clears
4857
# bits[12:19] to 0. No VGPR instruction follows, so result = 0x00005 = 5.
58+
59+
# ASM-LABEL: {{^}}setreg_size_lt_12_nonzero_upper:
60+
# ASM: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 0, 4), 5 ; msbs: dst=0 src0=0 src1=0 src2=0
61+
4962
name: setreg_size_lt_12_nonzero_upper
5063
tracksRegLiveness: true
5164
body: |
@@ -66,6 +79,10 @@ body: |
6679
# Case 2: Size > 12 (size=16), imm32[12:19] already matches VGPR MSBs
6780
# vgpr256/257: S_SET_VGPR_MSB mode = 65, MODE register mode = 5
6881
# imm32 = 0x5ABC = 23228 (bits 12:19 = 5), no modification needed
82+
83+
# ASM-LABEL: {{^}}setreg_size_gt_12_match:
84+
# ASM: _setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 0, 16), 0x5abc ; msbs: dst=1 src0=1 src1=0 src2=0
85+
6986
name: setreg_size_gt_12_match
7087
tracksRegLiveness: true
7188
body: |
@@ -86,6 +103,10 @@ body: |
86103
# Case 3: Size > 12 (size=16), imm32[12:19] doesn't match VGPR MSBs
87104
# vgpr256/257: S_SET_VGPR_MSB mode = 65, MODE register mode = 5
88105
# imm32 = 0x23ABC = 146108 (bits 12:19 = 0x23 != 5), must insert s_set_vgpr_msb after
106+
107+
# ASM-LABEL: {{^}}setreg_size_gt_12_mismatch:
108+
# ASM: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 0, 16), 0x23abc ; msbs: dst=3 src0=0 src1=2 src2=0
109+
89110
name: setreg_size_gt_12_mismatch
90111
tracksRegLiveness: true
91112
body: |
@@ -108,6 +129,10 @@ body: |
108129
# Case 4: Non-MODE hwreg should not be modified
109130
# This uses ID_STATUS=2 instead of ID_MODE=1
110131
# vgpr256/257: S_SET_VGPR_MSB mode = 65
132+
133+
# ASM-LABEL: {{^}}setreg_non_mode_hwreg:
134+
# ASM: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_STATUS, 0, 4), 5{{$}}
135+
111136
name: setreg_non_mode_hwreg
112137
tracksRegLiveness: true
113138
body: |
@@ -127,6 +152,10 @@ body: |
127152
# Case 5: Size <= 12 with VGPR MSBs already present in imm32[12:19]
128153
# imm32 = 0x5005 = 20485 (bits 12:19 = 5). Setreg resets mode scope and clears
129154
# bits[12:19] to 0, regardless of prior content. Result = 5.
155+
156+
# ASM-LABEL: {{^}}setreg_size_lt_12_already_correct:
157+
# ASM: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 0, 4), 5 ; msbs: dst=0 src0=0 src1=0 src2=0
158+
130159
name: setreg_size_lt_12_already_correct
131160
tracksRegLiveness: true
132161
body: |
@@ -147,6 +176,10 @@ body: |
147176
# Case 6: Different VGPR MSB value (using different high VGPRs)
148177
# vgpr512/513 (both MSB=2): S_SET_VGPR_MSB mode = (2 << 0) | (2 << 6) = 130
149178
# Setreg resets mode scope and clears bits[12:19] to 0. No VGPR follows. Result = 5.
179+
180+
# ASM-LABEL: {{^}}setreg_different_vgpr_msb:
181+
# ASM: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 0, 4), 5 ; msbs: dst=0 src0=0 src1=0 src2=0
182+
150183
name: setreg_different_vgpr_msb
151184
tracksRegLiveness: true
152185
body: |
@@ -170,6 +203,10 @@ body: |
170203
# MODE register mode = (1 << 0) | (1 << 2) | (2 << 4) = 37 (dst=1, src0=1, src1=2)
171204
# Piggybacking updates setreg imm32[12:19] from 0 to 37.
172205
# Final setreg imm = 5 | (37 << 12) = 151557
206+
207+
# ASM-LABEL: {{^}}setreg_size_le_12_piggyback_superset:
208+
# ASM: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 0, 4), 0x25005 ; msbs: dst=1 src0=1 src1=2 src2=0
209+
173210
name: setreg_size_le_12_piggyback_superset
174211
tracksRegLiveness: true
175212
body: |
@@ -195,6 +232,10 @@ body: |
195232
# The setreg (Size=4 <= 12) resets the mode scope. Its bits[12:19] are cleared to 0.
196233
# The second VGPR's setMode piggybacks mode = 65 into the setreg's bits[12:19],
197234
# giving imm32 = 5 | (5 << 12) = 20485 = 0x5005. No separate S_SET_VGPR_MSB needed.
235+
236+
# ASM-LABEL: {{^}}setreg_size_le_12_then_different_vgpr:
237+
# ASM: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 0, 4), 0x5005 ; msbs: dst=1 src0=1 src1=0 src2=0
238+
198239
name: setreg_size_le_12_then_different_vgpr
199240
tracksRegLiveness: true
200241
body: |
@@ -224,6 +265,10 @@ body: |
224265
# Second VGPR (vgpr512/513): S_SET_VGPR_MSB mode = 130, MODE register mode = 10
225266
# Since MostRecentModeSet = nullptr, a new s_set_vgpr_msb is inserted.
226267
# New s_set_vgpr_msb imm = NewMode | (OldMode << 8) = 130 | (65 << 8) = 16770
268+
269+
# ASM-LABEL: {{^}}setreg_size_gt_12_match_then_different_vgpr:
270+
# ASM: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 0, 16), 0x5abc ; msbs: dst=1 src0=1 src1=0 src2=0
271+
227272
name: setreg_size_gt_12_match_then_different_vgpr
228273
tracksRegLiveness: true
229274
body: |

0 commit comments

Comments
 (0)