[llvm] [DecoderEmitter] Eliminate `DecodeComplete` parameter to `decodeToMCInst` (PR #159130)
Rahul Joshi via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 16 10:08:24 PDT 2025
https://github.com/jurahul updated https://github.com/llvm/llvm-project/pull/159130
>From 88b54459555ea11a413fa1575d3cb9fb62d3fb68 Mon Sep 17 00:00:00 2001
From: Rahul Joshi <rjoshi at nvidia.com>
Date: Tue, 16 Sep 2025 09:50:08 -0700
Subject: [PATCH] [DecoderEmitter] Eliminate `DecodeComplete` parameter to
`decodeToMCInst`
Currently, the code generated by decoder emitter always set
`DeocdeComplete` to false when returning Fail from `decodeToMCInst`. As
a result, we can just use the return `DecodeStatus` from
`decodeToMCInst` to decide whether to terminate the decoding and
return or continue trying.
---
.../llvm/MC/MCDisassembler/MCDisassembler.h | 10 +++----
.../DecoderEmitter/DecoderEmitterFnTable.td | 12 ++++----
.../DecoderEmitter/trydecode-emission.td | 4 +--
.../DecoderEmitter/trydecode-emission2.td | 8 ++---
.../DecoderEmitter/trydecode-emission3.td | 4 +--
.../DecoderEmitter/trydecode-emission4.td | 4 +--
llvm/utils/TableGen/DecoderEmitter.cpp | 29 ++++++-------------
7 files changed, 30 insertions(+), 41 deletions(-)
diff --git a/llvm/include/llvm/MC/MCDisassembler/MCDisassembler.h b/llvm/include/llvm/MC/MCDisassembler/MCDisassembler.h
index cae2fbcac1fef..3d10380fa1d46 100644
--- a/llvm/include/llvm/MC/MCDisassembler/MCDisassembler.h
+++ b/llvm/include/llvm/MC/MCDisassembler/MCDisassembler.h
@@ -98,11 +98,11 @@ class LLVM_ABI MCDisassembler {
/// from Success->SoftFail ->Fail can be done with a simple
/// bitwise-AND:
///
- /// LEFT & TOP = | Success Unpredictable Fail
- /// --------------+-----------------------------------
- /// Success | Success Unpredictable Fail
- /// Unpredictable | Unpredictable Unpredictable Fail
- /// Fail | Fail Fail Fail
+ /// LEFT & TOP = | Success SoftFail Fail
+ /// --------------+-----------------------------
+ /// Success | Success SoftFail Fail
+ /// SoftFail | SoftFail SoftFail Fail
+ /// Fail | Fail Fail Fail
///
/// An easy way of encoding this is as 0b11, 0b01, 0b00 for
/// Success, SoftFail, Fail respectively.
diff --git a/llvm/test/TableGen/DecoderEmitter/DecoderEmitterFnTable.td b/llvm/test/TableGen/DecoderEmitter/DecoderEmitterFnTable.td
index 455089588511f..cc1efd58005b0 100644
--- a/llvm/test/TableGen/DecoderEmitter/DecoderEmitterFnTable.td
+++ b/llvm/test/TableGen/DecoderEmitter/DecoderEmitterFnTable.td
@@ -71,14 +71,14 @@ def Inst3 : TestInstruction {
let AsmString = "Inst3";
}
-// CHECK-LABEL: DecodeStatus decodeFn_0(DecodeStatus S, InsnType insn, MCInst &MI, uint64_t Address, const MCDisassembler *Decoder, bool &DecodeComplete)
-// CHECK-LABEL: DecodeStatus decodeFn_1(DecodeStatus S, InsnType insn, MCInst &MI, uint64_t Address, const MCDisassembler *Decoder, bool &DecodeComplete)
-// CHECK-LABEL: DecodeStatus decodeFn_2(DecodeStatus S, InsnType insn, MCInst &MI, uint64_t Address, const MCDisassembler *Decoder, bool &DecodeComplete)
-// CHECK-LABEL: DecodeStatus decodeFn_3(DecodeStatus S, InsnType insn, MCInst &MI, uint64_t Address, const MCDisassembler *Decoder, bool &DecodeComplete)
-// CHECK-LABEL: decodeToMCInst(unsigned Idx, DecodeStatus S, InsnType insn, MCInst &MI, uint64_t Address, const MCDisassembler *Decoder, bool &DecodeComplete)
+// CHECK-LABEL: DecodeStatus decodeFn_0(DecodeStatus S, InsnType insn, MCInst &MI, uint64_t Address, const MCDisassembler *Decoder)
+// CHECK-LABEL: DecodeStatus decodeFn_1(DecodeStatus S, InsnType insn, MCInst &MI, uint64_t Address, const MCDisassembler *Decoder)
+// CHECK-LABEL: DecodeStatus decodeFn_2(DecodeStatus S, InsnType insn, MCInst &MI, uint64_t Address, const MCDisassembler *Decoder)
+// CHECK-LABEL: DecodeStatus decodeFn_3(DecodeStatus S, InsnType insn, MCInst &MI, uint64_t Address, const MCDisassembler *Decoder)
+// CHECK-LABEL: decodeToMCInst(unsigned Idx, DecodeStatus S, InsnType insn, MCInst &MI, uint64_t Address, const MCDisassembler *Decoder)
// CHECK: static constexpr DecodeFnTy decodeFnTable[]
// CHECK-NEXT: decodeFn_0,
// CHECK-NEXT: decodeFn_1,
// CHECK-NEXT: decodeFn_2,
// CHECK-NEXT: decodeFn_3,
-// CHECK: return decodeFnTable[Idx](S, insn, MI, Address, Decoder, DecodeComplete)
+// CHECK: return decodeFnTable[Idx](S, insn, MI, Address, Decoder)
diff --git a/llvm/test/TableGen/DecoderEmitter/trydecode-emission.td b/llvm/test/TableGen/DecoderEmitter/trydecode-emission.td
index cdb1e327ad07d..98a78e29114c1 100644
--- a/llvm/test/TableGen/DecoderEmitter/trydecode-emission.td
+++ b/llvm/test/TableGen/DecoderEmitter/trydecode-emission.td
@@ -41,7 +41,7 @@ def InstB : TestInstruction {
// CHECK-NEXT: /* 15 */ OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: 1
// CHECK-NEXT: };
-// CHECK: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
+// CHECK: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { return MCDisassembler::Fail; }
// CHECK: unsigned NumToSkip = *Ptr++;
// CHECK-NEXT: NumToSkip |= (*Ptr++) << 8;
@@ -54,7 +54,7 @@ def InstB : TestInstruction {
// CHECK-LARGE-NEXT: /* 16 */ OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: 1
// CHECK-LARGE-NEXT: };
-// CHECK-LARGE: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
+// CHECK-LARGE: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { return MCDisassembler::Fail; }
// CHECK-LARGE: unsigned NumToSkip = *Ptr++;
// CHECK-LARGE-NEXT: NumToSkip |= (*Ptr++) << 8;
diff --git a/llvm/test/TableGen/DecoderEmitter/trydecode-emission2.td b/llvm/test/TableGen/DecoderEmitter/trydecode-emission2.td
index 35657ff35c86f..be3bf812fb636 100644
--- a/llvm/test/TableGen/DecoderEmitter/trydecode-emission2.td
+++ b/llvm/test/TableGen/DecoderEmitter/trydecode-emission2.td
@@ -39,8 +39,8 @@ def InstB : TestInstruction {
// CHECK-NEXT: /* 19 */ OPC_CheckField, 3, 2, 0,
// CHECK-NEXT: /* 23 */ OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 1,
-// CHECK: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
-// CHECK: if (!Check(S, DecodeInstA(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
+// CHECK: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { return MCDisassembler::Fail; }
+// CHECK: if (!Check(S, DecodeInstA(MI, insn, Address, Decoder))) { return MCDisassembler::Fail; }
// CHECK-LARGE: /* 0 */ OPC_CheckField, 2, 1, 0,
// CHECK-LARGE-NEXT: /* 4 */ OPC_CheckField, 5, 3, 0,
@@ -51,5 +51,5 @@ def InstB : TestInstruction {
// CHECK-LARGE-NEXT: /* 24 */ OPC_TryDecode, {{[0-9]+}}, {{[0-9]+}}, 1,
// CHECK-LARGE-NEXT: };
-// CHECK-LARGE: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
-// CHECK-LARGE: if (!Check(S, DecodeInstA(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
+// CHECK-LARGE: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { return MCDisassembler::Fail; }
+// CHECK-LARGE: if (!Check(S, DecodeInstA(MI, insn, Address, Decoder))) { return MCDisassembler::Fail; }
diff --git a/llvm/test/TableGen/DecoderEmitter/trydecode-emission3.td b/llvm/test/TableGen/DecoderEmitter/trydecode-emission3.td
index 4ac868dbb51aa..a46bd53cf1702 100644
--- a/llvm/test/TableGen/DecoderEmitter/trydecode-emission3.td
+++ b/llvm/test/TableGen/DecoderEmitter/trydecode-emission3.td
@@ -42,7 +42,7 @@ def InstB : TestInstruction {
// CHECK-NEXT: /* 15 */ OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: 1
// CHECK-NEXT: };
-// CHECK: if (!Check(S, DecodeInstBOp(MI, tmp, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
+// CHECK: if (!Check(S, DecodeInstBOp(MI, tmp, Address, Decoder))) { return MCDisassembler::Fail; }
// CHECK-LARGE: /* 0 */ OPC_CheckField, 4, 4, 0,
// CHECK-LARGE-NEXT: /* 4 */ OPC_Scope, 8, 0, 0, // end scope at 16
@@ -51,4 +51,4 @@ def InstB : TestInstruction {
// CHECK-LARGE-NEXT: /* 16 */ OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: 1
// CHECK-LARGE-NEXT: };
-// CHECK-LARGE: if (!Check(S, DecodeInstBOp(MI, tmp, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
+// CHECK-LARGE: if (!Check(S, DecodeInstBOp(MI, tmp, Address, Decoder))) { return MCDisassembler::Fail; }
diff --git a/llvm/test/TableGen/DecoderEmitter/trydecode-emission4.td b/llvm/test/TableGen/DecoderEmitter/trydecode-emission4.td
index ff1a7e33747ba..6be3af6b749aa 100644
--- a/llvm/test/TableGen/DecoderEmitter/trydecode-emission4.td
+++ b/llvm/test/TableGen/DecoderEmitter/trydecode-emission4.td
@@ -40,7 +40,7 @@ def InstB : TestInstruction {
// CHECK-NEXT: /* 17 */ OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: 1
// CHECK-NEXT: };
-// CHECK: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
+// CHECK: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { return MCDisassembler::Fail; }
// CHECK-LARGE: /* 0 */ OPC_CheckField, 250, 3, 4, 0,
@@ -50,4 +50,4 @@ def InstB : TestInstruction {
// CHECK-LARGE-NEXT: /* 18 */ OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: InstA, DecodeIdx: 1
// CHECK-LARGE-NEXT: };
-// CHECK-LARGE: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { DecodeComplete = false; return MCDisassembler::Fail; }
+// CHECK-LARGE: if (!Check(S, DecodeInstB(MI, insn, Address, Decoder))) { return MCDisassembler::Fail; }
diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp
index 9aa7d31c62693..acb2fc3b562ae 100644
--- a/llvm/utils/TableGen/DecoderEmitter.cpp
+++ b/llvm/utils/TableGen/DecoderEmitter.cpp
@@ -865,7 +865,7 @@ void DecoderEmitter::emitDecoderFunction(formatted_raw_ostream &OS,
"InsnType, uint64_t>;\n";
StringRef DecodeParams =
"DecodeStatus S, InsnType insn, MCInst &MI, uint64_t Address, const "
- "MCDisassembler *Decoder, bool &DecodeComplete";
+ "MCDisassembler *Decoder";
// Print the name of the decode function to OS.
auto PrintDecodeFnName = [&OS, BucketBitWidth](unsigned DecodeIdx) {
@@ -904,7 +904,6 @@ void DecoderEmitter::emitDecoderFunction(formatted_raw_ostream &OS,
OS << "// Handling " << Decoders.size() << " cases.\n";
PrintTemplate();
OS << "decodeToMCInst(unsigned Idx, " << DecodeParams << ") {\n";
- OS << " DecodeComplete = true;\n";
if (UseFnTableInDecodeToMCInst) {
// Build a table of function pointers
@@ -918,8 +917,7 @@ void DecoderEmitter::emitDecoderFunction(formatted_raw_ostream &OS,
OS << " };\n";
OS << " if (Idx >= " << Decoders.size() << ")\n";
OS << " llvm_unreachable(\"Invalid decoder index!\");\n";
- OS << " return decodeFnTable[Idx](S, insn, MI, Address, Decoder, "
- "DecodeComplete);\n";
+ OS << " return decodeFnTable[Idx](S, insn, MI, Address, Decoder);\n";
} else {
OS << " " << TmpTypeDecl;
OS << " TmpType tmp;\n";
@@ -1052,9 +1050,7 @@ static void emitBinaryParser(raw_ostream &OS, indent Indent,
StringRef Decoder = OpInfo.Decoder;
if (!Decoder.empty()) {
OS << Indent << "if (!Check(S, " << Decoder
- << "(MI, tmp, Address, Decoder))) { "
- << (OpInfo.HasCompleteDecoder ? "" : "DecodeComplete = false; ")
- << "return MCDisassembler::Fail; }\n";
+ << "(MI, tmp, Address, Decoder))) { return MCDisassembler::Fail; }\n";
} else {
OS << Indent << "MI.addOperand(MCOperand::createImm(tmp));\n";
}
@@ -1069,9 +1065,7 @@ static std::string getDecoderString(const InstructionEncoding &Encoding) {
StringRef DecoderMethod = Encoding.getDecoderMethod();
if (!DecoderMethod.empty()) {
OS << Indent << "if (!Check(S, " << DecoderMethod
- << "(MI, insn, Address, Decoder))) { "
- << (Encoding.hasCompleteDecoder() ? "" : "DecodeComplete = false; ")
- << "return MCDisassembler::Fail; }\n";
+ << "(MI, insn, Address, Decoder))) { return MCDisassembler::Fail; }\n";
} else {
for (const OperandInfo &Op : Encoding.getOperands())
emitBinaryParser(OS, Indent, Encoding, Op);
@@ -1682,15 +1676,13 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
unsigned DecodeIdx = decodeULEB128AndIncUnsafe(Ptr);
MI.clear();
- MI.setOpcode(Opc);
- bool DecodeComplete;)";
+ MI.setOpcode(Opc);)";
if (IsVarLenInst) {
OS << "\n unsigned Len = InstrLenTable[Opc];\n"
<< " makeUp(insn, Len);";
}
OS << R"(
- S = decodeToMCInst(DecodeIdx, S, insn, MI, Address, DisAsm, DecodeComplete);
- assert(DecodeComplete);
+ S = decodeToMCInst(DecodeIdx, S, insn, MI, Address, DisAsm);
LLVM_DEBUG(dbgs() << Loc << ": OPC_Decode: opcode " << Opc
<< ", using decoder " << DecodeIdx << ": "
@@ -1707,18 +1699,15 @@ static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], MCInst &MI,
// Perform the decode operation.
MCInst TmpMI;
TmpMI.setOpcode(Opc);
- bool DecodeComplete;
- S = decodeToMCInst(DecodeIdx, S, insn, TmpMI, Address, DisAsm, DecodeComplete);
+ S = decodeToMCInst(DecodeIdx, S, insn, TmpMI, Address, DisAsm);
LLVM_DEBUG(dbgs() << Loc << ": OPC_TryDecode: opcode " << Opc
<< ", using decoder " << DecodeIdx << ": ");
- if (DecodeComplete) {
- // Decoding complete.
- LLVM_DEBUG(dbgs() << (S != MCDisassembler::Fail ? "PASS\n" : "FAIL\n"));
+ if (S != MCDisassembler::Fail) {
+ LLVM_DEBUG(dbgs() << (S != MCDisassembler::Success ? "Success\n" : "SoftFail\n"));
MI = TmpMI;
return S;
}
- assert(S == MCDisassembler::Fail);
if (ScopeStack.empty()) {
LLVM_DEBUG(dbgs() << "FAIL, returning FAIL\n");
return MCDisassembler::Fail;
More information about the llvm-commits
mailing list