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; + +// 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) {