Skip to content

Commit c8e760e

Browse files
authored
[LLVM][MC][DecoderEmitter] Fail fatally if Insn and decoder table bitwidths mismatch (#156734)
1 parent 08fd349 commit c8e760e

File tree

2 files changed

+44
-7
lines changed

2 files changed

+44
-7
lines changed

llvm/test/TableGen/DecoderEmitterBitwidthSpecialization.td

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ def Inst3 : Instruction16Bit<3> {
105105
// When we specialize per bitwidth, we emit 2 decodeToMCInst functions and
106106
// DecodeIdx is assigned per bit width.
107107

108-
// CHECK-SPECIALIZE-NO-TABLE-LABEL: DecoderTable8[25]
108+
// CHECK-SPECIALIZE-NO-TABLE-LABEL: DecoderTable8[26]
109+
// CHECK-SPECIALIZE-NO-TABLE: /* 0 */ 8, // Bitwidth 8
109110
// CHECK-SPECIALIZE-NO-TABLE: DecodeIdx: 0
110111
// CHECK-SPECIALIZE-NO-TABLE: DecodeIdx: 1
111112
// CHECK-SPECIALIZE-NO-TABLE: };
@@ -116,7 +117,8 @@ def Inst3 : Instruction16Bit<3> {
116117
// CHECK-SPECIALIZE-NO-TABLE: case 0
117118
// CHECK-SPECIALIZE-NO-TABLE: case 1
118119

119-
// CHECK-SPECIALIZE-NO-TABLE-LABEL: DecoderTable16[25]
120+
// CHECK-SPECIALIZE-NO-TABLE-LABEL: DecoderTable16[26]
121+
// CHECK-SPECIALIZE-NO-TABLE: /* 0 */ 16, // Bitwidth 16
120122
// CHECK-SPECIALIZE-NO-TABLE: DecodeIdx: 0
121123
// CHECK-SPECIALIZE-NO-TABLE: DecodeIdx: 1
122124
// CHECK-SPECIALIZE-NO-TABLE: };
@@ -127,11 +129,17 @@ def Inst3 : Instruction16Bit<3> {
127129
// CHECK-SPECIALIZE-NO-TABLE: case 0
128130
// CHECK-SPECIALIZE-NO-TABLE: case 1
129131

132+
// CHECK-SPECIALIZE-NO-TABLE-LABEL: template <typename InsnType>
133+
// CHECK-SPECIALIZE-NO-TABLE-NEXT: decodeInstruction
134+
// CHECK-SPECIALIZE-NO-TABLE: uint32_t BitWidth = decodeULEB128AndIncUnsafe(Ptr);
135+
// CHECK-SPECIALIZE-NO-TABLE-NEXT: assert(InsnBitWidth<InsnType> == BitWidth &&
136+
130137
// -----------------------------------------------------------------------------
131138
// Per bitwidth specialization with function table.
132139

133140
// 8 bit deccoder table, functions, and function table.
134-
// CHECK-SPECIALIZE-TABLE-LABEL: DecoderTable8[25]
141+
// CHECK-SPECIALIZE-TABLE-LABEL: DecoderTable8[26]
142+
// CHECK-SPECIALIZE-TABLE: /* 0 */ 8, // Bitwidth 8
135143
// CHECK-SPECIALIZE-TABLE: DecodeIdx: 0
136144
// CHECK-SPECIALIZE-TABLE: DecodeIdx: 1
137145
// CHECK-SPECIALIZE-TABLE: };
@@ -153,7 +161,8 @@ def Inst3 : Instruction16Bit<3> {
153161
// CHECK-SPECIALIZE-TABLE-NEXT: };
154162

155163
// 16 bit deccoder table, functions, and function table.
156-
// CHECK-SPECIALIZE-TABLE-LABEL: DecoderTable16[25]
164+
// CHECK-SPECIALIZE-TABLE-LABEL: DecoderTable16[26]
165+
// CHECK-SPECIALIZE-TABLE: /* 0 */ 16, // Bitwidth 16
157166
// CHECK-SPECIALIZE-TABLE: DecodeIdx: 0
158167
// CHECK-SPECIALIZE-TABLE: DecodeIdx: 1
159168
// CHECK-SPECIALIZE-TABLE: };
@@ -173,3 +182,8 @@ def Inst3 : Instruction16Bit<3> {
173182
// CHECK-SPECIALIZE-TABLE-NEXT: decodeFn_16bit_0,
174183
// CHECK-SPECIALIZE-TABLE-NEXT: decodeFn_16bit_1,
175184
// CHECK-SPECIALIZE-TABLE-NEXT: };
185+
186+
// CHECK-SPECIALIZE-TABLE-LABEL: template <typename InsnType>
187+
// CHECK-SPECIALIZE-TABLE-NEXT: decodeInstruction
188+
// CHECK-SPECIALIZE-TABLE: uint32_t BitWidth = decodeULEB128AndIncUnsafe(Ptr);
189+
// CHECK-SPECIALIZE-TABLE-NEXT: assert(InsnBitWidth<InsnType> == BitWidth &&

llvm/utils/TableGen/DecoderEmitter.cpp

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,11 @@ class DecoderTableBuilder {
611611
DecoderTableInfo &TableInfo)
612612
: Target(Target), Encodings(Encodings), TableInfo(TableInfo) {}
613613

614-
void buildTable(const FilterChooser &FC) const {
614+
void buildTable(const FilterChooser &FC, unsigned BitWidth) const {
615+
// When specializing decoders per bit width, each decoder table will begin
616+
// with the bitwidth for that table.
617+
if (SpecializeDecodersPerBitwidth)
618+
TableInfo.Table.insertULEB128(BitWidth);
615619
emitTableEntries(FC);
616620
assert(TableInfo.FixupStack.empty() && "Fixup stack phasing error!");
617621
}
@@ -774,6 +778,15 @@ unsigned DecoderEmitter::emitTable(formatted_raw_ostream &OS,
774778
OS << "Skip to: " << Index;
775779
};
776780

781+
// The first entry when specializing decoders per bitwidth is the bitwidth.
782+
// This will be used for additional checks in `decodeInstruction`.
783+
if (SpecializeDecodersPerBitwidth) {
784+
OS << "/* 0 */";
785+
OS.PadToColumn(14);
786+
emitULEB128(I, OS);
787+
OS << " // Bitwidth " << BitWidth << '\n';
788+
}
789+
777790
unsigned OpcodeMask = 0;
778791

779792
while (I != E) {
@@ -2108,9 +2121,19 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
21082121
if (HasCheckPredicate)
21092122
OS << " const FeatureBitset &Bits = STI.getFeatureBits();\n";
21102123
OS << " using namespace llvm::MCD;\n";
2124+
OS << " const uint8_t *Ptr = DecodeTable;\n";
2125+
2126+
if (SpecializeDecodersPerBitwidth) {
2127+
// Fail with a fatal error if decoder table's bitwidth does not match
2128+
// `InsnType` bitwidth.
2129+
OS << R"(
2130+
[[maybe_unused]] uint32_t BitWidth = decodeULEB128AndIncUnsafe(Ptr);
2131+
assert(InsnBitWidth<InsnType> == BitWidth &&
2132+
"Table and instruction bitwidth mismatch");
2133+
)";
2134+
}
21112135

21122136
OS << R"(
2113-
const uint8_t *Ptr = DecodeTable;
21142137
uint64_t CurFieldValue = 0;
21152138
DecodeStatus S = MCDisassembler::Success;
21162139
while (true) {
@@ -2554,7 +2577,7 @@ template <typename T> constexpr uint32_t InsnBitWidth = 0;
25542577
// across all decoder tables.
25552578
// - predicates are shared across all decoder tables.
25562579
TableInfo.Table.clear();
2557-
TableBuilder.buildTable(FC);
2580+
TableBuilder.buildTable(FC, BitWidth);
25582581

25592582
// Print the table to the output stream.
25602583
OpcodeMask |= emitTable(OS, TableInfo.Table, DecoderNamespace, HwModeID,

0 commit comments

Comments
 (0)