[llvm] [TableGen] Fix a couple of crashes related to sub-operand dags (PR #156179)
Sergei Barannikov via llvm-commits
llvm-commits at lists.llvm.org
Sat Aug 30 06:16:49 PDT 2025
https://github.com/s-barannikov created https://github.com/llvm/llvm-project/pull/156179
The added tests used to crash when attempting to dereference a nullptr MIOpInfo or call MIOpInfo->getArg(0) on an empty MIOpInfo dag.
>From 6e31a7c0b4b4af7144442105f8338fe5c0c1fda0 Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Sat, 30 Aug 2025 16:15:31 +0300
Subject: [PATCH] [TableGen] Fix a couple of crashes related to sub-operand
dags
The added tests used to crash when attempting to dereference a nullptr
MIOpInfo or call MIOpInfo->getArg(0) on an empty MIOpInfo dag.
---
.../sub-arg-dag-error-1.td | 28 +++++++++++++++++++
.../sub-arg-dag-error-2.td | 27 ++++++++++++++++++
.../TableGen/Common/CodeGenInstruction.cpp | 14 ++++++++--
3 files changed, 66 insertions(+), 3 deletions(-)
create mode 100644 llvm/test/TableGen/FixedLenDecoderEmitter/sub-arg-dag-error-1.td
create mode 100644 llvm/test/TableGen/FixedLenDecoderEmitter/sub-arg-dag-error-2.td
diff --git a/llvm/test/TableGen/FixedLenDecoderEmitter/sub-arg-dag-error-1.td b/llvm/test/TableGen/FixedLenDecoderEmitter/sub-arg-dag-error-1.td
new file mode 100644
index 0000000000000..7090eaf20a9ad
--- /dev/null
+++ b/llvm/test/TableGen/FixedLenDecoderEmitter/sub-arg-dag-error-1.td
@@ -0,0 +1,28 @@
+// RUN: not llvm-tblgen -gen-disassembler -I %p/../../../include %s 2>&1 \
+// RUN: | FileCheck %s --implicit-check-not=error:
+
+include "llvm/Target/Target.td"
+
+def R0 : Register<"r0">;
+def RC : RegisterClass<"MyTarget", [i32], 32, (add R0)>;
+
+// Used to crash.
+// CHECK: error: In instruction 'I', operand #0 has 1 sub-arg names, but no sub-operands
+
+def I : Instruction {
+ let Size = 1;
+ bits<8> Inst;
+ bits<1> r;
+
+ let Inst{0} = 0;
+ let Inst{1} = r;
+
+ let OutOperandList = (outs);
+ let InOperandList = (ins (RC $r):$op);
+}
+
+def II : InstrInfo;
+
+def MyTarget : Target {
+ let InstructionSet = II;
+}
diff --git a/llvm/test/TableGen/FixedLenDecoderEmitter/sub-arg-dag-error-2.td b/llvm/test/TableGen/FixedLenDecoderEmitter/sub-arg-dag-error-2.td
new file mode 100644
index 0000000000000..65cc0e20350c0
--- /dev/null
+++ b/llvm/test/TableGen/FixedLenDecoderEmitter/sub-arg-dag-error-2.td
@@ -0,0 +1,27 @@
+// RUN: not llvm-tblgen -gen-disassembler -I %p/../../../include %s 2>&1 \
+// RUN: | FileCheck %s --implicit-check-not=error:
+
+include "llvm/Target/Target.td"
+
+def CustomOp : Operand<i32>;
+
+// Used to crash.
+// CHECK: error: In instruction 'I', operand #0 has 1 sub-arg names, expected 0
+
+def I : Instruction {
+ let Size = 1;
+ bits<8> Inst;
+ bits<1> i;
+
+ let Inst{0} = 0;
+ let Inst{1} = i;
+
+ let OutOperandList = (outs);
+ let InOperandList = (ins (CustomOp $i):$op);
+}
+
+def II : InstrInfo;
+
+def MyTarget : Target {
+ let InstructionSet = II;
+}
diff --git a/llvm/utils/TableGen/Common/CodeGenInstruction.cpp b/llvm/utils/TableGen/Common/CodeGenInstruction.cpp
index da343e5e23177..ff70d50971b89 100644
--- a/llvm/utils/TableGen/Common/CodeGenInstruction.cpp
+++ b/llvm/utils/TableGen/Common/CodeGenInstruction.cpp
@@ -143,12 +143,20 @@ CGIOperandList::CGIOperandList(const Record *R) : TheDef(R) {
MIOperandNo, NumOps, MIOpInfo);
if (SubArgDag) {
- if (SubArgDag->getNumArgs() != NumOps) {
+ if (!MIOpInfo) {
PrintFatalError(R->getLoc(), "In instruction '" + R->getName() +
"', operand #" + Twine(i) + " has " +
Twine(SubArgDag->getNumArgs()) +
- " sub-arg names, expected " +
- Twine(NumOps) + ".");
+ " sub-arg names, but no sub-operands");
+ }
+
+ unsigned NumSubArgs = SubArgDag->getNumArgs();
+ unsigned NumSubOps = MIOpInfo->getNumArgs();
+ if (NumSubArgs != NumSubOps) {
+ PrintFatalError(R->getLoc(),
+ "In instruction '" + R->getName() + "', operand #" +
+ Twine(i) + " has " + Twine(NumSubArgs) +
+ " sub-arg names, expected " + Twine(NumSubOps));
}
for (unsigned j = 0; j < NumOps; ++j) {
More information about the llvm-commits
mailing list