Index: llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp =================================================================== --- llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp +++ llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp @@ -1847,13 +1847,25 @@ CvtOS << " assert(Kind < CVT_NUM_SIGNATURES && \"Invalid signature!\");\n"; CvtOS << " const uint8_t *Converter = ConversionTable[Kind];\n"; if (HasOptionalOperands) { - CvtOS << " unsigned NumDefaults = 0;\n"; + size_t MaxNumOperands = 0; + for (const auto &MI : Infos) { + MaxNumOperands = std::max(MaxNumOperands, MI->AsmOperands.size()); + } + CvtOS << " unsigned DefaultsOffset[" << (MaxNumOperands + 1) + << "] = { 0 };\n"; + CvtOS << " assert(OptionalOperandsMask.size() == " << (MaxNumOperands) + << ");\n"; + CvtOS << " for (unsigned i = 0, NumDefaults = 0; i < " << (MaxNumOperands) + << "; ++i) {\n"; + CvtOS << " DefaultsOffset[i + 1] = NumDefaults;\n"; + CvtOS << " NumDefaults += (OptionalOperandsMask[i] ? 1 : 0);\n"; + CvtOS << " }\n"; } CvtOS << " unsigned OpIdx;\n"; CvtOS << " Inst.setOpcode(Opcode);\n"; CvtOS << " for (const uint8_t *p = Converter; *p; p+= 2) {\n"; if (HasOptionalOperands) { - CvtOS << " OpIdx = *(p + 1) - NumDefaults;\n"; + CvtOS << " OpIdx = *(p + 1) - DefaultsOffset[*(p + 1)];\n"; } else { CvtOS << " OpIdx = *(p + 1);\n"; } @@ -1988,7 +2000,6 @@ << " " << Op.Class->DefaultMethod << "()" << "->" << Op.Class->RenderMethod << "(Inst, " << OpInfo.MINumOperands << ");\n" - << " ++NumDefaults;\n" << " } else {\n" << " static_cast<" << TargetOperandClass << "&>(*Operands[OpIdx])." << Op.Class->RenderMethod