Skip to content

Commit dcc7ef3

Browse files
authored
[AMDGPU][MC] Disable sendmsg SYSMSG_OP_HOST_TRAP_ACK on gfx9+ (#90203)
This is no longer supported as of gfx9. Fixes #52903 This commit also includes some refactoring of sendmsg operand parsing: - Use CustomOperand for sendmsg operations, this allows them to be conditionally available based on a STI check (and automatically in sync with SIDefines.h). - Move CustomOperand table lookups from AMDGPUBaseInfo to AMDGPUAsmUtils. This cleans up an awkward interface where AMDGPUAsmUtils defined a table/size as globals that AMDGPUBaseInfo had to loop over. - Clean up a few of the operand lookup functions while moving them.
1 parent 97dd8e3 commit dcc7ef3

File tree

9 files changed

+150
-165
lines changed

9 files changed

+150
-165
lines changed

llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7436,7 +7436,8 @@ AMDGPUAsmParser::parseSendMsgBody(OperandInfoTy &Msg,
74367436
Op.IsDefined = true;
74377437
Op.Loc = getLoc();
74387438
if (isToken(AsmToken::Identifier) &&
7439-
(Op.Val = getMsgOpId(Msg.Val, getTokenStr())) >= 0) {
7439+
(Op.Val = getMsgOpId(Msg.Val, getTokenStr(), getSTI())) !=
7440+
OPR_ID_UNKNOWN) {
74407441
lex(); // skip operation name
74417442
} else if (!parseExpr(Op.Val, "an operation name")) {
74427443
return false;
@@ -7484,7 +7485,10 @@ AMDGPUAsmParser::validateSendMsg(const OperandInfoTy &Msg,
74847485
return false;
74857486
}
74867487
if (!isValidMsgOp(Msg.Val, Op.Val, getSTI(), Strict)) {
7487-
Error(Op.Loc, "invalid operation id");
7488+
if (Op.Val == OPR_ID_UNSUPPORTED)
7489+
Error(Op.Loc, "specified operation id is not supported on this GPU");
7490+
else
7491+
Error(Op.Loc, "invalid operation id");
74887492
return false;
74897493
}
74907494
if (Strict && !msgSupportsStream(Msg.Val, Op.Val, getSTI()) &&

llvm/lib/Target/AMDGPU/SIDefines.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,6 @@ enum Id { // Message ID, width(4) [3:0].
468468
};
469469

470470
enum Op { // Both GS and SYS operation IDs.
471-
OP_UNKNOWN_ = -1,
472471
OP_SHIFT_ = 4,
473472
OP_NONE_ = 0,
474473
// Bits used for operation encoding
@@ -479,14 +478,12 @@ enum Op { // Both GS and SYS operation IDs.
479478
OP_GS_CUT = 1,
480479
OP_GS_EMIT = 2,
481480
OP_GS_EMIT_CUT = 3,
482-
OP_GS_LAST_,
483481
OP_GS_FIRST_ = OP_GS_NOP,
484482
// SYS operations are encoded in bits 6:4
485483
OP_SYS_ECC_ERR_INTERRUPT = 1,
486484
OP_SYS_REG_RD = 2,
487485
OP_SYS_HOST_TRAP_ACK = 3,
488486
OP_SYS_TTRACE_PC = 4,
489-
OP_SYS_LAST_,
490487
OP_SYS_FIRST_ = OP_SYS_ECC_ERR_INTERRUPT,
491488
};
492489

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

Lines changed: 101 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,60 @@
1212
namespace llvm {
1313
namespace AMDGPU {
1414

15+
//===----------------------------------------------------------------------===//
16+
// Custom Operands.
17+
//
18+
// A table of custom operands shall describe "primary" operand names first
19+
// followed by aliases if any. It is not required but recommended to arrange
20+
// operands so that operand encoding match operand position in the table. This
21+
// will make getNameFromOperandTable() a bit more efficient. Unused slots in the
22+
// table shall have an empty name.
23+
//
24+
//===----------------------------------------------------------------------===//
25+
26+
/// Map from the encoding of a sendmsg/hwreg asm operand to it's name.
27+
template <size_t N>
28+
static StringRef getNameFromOperandTable(const CustomOperand (&Table)[N],
29+
unsigned Encoding,
30+
const MCSubtargetInfo &STI) {
31+
auto isValidIndexForEncoding = [&](size_t Idx) {
32+
return Idx < N && Table[Idx].Encoding == Encoding &&
33+
!Table[Idx].Name.empty() &&
34+
(!Table[Idx].Cond || Table[Idx].Cond(STI));
35+
};
36+
37+
// This is an optimization that should work in most cases. As a side effect,
38+
// it may cause selection of an alias instead of a primary operand name in
39+
// case of sparse tables.
40+
if (isValidIndexForEncoding(Encoding))
41+
return Table[Encoding].Name;
42+
43+
for (size_t Idx = 0; Idx != N; ++Idx)
44+
if (isValidIndexForEncoding(Idx))
45+
return Table[Idx].Name;
46+
47+
return "";
48+
}
49+
50+
/// Map from a symbolic name for a sendmsg/hwreg asm operand to it's encoding.
51+
template <size_t N>
52+
static int64_t getEncodingFromOperandTable(const CustomOperand (&Table)[N],
53+
StringRef Name,
54+
const MCSubtargetInfo &STI) {
55+
int64_t InvalidEncoding = OPR_ID_UNKNOWN;
56+
for (const CustomOperand &Entry : Table) {
57+
if (Entry.Name != Name)
58+
continue;
59+
60+
if (!Entry.Cond || Entry.Cond(STI))
61+
return Entry.Encoding;
62+
63+
InvalidEncoding = OPR_ID_UNSUPPORTED;
64+
}
65+
66+
return InvalidEncoding;
67+
}
68+
1569
namespace DepCtr {
1670

1771
// NOLINTBEGIN
@@ -34,10 +88,11 @@ const int DEP_CTR_SIZE =
3488

3589
namespace SendMsg {
3690

37-
// Disable lint checking for this block since it makes the table unreadable.
91+
// Disable lint checking here since it makes these tables unreadable.
3892
// NOLINTBEGIN
3993
// clang-format off
40-
const CustomOperand<const MCSubtargetInfo &> Msg[] = {
94+
95+
static constexpr CustomOperand MsgOperands[] = {
4196
{{""}},
4297
{{"MSG_INTERRUPT"}, ID_INTERRUPT},
4398
{{"MSG_GS"}, ID_GS_PreGFX11, isNotGFX11Plus},
@@ -63,27 +118,47 @@ const CustomOperand<const MCSubtargetInfo &> Msg[] = {
63118
{{"MSG_RTN_GET_TBA_TO_PC"}, ID_RTN_GET_TBA_TO_PC, isGFX11Plus},
64119
{{"MSG_RTN_GET_SE_AID_ID"}, ID_RTN_GET_SE_AID_ID, isGFX12Plus},
65120
};
121+
122+
static constexpr CustomOperand SysMsgOperands[] = {
123+
{{""}},
124+
{{"SYSMSG_OP_ECC_ERR_INTERRUPT"}, OP_SYS_ECC_ERR_INTERRUPT},
125+
{{"SYSMSG_OP_REG_RD"}, OP_SYS_REG_RD},
126+
{{"SYSMSG_OP_HOST_TRAP_ACK"}, OP_SYS_HOST_TRAP_ACK, isNotGFX9Plus},
127+
{{"SYSMSG_OP_TTRACE_PC"}, OP_SYS_TTRACE_PC},
128+
};
129+
130+
static constexpr CustomOperand StreamMsgOperands[] = {
131+
{{"GS_OP_NOP"}, OP_GS_NOP},
132+
{{"GS_OP_CUT"}, OP_GS_CUT},
133+
{{"GS_OP_EMIT"}, OP_GS_EMIT},
134+
{{"GS_OP_EMIT_CUT"}, OP_GS_EMIT_CUT},
135+
};
136+
66137
// clang-format on
67138
// NOLINTEND
68139

69-
const int MSG_SIZE = static_cast<int>(
70-
sizeof(Msg) / sizeof(CustomOperand<const MCSubtargetInfo &>));
140+
int64_t getMsgId(StringRef Name, const MCSubtargetInfo &STI) {
141+
return getEncodingFromOperandTable(MsgOperands, Name, STI);
142+
}
71143

72-
// These two must be in sync with llvm::AMDGPU::SendMsg::Op enum members, see SIDefines.h.
73-
const char *const OpSysSymbolic[OP_SYS_LAST_] = {
74-
nullptr,
75-
"SYSMSG_OP_ECC_ERR_INTERRUPT",
76-
"SYSMSG_OP_REG_RD",
77-
"SYSMSG_OP_HOST_TRAP_ACK",
78-
"SYSMSG_OP_TTRACE_PC"
79-
};
144+
StringRef getMsgName(uint64_t Encoding, const MCSubtargetInfo &STI) {
145+
return getNameFromOperandTable(MsgOperands, Encoding, STI);
146+
}
80147

81-
const char *const OpGsSymbolic[OP_GS_LAST_] = {
82-
"GS_OP_NOP",
83-
"GS_OP_CUT",
84-
"GS_OP_EMIT",
85-
"GS_OP_EMIT_CUT"
86-
};
148+
int64_t getMsgOpId(int64_t MsgId, StringRef Name, const MCSubtargetInfo &STI) {
149+
if (MsgId == ID_SYSMSG)
150+
return getEncodingFromOperandTable(SysMsgOperands, Name, STI);
151+
return getEncodingFromOperandTable(StreamMsgOperands, Name, STI);
152+
}
153+
154+
StringRef getMsgOpName(int64_t MsgId, uint64_t Encoding,
155+
const MCSubtargetInfo &STI) {
156+
assert(msgRequiresOp(MsgId, STI) && "must have an operand");
157+
158+
if (MsgId == ID_SYSMSG)
159+
return getNameFromOperandTable(SysMsgOperands, Encoding, STI);
160+
return getNameFromOperandTable(StreamMsgOperands, Encoding, STI);
161+
}
87162

88163
} // namespace SendMsg
89164

@@ -92,7 +167,7 @@ namespace Hwreg {
92167
// Disable lint checking for this block since it makes the table unreadable.
93168
// NOLINTBEGIN
94169
// clang-format off
95-
const CustomOperand<const MCSubtargetInfo &> Opr[] = {
170+
static constexpr CustomOperand Operands[] = {
96171
{{""}},
97172
{{"HW_REG_MODE"}, ID_MODE},
98173
{{"HW_REG_STATUS"}, ID_STATUS},
@@ -155,8 +230,13 @@ const CustomOperand<const MCSubtargetInfo &> Opr[] = {
155230
// clang-format on
156231
// NOLINTEND
157232

158-
const int OPR_SIZE = static_cast<int>(
159-
sizeof(Opr) / sizeof(CustomOperand<const MCSubtargetInfo &>));
233+
int64_t getHwregId(StringRef Name, const MCSubtargetInfo &STI) {
234+
return getEncodingFromOperandTable(Operands, Name, STI);
235+
}
236+
237+
StringRef getHwreg(uint64_t Encoding, const MCSubtargetInfo &STI) {
238+
return getNameFromOperandTable(Operands, Encoding, STI);
239+
}
160240

161241
} // namespace Hwreg
162242

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

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ const int OPR_ID_UNSUPPORTED = -2;
2525
const int OPR_ID_DUPLICATE = -3;
2626
const int OPR_VAL_INVALID = -4;
2727

28-
template <class T> struct CustomOperand {
28+
struct CustomOperand {
2929
StringLiteral Name;
30-
int Encoding = 0;
31-
bool (*Cond)(T Context) = nullptr;
30+
unsigned Encoding = 0;
31+
bool (*Cond)(const MCSubtargetInfo &STI) = nullptr;
3232
};
3333

3434
struct CustomOperandVal {
@@ -60,20 +60,34 @@ extern const int DEP_CTR_SIZE;
6060

6161
} // namespace DepCtr
6262

63-
namespace SendMsg { // Symbolic names for the sendmsg(...) syntax.
63+
// Symbolic names for the sendmsg(msg_id, operation, stream) syntax.
64+
namespace SendMsg {
65+
66+
/// Map from a symbolic name for a msg_id to the message portion of the
67+
/// immediate encoding. A negative return value indicates that the Name was
68+
/// unknown or unsupported on this target.
69+
int64_t getMsgId(StringRef Name, const MCSubtargetInfo &STI);
70+
71+
/// Map from an encoding to the symbolic name for a msg_id immediate. This is
72+
/// doing opposite of getMsgId().
73+
StringRef getMsgName(uint64_t Encoding, const MCSubtargetInfo &STI);
6474

65-
extern const CustomOperand<const MCSubtargetInfo &> Msg[];
66-
extern const int MSG_SIZE;
75+
/// Map from a symbolic name for a sendmsg operation to the operation portion of
76+
/// the immediate encoding. A negative return value indicates that the Name was
77+
/// unknown or unsupported on this target.
78+
int64_t getMsgOpId(int64_t MsgId, StringRef Name, const MCSubtargetInfo &STI);
6779

68-
extern const char *const OpSysSymbolic[OP_SYS_LAST_];
69-
extern const char *const OpGsSymbolic[OP_GS_LAST_];
80+
/// Map from an encoding to the symbolic name for a sendmsg operation. This is
81+
/// doing opposite of getMsgOpId().
82+
StringRef getMsgOpName(int64_t MsgId, uint64_t Encoding,
83+
const MCSubtargetInfo &STI);
7084

7185
} // namespace SendMsg
7286

7387
namespace Hwreg { // Symbolic names for the hwreg(...) syntax.
7488

75-
extern const CustomOperand<const MCSubtargetInfo &> Opr[];
76-
extern const int OPR_SIZE;
89+
int64_t getHwregId(StringRef Name, const MCSubtargetInfo &STI);
90+
StringRef getHwreg(uint64_t Encoding, const MCSubtargetInfo &STI);
7791

7892
} // namespace Hwreg
7993

0 commit comments

Comments
 (0)