<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/62833>62833</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            CodeEmitterGen segfaults on instruction with missing operand and empty OperandList
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          piotro888
      </td>
    </tr>
</table>

<pre>
    Hello, during writing of custom LLVM Target I noticed a problem with error message of TableGen Code Emitter.
CodeEmitterGen is segfaulting instead of providing diagnostics on missing operand, if `InOperandList` and `OutOperandList` dags are empty.

Example (`rd` field is missing):
```
def IRT : PCPUFrri<0b0011110,
  (outs),
  (ins),
  "irt",
  []> {
 let rs1 = 0;
    let rs2 = 0;
    let imm = 0;
}
```
Format:
```
class PCPUInst<dag outs, dag ins, string asmstr, list<dag> pattern>
    : Instruction {
  let Namespace = "PCPU";

  dag OutOperandList = outs;
  dag InOperandList = ins;
  let AsmString = asmstr;
  let Pattern = pattern;
  let Size = 4;

  field bits<32> Inst;
  field bits<32> SoftFail = 0;
}

class PCPUFrri<bits<7> op, dag outs, dag ins, string asmstr, list<dag> pattern>: 
  PCPUInst<outs, ins, asmstr, pattern>
{
 bits<3>  rd;
  bits<3>  rs1;
  bits<3>  rs2;
  bits<16> imm;

 let Inst{31-16}  = imm;
  let Inst{15-13}  = rs2;
  let Inst{12-10}  = rs1;
  let Inst{9-7}    = rd;
  let Inst{6-0}    = op;
}
```
Causes
```
Stack dump:
0.      Program arguments: ../../../bin/llvm-tblgen -gen-emitter -I /home/piotro/llvm-project/llvm/lib/Target/PCPU -I/home/piotro/llvm-project/build/include -I/home/piotro/llvm-project/llvm/include -I /home/piotro/llvm-project/llvm/lib/Target /home/piotro/llvm-project/llvm/lib/Target/PCPU/PCPU.td --write-if-changed -o /home/piotro/llvm-project/build/lib/Target/PCPU/PCPUGenMCCodeEmitter.inc
 #0 0x0000558274c70018 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /home/piotro/llvm-project/llvm/lib/Support/Unix/Signals.inc:567:22
 #1 0x0000558274c703e0 PrintStackTraceSignalHandler(void*) /home/piotro/llvm-project/llvm/lib/Support/Unix/Signals.inc:641:1
 #2 0x0000558274c6dbcf llvm::sys::RunSignalHandlers() /home/piotro/llvm-project/llvm/lib/Support/Signals.cpp:104:20
 #3 0x0000558274c6f97d SignalHandler(int) /home/piotro/llvm-project/llvm/lib/Support/Unix/Signals.inc:412:1
 #4 0x00007f82f973dab0 (/usr/lib/libc.so.6+0x39ab0)
 #5 0x00005582747ec2e1 (anonymous namespace)::CodeEmitterGen::addCodeToMergeInOperand(llvm::Record*, llvm::BitsInit*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, unsigned int&, std::set<unsigned int, std::less<unsigned int>, std::allocator<unsigned int>>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, llvm::CodeGenTarget&) /home/piotro/llvm-project/llvm/utils/TableGen/CodeEmitterGen.cpp:134:29
 #6 0x00005582747ee092 (anonymous namespace)::CodeEmitterGen::getInstructionCaseForEncoding(llvm::Record*, llvm::Record*, llvm::CodeGenTarget&) /home/piotro/llvm-project/llvm/utils/TableGen/CodeEmitterGen.cpp:349:32
 #7 0x00005582747edd1d (anonymous namespace)::CodeEmitterGen::getInstructionCase(llvm::Record*, llvm::CodeGenTarget&) /home/piotro/llvm-project/llvm/utils/TableGen/CodeEmitterGen.cpp:316:1
 #8 0x00005582747ef53a (anonymous namespace)::CodeEmitterGen::run(llvm::raw_ostream&) /home/piotro/llvm-project/llvm/utils/TableGen/CodeEmitterGen.cpp:511:19
 #9 0x00005582747efb30 llvm::EmitCodeEmitter(llvm::RecordKeeper&, llvm::raw_ostream&) /home/piotro/llvm-project/llvm/utils/TableGen/CodeEmitterGen.cpp:572:1
#10 0x0000558274b40908 (anonymous namespace)::LLVMTableGenMain(llvm::raw_ostream&, llvm::RecordKeeper&) /home/piotro/llvm-project/llvm/utils/TableGen/TableGen.cpp:166:5
#11 0x0000558274c8da4e llvm::TableGenMain(char const*, bool (*)(llvm::raw_ostream&, llvm::RecordKeeper&)) /home/piotro/llvm-project/llvm/lib/TableGen/Main.cpp:122:40
#12 0x0000558274b41161 main /home/piotro/llvm-project/llvm/utils/TableGen/TableGen.cpp:291:22
#13 0x00007f82f9727850 (/usr/lib/libc.so.6+0x23850)
#14 0x00007f82f972790a __libc_start_main (/usr/lib/libc.so.6+0x2390a)
#15 0x0000558274766d45 _start (../../../bin/llvm-tblgen+0x36ed45)
make[2]: *** [lib/Target/PCPU/CMakeFiles/PCPUCommonTableGen.dir/build.make:449: lib/Target/PCPU/PCPUGenMCCodeEmitter.inc] Segmentation fault (core dumped)
```
But with some dag entry and still missing operand it prints the error  correctly:
```
def IRT : PCPUFrri<0b0011110,
 (outs),
  (ins GPR:$rs1),
  "irt $rs1",
  []> {
    let rs2 = 0;
    let imm = 0;
}
```
Produces:
```
error: No operand named rd in record IRT (would've used positional operand #0 ('rs1') sub-op #0 with useDeprecatedPositionallyEncodedOperands=true)
def IRT : PCPUFrri<0b0011110,
    ^
```
It's only a small issue, because it is only related to creating instruction definitions for new targets, but as this is a very useful diagnostic message, I thought that it may be worth reporting.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy8Wd1y27gOfhrmBmOPRP3ZF75wnLibOc1upunubYYSYZunkughqSY5T38GlGRLatL0b9tJ45iAwO8DQBKEhLVqXyOuWHLJkqsL0biDNquj0s7oxWJxkWv5vPoDy1IzvgHZGFXv4dEoR596B0Vjna7g_ft_buGjMHt0cAO1dqpACQKORuclVvCo3AHQGG2gQmvFHunhjyIv8R3WsNES4bpSzqGZs-CKBWsa6kZIQ1mwuN-JpvQzq9o6FJKMHI3-rCQNSiX2tbZOFRZ0DZWy1qM8ohG1JPxqBywNbuq_2qH3yjqWBiBqSeN_NW4ikGJvQRgErI7uuUPW_r5-EtWxRGB8wdLASFLfKSwlQe2mZnzJok6fpUH3479K3MHNh4_AojXcbe7-3hqjWLQJ8iAIwzAMGN-0ikAz6MZZMjYaVPUXY1wZxzgfjvm4sugaWHbZDZbowNgQWHQFAYv6YYBOwl-RqKqaSFh29SK7rTaVcK9xL0phrWd9U1vHoo0Ue2gpbsjl4JltwDqfbcJW1hkaKFWvToSOgpKjZtH1GSa5k4yapnBK1wPSnsGfokJ7FAV6HoxzAkEOOxHqlAnFOB38Ex7k2S2kNUomr0Too9G0a1vdt1xI3vEZq9y1ZLzCidhI4179r4Udf4G2zbtcEbhNxMk5rWcvv6Jxr3duK1T5akgnseoytLORkQl97CP2U9GL1tDjHCRFb7Izd7Yzjfs5xj0_sg9GDviPJTZ8XcS_FIUpyVRVTR1PYfFos8sonIUpy66gTYGBLgzVwmQWRie18WxDNT4Lg4Fa-LLacpZ5pU5NvqyVzoKBlj6-uXo3orFoXxTdO1F8AtlUx9PiDubg_90ZvTeiAmH2TYU1eW4N8znj2_OvXNWMb8vyczVzebnHGmZ7rGfY7vMwuwHGtwddIePb9gzq1Y9G_xcL132lD5Uzvm2PHMa3lDgwu3n78bxRpWR8q-qibCR-0zPdlOdHfgzmT5HrPuZOwmxGBzDO1G5WHES9Rwkz_Q3Ge-qvW3-H9e1mcPLOVV10GcV4FEDwFARBkCQLnsVFFgThAjziaM2itX227R93RtXOZ8pHIwpkfHFWMuLxQVtnUFSMp-36dowvv9c3983xqOmw2_5dqycaUPtalNYjjtZJmrFozfkZfDgFH2EAE6StjT9ELUs0jC8-ayUZX_96eGkcsmgdntHxMbpU5sXuJdd-aOoRSEvlx8_A63EVR1rRYRCT24IzsGgCbLfMJEz99K-EMA752EdxByXbLfhumUVS5IEvv_i2seZktlR5Mbd6njJ-GTxFS5EHVCadzCQjRhkWHEMyI2pdP1e6sVD3VUJXv0WTYrQdE1LS8Ed9i2aPpzJglO0fsNCmTaHNIJyXytmbWrlOYJ1sxx8eiqenMGy_5MKq4qE9RVm0KQ7CjJRp4MEZ0Z5RXhxdjzREWepCOG0G8ugaCk3nQrv4mtrX_7JdhenocYt0DI81BuISrZ3KvwJgqkeq6e9n3016jgXF8B3W_W6YflciN06V1u-l7UWG8e04Vfp1Ffl1NcjCdJKFGCz5j2ThHt2g3t0Ii1ttrutCS3__eDsXXxn-LW6JYmIWDXbpbOIWKUP5a9zyLb74PaSpnBzua4sJ510SiR_hbJr6q0ftv8Al8cs1HOT1ckomj4KBh8nCwNILQfkP4pEEk2X6O8hkgwOHKoZxvZPHwTJYvBWY9-__ue0nuhXq6xH5ch0O2P8cw_7PfgNKKemSM7dJObSQIsYBmgkF2j_7c8OvmVzrsj17174H8cMkf6BuGLAkeD1DusWv4-BMkU_CF4ZpCJVQ9a90LF-Gg0KTpo3GZQrPFsnbZQqPFsm5TCEz8dTMMhDw8ECPPVgnjHvoqLxleBmIkeFJ_ZOmMk6gNUnW3rqxtVVVijJOTmYr8QlZcsl9p4m2gXX7Ayy5fPmysbkVn3CrSrTd2EZXla5PzpXK9BeWubcerWN_WMB3Xl6SK7jHPd1HhW8I-Q4i8Sy0QX-RRXl2z_iye9m4tnFpdYW-tYG1M8--XWidKstpixGUgyNdKSy4A3b9Tii0MVi48vnne4FfaQXCu7sPNAGPjQ1f6gtCL3qrPfgL-4B3RsumQPsac-8hov2nPvmQ9lQJhgpFMH6_aJ3DF4-6oftr9hmhsSjhqK2ioIry9LC_pfo1kXmuGe0vtsln-tjKfDwbi1d4NFgIh_LuZKV89oUTyq6Utyy6cqbBU358R9OWXHv9Iucbx3hmQdflMwiwlShLUNbSNBvIsRCNRUok1ekYLAkmOA2FQXFqf_ctTok7VXsGFnbaQI2P4Pzy8H2zvHEgKB-VJZMCPqN5Jg_smnLQMe_b8vTIDbiDbvYHB-4gHGGpxDPkCI_auAMYpGubqvfzC7mK5DJaigtchekiTjPaUS4Oqyxe7vIkkUmWSpnkWZJjFmexFHlYLOIguVArHvAoSHgY0g6VzXeZ3EXFAhcR3y1jFCwOsBKqnNPWM9dmf-F9tEr5IoouSpFjaf1LC86JcOdA2oEuzMpvV3mztywOSmWdPVtxypW4mrxc6N8s-NcGQ9_6bJkucvrv3wfAoPN70ZhydXDu6HOdbxnf7pU7NPm80NXgBBsfMx42bYGe1v8DAAD__3pYsGc">