Skip to content

Commit 78d8ce3

Browse files
authored
[AMDGPU] Require explicit immediate offsets for SGPR+IMM SMEM instructions. (#79131)
As otherwise SGPR+IMM instructions are not distinguishable to SGPR-only ones in AsmParser, leading to ambiguities. GFX12 doesn't have special SGPR-only variants, so we still allow optional immediate offsets for the subtarget. Also rename the offset operand classes while there. Part of <#69256>.
1 parent cfddb59 commit 78d8ce3

File tree

2 files changed

+32
-23
lines changed

2 files changed

+32
-23
lines changed

llvm/lib/Target/AMDGPU/SIInstrInfo.td

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -994,9 +994,9 @@ def SDWAVopcDst : BoolRC {
994994
let PrintMethod = "printVOPDst";
995995
}
996996

997-
class NamedIntOperand<ValueType Type, string Prefix, string Name = NAME,
998-
string ConvertMethod = "nullptr">
999-
: CustomOperand<Type, 1, Name> {
997+
class NamedIntOperand<ValueType Type, string Prefix, bit Optional = 1,
998+
string Name = NAME, string ConvertMethod = "nullptr">
999+
: CustomOperand<Type, Optional, Name> {
10001000
let ParserMethod =
10011001
"[this](OperandVector &Operands) -> ParseStatus { "#
10021002
"return parseIntWithPrefix(\""#Prefix#"\", Operands, "#
@@ -1039,9 +1039,9 @@ class ArrayOperand0<string Id, string Name = NAME>
10391039

10401040
let ImmTy = "ImmTyOffset" in
10411041
def flat_offset : CustomOperand<i32, 1, "FlatOffset">;
1042-
def offset : NamedIntOperand<i32, "offset", "Offset">;
1043-
def offset0 : NamedIntOperand<i8, "offset0", "Offset0">;
1044-
def offset1 : NamedIntOperand<i8, "offset1", "Offset1">;
1042+
def offset : NamedIntOperand<i32, "offset", 1, "Offset">;
1043+
def offset0 : NamedIntOperand<i8, "offset0", 1, "Offset0">;
1044+
def offset1 : NamedIntOperand<i8, "offset1", 1, "Offset1">;
10451045

10461046
def gds : NamedBitOperand<"gds", "GDS">;
10471047

@@ -1092,25 +1092,25 @@ def dpp8 : CustomOperand<i32, 0, "DPP8">;
10921092
def dpp_ctrl : CustomOperand<i32, 0, "DPPCtrl">;
10931093

10941094
let DefaultValue = "0xf" in {
1095-
def row_mask : NamedIntOperand<i32, "row_mask", "DppRowMask">;
1096-
def bank_mask : NamedIntOperand<i32, "bank_mask", "DppBankMask">;
1095+
def row_mask : NamedIntOperand<i32, "row_mask", 1, "DppRowMask">;
1096+
def bank_mask : NamedIntOperand<i32, "bank_mask", 1, "DppBankMask">;
10971097
}
1098-
def bound_ctrl : NamedIntOperand<i1, "bound_ctrl", "DppBoundCtrl",
1098+
def bound_ctrl : NamedIntOperand<i1, "bound_ctrl", 1, "DppBoundCtrl",
10991099
"[this] (int64_t &BC) -> bool { return convertDppBoundCtrl(BC); }">;
1100-
def FI : NamedIntOperand<i32, "fi", "DppFI">;
1100+
def FI : NamedIntOperand<i32, "fi", 1, "DppFI">;
11011101

11021102
def blgp : CustomOperand<i32, 1, "BLGP">;
1103-
def cbsz : NamedIntOperand<i32, "cbsz", "CBSZ">;
1104-
def abid : NamedIntOperand<i32, "abid", "ABID">;
1103+
def cbsz : NamedIntOperand<i32, "cbsz", 1, "CBSZ">;
1104+
def abid : NamedIntOperand<i32, "abid", 1, "ABID">;
11051105

11061106
def hwreg : CustomOperand<i32, 0, "Hwreg">;
11071107

11081108
def exp_tgt : CustomOperand<i32, 0, "ExpTgt">;
11091109

1110-
def wait_vdst : NamedIntOperand<i8, "wait_vdst", "WaitVDST">;
1111-
def wait_exp : NamedIntOperand<i8, "wait_exp", "WaitEXP">;
1112-
def wait_va_vdst : NamedIntOperand<i8, "wait_va_vdst", "WaitVAVDst">;
1113-
def wait_va_vsrc : NamedIntOperand<i8, "wait_vm_vsrc", "WaitVMVSrc">;
1110+
def wait_vdst : NamedIntOperand<i8, "wait_vdst", 1, "WaitVDST">;
1111+
def wait_exp : NamedIntOperand<i8, "wait_exp", 1, "WaitEXP">;
1112+
def wait_va_vdst : NamedIntOperand<i8, "wait_va_vdst", 1, "WaitVAVDst">;
1113+
def wait_va_vsrc : NamedIntOperand<i8, "wait_vm_vsrc", 1, "WaitVMVSrc">;
11141114

11151115
class KImmFPOperand<ValueType vt> : ImmOperand<vt> {
11161116
let OperandNamespace = "AMDGPU";

llvm/lib/Target/AMDGPU/SMInstructions.td

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,13 @@ def smrd_offset_8 : ImmOperand<i32, "SMRDOffset8", 1>;
1010

1111
let EncoderMethod = "getSMEMOffsetEncoding",
1212
DecoderMethod = "decodeSMEMOffset" in {
13-
def smem_offset : ImmOperand<i32, "SMEMOffset", 1>;
14-
def smem_offset_mod : NamedIntOperand<i32, "offset", "SMEMOffsetMod">;
13+
def SMEMOffset : ImmOperand<i32, "SMEMOffset", 1>;
14+
def SMEMOffsetMod : NamedIntOperand<i32, "offset", 0>;
15+
def OptSMEMOffsetMod : NamedIntOperand<i32, "offset"> {
16+
let ImmTy = SMEMOffsetMod.ImmTy;
17+
let PredicateMethod = SMEMOffsetMod.PredicateMethod;
18+
let PrintMethod = SMEMOffsetMod.PrintMethod;
19+
}
1520
}
1621

1722
//===----------------------------------------------------------------------===//
@@ -87,11 +92,14 @@ class OffsetMode<bit hasOffset, bit hasSOffset, string variant,
8792
string Asm = asm;
8893
}
8994

90-
def IMM_Offset : OffsetMode<1, 0, "_IMM", (ins smem_offset:$offset), "$offset">;
95+
def IMM_Offset : OffsetMode<1, 0, "_IMM", (ins SMEMOffset:$offset), "$offset">;
9196
def SGPR_Offset : OffsetMode<0, 1, "_SGPR", (ins SReg_32:$soffset), "$soffset">;
9297
def SGPR_IMM_Offset : OffsetMode<1, 1, "_SGPR_IMM",
93-
(ins SReg_32:$soffset, smem_offset_mod:$offset),
98+
(ins SReg_32:$soffset, SMEMOffsetMod:$offset),
9499
"$soffset$offset">;
100+
def SGPR_IMM_OptOffset : OffsetMode<1, 1, "_SGPR_IMM",
101+
(ins SReg_32:$soffset, OptSMEMOffsetMod:$offset),
102+
"$soffset$offset">;
95103

96104
class SM_Probe_Pseudo <string opName, RegisterClass baseClass, OffsetMode offsets>
97105
: SM_Pseudo<opName, (outs),
@@ -201,6 +209,7 @@ multiclass SM_Pseudo_Probe<RegisterClass baseClass> {
201209
def _IMM : SM_Probe_Pseudo <opName, baseClass, IMM_Offset>;
202210
def _SGPR : SM_Probe_Pseudo <opName, baseClass, SGPR_Offset>;
203211
def _SGPR_IMM : SM_Probe_Pseudo <opName, baseClass, SGPR_IMM_Offset>;
212+
def _SGPR_OPT_IMM : SM_Probe_Pseudo <opName, baseClass, SGPR_IMM_OptOffset>;
204213
}
205214

206215
class SM_WaveId_Pseudo<string opName, SDPatternOperator node> : SM_Pseudo<
@@ -214,7 +223,7 @@ class SM_WaveId_Pseudo<string opName, SDPatternOperator node> : SM_Pseudo<
214223

215224
class SM_Prefetch_Pseudo <string opName, RegisterClass baseClass, bit hasSBase>
216225
: SM_Pseudo<opName, (outs), !con(!if(hasSBase, (ins baseClass:$sbase), (ins)),
217-
(ins smem_offset:$offset, SReg_32:$soffset, i8imm:$sdata)),
226+
(ins SMEMOffset:$offset, SReg_32:$soffset, i8imm:$sdata)),
218227
!if(hasSBase, " $sbase,", "") # " $offset, $soffset, $sdata"> {
219228
// Mark prefetches as both load and store to prevent reordering with loads
220229
// and stores. This is also needed for pattern to match prefetch intrinsic.
@@ -1410,7 +1419,7 @@ class SMEM_Real_Load_gfx12<bits<6> op, string ps, string opName, OffsetMode offs
14101419
multiclass SM_Real_Loads_gfx12<bits<6> op, string ps = NAME> {
14111420
defvar opName = !tolower(NAME);
14121421
def _IMM_gfx12 : SMEM_Real_Load_gfx12<op, ps, opName, IMM_Offset>;
1413-
def _SGPR_IMM_gfx12 : SMEM_Real_Load_gfx12<op, ps, opName, SGPR_IMM_Offset>;
1422+
def _SGPR_IMM_gfx12 : SMEM_Real_Load_gfx12<op, ps, opName, SGPR_IMM_OptOffset>;
14141423
}
14151424

14161425
defm S_LOAD_B32 : SM_Real_Loads_gfx12<0x00, "S_LOAD_DWORD">;
@@ -1448,7 +1457,7 @@ def S_PREFETCH_DATA_PC_REL_gfx12 : SMEM_Real_Prefetch_gfx12<0x28, S_PREFETCH_DAT
14481457
multiclass SMEM_Real_Probe_gfx12<bits<6> op> {
14491458
defvar ps = NAME;
14501459
def _IMM_gfx12 : SMEM_Real_Prefetch_gfx12<op, !cast<SM_Probe_Pseudo>(ps#_IMM)>;
1451-
def _SGPR_IMM_gfx12 : SMEM_Real_Prefetch_gfx12<op, !cast<SM_Probe_Pseudo>(ps#_SGPR_IMM)>;
1460+
def _SGPR_IMM_gfx12 : SMEM_Real_Prefetch_gfx12<op, !cast<SM_Probe_Pseudo>(ps#_SGPR_OPT_IMM)>;
14521461
}
14531462

14541463
defm S_ATC_PROBE : SMEM_Real_Probe_gfx12<0x22>;

0 commit comments

Comments
 (0)