Skip to content

Conversation

s-barannikov
Copy link
Contributor

The added tests used to crash when attempting to dereference a nullptr MIOpInfo or call MIOpInfo->getArg(0) on an empty MIOpInfo dag.

The added tests used to crash when attempting to dereference a nullptr
MIOpInfo or call MIOpInfo->getArg(0) on an empty MIOpInfo dag.
@llvmbot
Copy link
Member

llvmbot commented Aug 30, 2025

@llvm/pr-subscribers-tablegen

Author: Sergei Barannikov (s-barannikov)

Changes

The added tests used to crash when attempting to dereference a nullptr MIOpInfo or call MIOpInfo->getArg(0) on an empty MIOpInfo dag.


Full diff: https://github.com/llvm/llvm-project/pull/156179.diff

3 Files Affected:

  • (added) llvm/test/TableGen/FixedLenDecoderEmitter/sub-arg-dag-error-1.td (+28)
  • (added) llvm/test/TableGen/FixedLenDecoderEmitter/sub-arg-dag-error-2.td (+27)
  • (modified) llvm/utils/TableGen/Common/CodeGenInstruction.cpp (+11-3)
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) {

@s-barannikov s-barannikov requested a review from jurahul September 4, 2025 19:11
@s-barannikov
Copy link
Contributor Author

ping

@s-barannikov s-barannikov merged commit dc10373 into llvm:main Sep 5, 2025
9 checks passed
@s-barannikov s-barannikov deleted the tablegen/empty-mi-operands-crash branch September 5, 2025 15:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants