[llvm] [TableGen][Decoder] Always handle `bits<0>` (PR #159951)

Sergei Barannikov via llvm-commits llvm-commits at lists.llvm.org
Sat Sep 20 16:16:24 PDT 2025


https://github.com/s-barannikov updated https://github.com/llvm/llvm-project/pull/159951

>From 7cc4084b3a6005a02e3584ac3f6eccb9543f66d9 Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Sun, 21 Sep 2025 01:17:44 +0300
Subject: [PATCH] [TableGen][Decoder] Always handle `bits<0>`

Previously, `bits<0>` only had effect if `ignore-non-decodable-operands`
wasn't specified. Handle it even if the option wasn't specified. This
should allow for a smoother transition.
---
 .../Target/RISCV/Disassembler/RISCVDisassembler.cpp    |  8 ++++++++
 llvm/lib/Target/RISCV/RISCVInstrInfoC.td               |  5 ++---
 llvm/utils/TableGen/Common/InstructionEncoding.cpp     | 10 ++++++++++
 llvm/utils/TableGen/DecoderEmitter.cpp                 |  2 --
 4 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index ff07122b61378..9f070fb2ff3e2 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -206,6 +206,14 @@ static DecodeStatus DecodeSPRegisterClass(MCInst &Inst,
   return MCDisassembler::Success;
 }
 
+static DecodeStatus DecodeSPRegisterClass(MCInst &Inst, uint64_t RegNo,
+                                          uint32_t Address,
+                                          const MCDisassembler *Decoder) {
+  assert(RegNo == 2);
+  Inst.addOperand(MCOperand::createReg(RISCV::X2));
+  return MCDisassembler::Success;
+}
+
 static DecodeStatus DecodeGPRX5RegisterClass(MCInst &Inst,
                                              const MCDisassembler *Decoder) {
   Inst.addOperand(MCOperand::createReg(RISCV::X5));
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td
index 9fc73662d9704..24e7a0ee5a79f 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td
@@ -298,7 +298,7 @@ def C_ADDI4SPN : RVInst16CIW<0b000, 0b00, (outs GPRC:$rd),
                              (ins SP:$rs1, uimm10_lsb00nonzero:$imm),
                              "c.addi4spn", "$rd, $rs1, $imm">,
                              Sched<[WriteIALU, ReadIALU]> {
-  bits<5> rs1;
+  bits<0> rs1;
   let Inst{12-11} = imm{5-4};
   let Inst{10-7} = imm{9-6};
   let Inst{6} = imm{2};
@@ -404,8 +404,8 @@ def C_ADDI16SP : RVInst16CI<0b011, 0b01, (outs SP:$rd_wb),
                             "c.addi16sp", "$rd, $imm">,
                  Sched<[WriteIALU, ReadIALU]> {
   let Constraints = "$rd = $rd_wb";
+  let rd = 2;
   let Inst{12} = imm{9};
-  let Inst{11-7} = 2;
   let Inst{6} = imm{4};
   let Inst{5} = imm{6};
   let Inst{4-3} = imm{8-7};
@@ -965,4 +965,3 @@ let Predicates = [HasStdExtCOrZcd, HasStdExtD] in {
   def : CompressPat<(FSD FPR64:$rs2, SPMem:$rs1, uimm9_lsb000:$imm),
                     (C_FSDSP FPR64:$rs2, SPMem:$rs1, uimm9_lsb000:$imm)>;
 } // Predicates = [HasStdExtCOrZcd, HasStdExtD]
-
diff --git a/llvm/utils/TableGen/Common/InstructionEncoding.cpp b/llvm/utils/TableGen/Common/InstructionEncoding.cpp
index 7260ee3d9b534..d3678cfb88d52 100644
--- a/llvm/utils/TableGen/Common/InstructionEncoding.cpp
+++ b/llvm/utils/TableGen/Common/InstructionEncoding.cpp
@@ -316,6 +316,16 @@ static void addOneOperandFields(const Record *EncodingDef,
     else
       OpInfo.addField(I, J - I, Offset);
   }
+
+  if (!OpInfo.InitValue && OpInfo.fields().empty()) {
+    // We found a field in InstructionEncoding record that corresponds to the
+    // named operand, but that field has no constant bits and doesn't contribute
+    // to the Inst field. For now, give a warning and treat that field as if it
+    // didn't exist.
+    PrintWarning(EncodingDef->getLoc(),
+                 "operand '" + OpName + "' should be defined as `bits<0>`");
+    OpInfo.HasNoEncoding = true;
+  }
 }
 
 void InstructionEncoding::parseFixedLenOperands(const BitsInit &Bits) {
diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp
index e83df47d541c6..961dc2815f6b9 100644
--- a/llvm/utils/TableGen/DecoderEmitter.cpp
+++ b/llvm/utils/TableGen/DecoderEmitter.cpp
@@ -696,8 +696,6 @@ static void emitBinaryParser(raw_ostream &OS, indent Indent,
 
   // Special case for 'bits<0>'.
   if (OpInfo.Fields.empty() && !OpInfo.InitValue) {
-    if (IgnoreNonDecodableOperands)
-      return;
     assert(!OpInfo.Decoder.empty());
     // The operand has no encoding, so the corresponding argument is omitted.
     // This avoids confusion and allows the function to be overloaded if the



More information about the llvm-commits mailing list