diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp --- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -1673,7 +1673,6 @@ bool validateMIMGDataSize(const MCInst &Inst, const SMLoc &IDLoc); bool validateMIMGAddrSize(const MCInst &Inst); bool validateMIMGD16(const MCInst &Inst); - bool validateMIMGDim(const MCInst &Inst); bool validateMIMGMSAA(const MCInst &Inst); bool validateOpSel(const MCInst &Inst); bool validateDPP(const MCInst &Inst, const OperandVector &Operands); @@ -3956,24 +3955,6 @@ return true; } -bool AMDGPUAsmParser::validateMIMGDim(const MCInst &Inst) { - const unsigned Opc = Inst.getOpcode(); - const MCInstrDesc &Desc = MII.get(Opc); - - if ((Desc.TSFlags & SIInstrFlags::MIMG) == 0) - return true; - - int DimIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::dim); - if (DimIdx < 0) - return true; - - int64_t Imm = Inst.getOperand(DimIdx).getImm(); - if (Imm < 0 || Imm >= 8) - return false; - - return true; -} - static bool IsRevOpcode(const unsigned Opcode) { switch (Opcode) { @@ -4617,18 +4598,8 @@ if ((TSFlags & (SIInstrFlags::VALU | Enc)) != (SIInstrFlags::VALU | Enc)) return true; - // This is FLAT/MUBUF LDS DMA. - - SMLoc S = getImmLoc(AMDGPUOperand::ImmTyLDS, Operands); - StringRef CStr(S.getPointer()); - if (!CStr.startswith("lds")) { - // This is incorrectly selected LDS DMA version of a FLAT/MUBUF load - // opcode. And LDS version should have 'lds' modifier, but it follows - // optional operands so its absense is ignored by the matcher. - Error(IDLoc, "missing dst operand or lds modifier"); - return false; - } + // This is FLAT/MUBUF LDS DMA. return true; } @@ -4688,10 +4659,6 @@ "d16 modifier is not supported on this GPU"); return false; } - if (!validateMIMGDim(Inst)) { - Error(IDLoc, "dim modifier is required on this GPU"); - return false; - } if (!validateMIMGMSAA(Inst)) { Error(getImmLoc(AMDGPUOperand::ImmTyDim, Operands), "invalid dim; must be MSAA type"); diff --git a/llvm/test/MC/AMDGPU/gfx10_err_pos.s b/llvm/test/MC/AMDGPU/gfx10_err_pos.s --- a/llvm/test/MC/AMDGPU/gfx10_err_pos.s +++ b/llvm/test/MC/AMDGPU/gfx10_err_pos.s @@ -4,7 +4,7 @@ // dim modifier is required on this GPU image_atomic_add v252, v2, s[8:15] -// CHECK: error: dim modifier is required on this GPU +// CHECK: error: operands are not valid for this GPU or mode // CHECK-NEXT:{{^}}image_atomic_add v252, v2, s[8:15] // CHECK-NEXT:{{^}}^ @@ -970,12 +970,12 @@ // missing dst operand or lds modifier buffer_load_dword off, s[8:11], s3 -// CHECK: error: missing dst operand or lds modifier +// CHECK: error: too few operands for instruction // CHECK-NEXT:{{^}}buffer_load_dword off, s[8:11], s3 // CHECK-NEXT:{{^}}^ buffer_load_dword off, s[8:11], s3 offset:1 -// CHECK: error: missing dst operand or lds modifier +// CHECK: error: too few operands for instruction // CHECK-NEXT:{{^}}buffer_load_dword off, s[8:11], s3 offset:1 // CHECK-NEXT:{{^}}^ diff --git a/llvm/test/MC/AMDGPU/gfx9-asm-err.s b/llvm/test/MC/AMDGPU/gfx9-asm-err.s --- a/llvm/test/MC/AMDGPU/gfx9-asm-err.s +++ b/llvm/test/MC/AMDGPU/gfx9-asm-err.s @@ -37,7 +37,7 @@ // GFX9ERR: error: instruction not supported on this GPU global_load_dword v[2:3], off -// GFX9ERR: error: missing dst operand or lds modifier +// GFX9ERR: error: too few operands for instruction scratch_load_dword v2, off, offset:256 -// GFX9ERR: error: missing dst operand or lds modifier +// GFX9ERR: error: too few operands for instruction diff --git a/llvm/test/MC/AMDGPU/gfx9_err_pos.s b/llvm/test/MC/AMDGPU/gfx9_err_pos.s --- a/llvm/test/MC/AMDGPU/gfx9_err_pos.s +++ b/llvm/test/MC/AMDGPU/gfx9_err_pos.s @@ -182,12 +182,12 @@ // missing dst operand or lds modifier buffer_load_dword off, s[8:11], s3 -// CHECK: error: missing dst operand or lds modifier +// CHECK: error: too few operands for instruction // CHECK-NEXT:{{^}}buffer_load_dword off, s[8:11], s3 // CHECK-NEXT:{{^}}^ buffer_load_dword off, s[8:11], s3 offset:1 -// CHECK: error: missing dst operand or lds modifier +// CHECK: error: too few operands for instruction // CHECK-NEXT:{{^}}buffer_load_dword off, s[8:11], s3 offset:1 // CHECK-NEXT:{{^}}^ diff --git a/llvm/test/MC/AMDGPU/mubuf.s b/llvm/test/MC/AMDGPU/mubuf.s --- a/llvm/test/MC/AMDGPU/mubuf.s +++ b/llvm/test/MC/AMDGPU/mubuf.s @@ -862,7 +862,7 @@ // NOVI: error: invalid operand for instruction buffer_load_dword off, s[8:11], s3 -// NOSICIVI: error: missing dst operand or lds modifier +// NOSICIVI: error: too few operands for instruction buffer_load_dword off, s[8:11], s3 offset:1 -// NOSICIVI: error: missing dst operand or lds modifier +// NOSICIVI: error: too few operands for instruction diff --git a/llvm/test/MC/SystemZ/asm-match.s b/llvm/test/MC/SystemZ/asm-match.s --- a/llvm/test/MC/SystemZ/asm-match.s +++ b/llvm/test/MC/SystemZ/asm-match.s @@ -8,53 +8,91 @@ // CHECK: Matching formal operand class MCK_GR64 against actual operand at index 1 (Reg:r3): match success using generic matcher // CHECK: Matching formal operand class MCK_GR64 against actual operand at index 2 (Reg:r0): match success using generic matcher // CHECK: Matching formal operand class MCK_BDAddr32Disp20 against actual operand at index 3 (Mem:3): match success using generic matcher -// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range Opcode result: complete match, selecting this opcode +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 5: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 6: actual operand index out of range +// CHECK: Opcode result: complete match, selecting this opcode // CHECK: AsmMatcher: found 1 encodings with mnemonic 'llill' // CHECK: Trying to match opcode LLILL // CHECK: Matching formal operand class MCK_GR64 against actual operand at index 1 (Reg:r0): match success using generic matcher // CHECK: Matching formal operand class MCK_U16Imm against actual operand at index 2 (Imm:0): match success using generic matcher -// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range Opcode result: complete match, selecting this opcode +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 5: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 6: actual operand index out of range +// CHECK: Opcode result: complete match, selecting this opcode // CHECK: AsmMatcher: found 1 encodings with mnemonic 'lgr' // CHECK: Trying to match opcode LGR // CHECK: Matching formal operand class MCK_GR64 against actual operand at index 1 (Reg:r1): match success using generic matcher // CHECK: Matching formal operand class MCK_GR64 against actual operand at index 2 (Reg:r0): match success using generic matcher -// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range Opcode result: complete match, selecting this opcode +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 5: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 6: actual operand index out of range +// CHECK: Opcode result: complete match, selecting this opcode // CHECK: AsmMatcher: found 1 encodings with mnemonic 'lg' // CHECK: Trying to match opcode LG // CHECK: Matching formal operand class MCK_GR64 against actual operand at index 1 (Reg:r1): match success using generic matcher // CHECK: Matching formal operand class MCK_BDXAddr64Disp20 against actual operand at index 2 (Mem:16(r2)): match success using generic matcher -// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range Opcode result: complete match, selecting this opcode +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 5: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 6: actual operand index out of range +// CHECK: Opcode result: complete match, selecting this opcode // CHECK: AsmMatcher: found 1 encodings with mnemonic 'lg' // CHECK: Trying to match opcode LG // CHECK: Matching formal operand class MCK_GR64 against actual operand at index 1 (Reg:r1): match success using generic matcher // CHECK: Matching formal operand class MCK_BDXAddr64Disp20 against actual operand at index 2 (Mem:16(r2,r3)): match success using generic matcher -// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range Opcode result: complete match, selecting this opcode +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 5: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 6: actual operand index out of range +// CHECK: Opcode result: complete match, selecting this opcode // CHECK: AsmMatcher: found 1 encodings with mnemonic 'stmg' // CHECK: Trying to match opcode STMG // CHECK: Matching formal operand class MCK_GR64 against actual operand at index 1 (Reg:r13): match success using generic matcher // CHECK: Matching formal operand class MCK_GR64 against actual operand at index 2 (Reg:r15): match success using generic matcher // CHECK: Matching formal operand class MCK_BDAddr64Disp20 against actual operand at index 3 (Mem:104(r15)): match success using generic matcher -// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range Opcode result: complete match, selecting this opcode +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 5: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 6: actual operand index out of range +// CHECK: Opcode result: complete match, selecting this opcode // CHECK: AsmMatcher: found 1 encodings with mnemonic 'mvc' // CHECK: Trying to match opcode MVC // CHECK: Matching formal operand class MCK_BDLAddr64Disp12Len8 against actual operand at index 1 (Mem:184(8,r15)): match success using generic matcher // CHECK: Matching formal operand class MCK_BDAddr64Disp12 against actual operand at index 2 (Mem:8(r2)): match success using generic matcher -// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range Opcode result: complete match, selecting this opcode +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 5: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 6: actual operand index out of range +// CHECK: Opcode result: complete match, selecting this opcode // CHECK: AsmMatcher: found 1 encodings with mnemonic 'mvck' // CHECK: Trying to match opcode MVCK // CHECK: Matching formal operand class MCK_BDRAddr64Disp12 against actual operand at index 1 (Mem:0(r0,r1)): match success using generic matcher // CHECK: Matching formal operand class MCK_BDAddr64Disp12 against actual operand at index 2 (Mem:4095(r15)): match success using generic matcher // CHECK: Matching formal operand class MCK_GR64 against actual operand at index 3 (Reg:r2): match success using generic matcher -// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range Opcode result: complete match, selecting this opcode +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 5: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 6: actual operand index out of range +// CHECK: Opcode result: complete match, selecting this opcode // CHECK: AsmMatcher: found 1 encodings with mnemonic 'j' // CHECK: Trying to match opcode J // CHECK: Matching formal operand class MCK_PCRel16 against actual operand at index 1 (Imm:.Ltmp0+2): match success using generic matcher -// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 2: actual operand index out of range Opcode result: complete match, selecting this opcode +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 2: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 5: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 6: actual operand index out of range +// CHECK: Opcode result: complete match, selecting this opcode // CHECK: AsmMatcher: found 1 encodings with mnemonic 'brasl' // CHECK: Trying to match opcode BRASL // CHECK: Matching formal operand class MCK_GR64 against actual operand at index 1 (Reg:r14): match success using generic matcher // CHECK: Matching formal operand class MCK_PCRelTLS32 against actual operand at index 2 (ImmTLS:fun): match success using generic matcher -// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range Opcode result: complete match, selecting this opcode +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 5: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 6: actual operand index out of range +// CHECK: Opcode result: complete match, selecting this opcode // CHECK: .text // CHECK: sllg %r3, %r0, 3 // CHECK: llill %r0, 0 diff --git a/llvm/test/MC/X86/x86_64-asm-match.s b/llvm/test/MC/X86/x86_64-asm-match.s --- a/llvm/test/MC/X86/x86_64-asm-match.s +++ b/llvm/test/MC/X86/x86_64-asm-match.s @@ -9,13 +9,23 @@ // CHECK: Trying to match opcode PSHUFBrm // CHECK: Matching formal operand class MCK_Mem128 against actual operand at index 1 (Memory: ModeSize=64,BaseReg=rip,Scale=1,Disp=CPI1_0): match success using generic matcher // CHECK: Matching formal operand class MCK_FR16 against actual operand at index 2 (Reg:xmm1): match success using generic matcher -// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range Opcode result: complete match, selecting this opcode +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 5: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 6: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 7: actual operand index out of range +// CHECK: Opcode result: complete match, selecting this opcode // CHECK: AsmMatcher: found 2 encodings with mnemonic 'sha1rnds4' // CHECK: Trying to match opcode SHA1RNDS4rri // CHECK: Matching formal operand class MCK_ImmUnsignedi8 against actual operand at index 1 (Imm:1): match success using generic matcher // CHECK: Matching formal operand class MCK_FR16 against actual operand at index 2 (Reg:xmm1): match success using generic matcher // CHECK: Matching formal operand class MCK_FR16 against actual operand at index 3 (Reg:xmm2): match success using generic matcher -// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range Opcode result: complete match, selecting this opcode +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 5: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 6: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 7: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 8: actual operand index out of range +// CHECK: Opcode result: complete match, selecting this opcode // CHECK: AsmMatcher: found 4 encodings with mnemonic 'pinsrw' // CHECK: Trying to match opcode MMX_PINSRWrr // CHECK: Matching formal operand class MCK_ImmUnsignedi8 against actual operand at index 1 (Imm:3): match success using generic matcher @@ -25,14 +35,24 @@ // CHECK: Matching formal operand class MCK_ImmUnsignedi8 against actual operand at index 1 (Imm:3): match success using generic matcher // CHECK: Matching formal operand class MCK_GR32orGR64 against actual operand at index 2 (Reg:ecx): match success using generic matcher // CHECK: Matching formal operand class MCK_FR16 against actual operand at index 3 (Reg:xmm5): match success using generic matcher -// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range Opcode result: complete match, selecting this opcode +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 5: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 6: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 7: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 8: actual operand index out of range +// CHECK: Opcode result: complete match, selecting this opcode // CHECK: AsmMatcher: found 2 encodings with mnemonic 'crc32l' // CHECK: Trying to match opcode CRC32r32r32 // CHECK: Matching formal operand class MCK_GR32 against actual operand at index 1 (Memory: ModeSize=64,BaseReg=rbx,IndexReg=rcx,Scale=8,Disp=3735928559,SegReg=gs): Opcode result: multiple operand mismatches, ignoring this opcode // CHECK: Trying to match opcode CRC32r32m32 // CHECK: Matching formal operand class MCK_Mem32 against actual operand at index 1 (Memory: ModeSize=64,BaseReg=rbx,IndexReg=rcx,Scale=8,Disp=3735928559,SegReg=gs): match success using generic matcher // CHECK: Matching formal operand class MCK_GR32 against actual operand at index 2 (Reg:ecx): match success using generic matcher -// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range Opcode result: complete match, selecting this opcode +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 5: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 6: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 7: actual operand index out of range +// CHECK: Opcode result: complete match, selecting this opcode // CHECK: AsmMatcher: found 4 encodings with mnemonic 'punpcklbw' // CHECK: Trying to match opcode MMX_PUNPCKLBWrr // CHECK: Matching formal operand class MCK_VR64 against actual operand at index 1 (Reg:mm0): match success using generic matcher @@ -40,7 +60,12 @@ // CHECK: Trying to match opcode MMX_PUNPCKLBWrm // CHECK: Matching formal operand class MCK_VR64 against actual operand at index 1 (Reg:mm0): match success using generic matcher // CHECK: Matching formal operand class MCK_Mem32 against actual operand at index 2 (Memory: ModeSize=64,Size=32,BaseReg=rsp,Scale=1): match success using generic matcher -// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range Opcode result: complete match, selecting this opcode +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 5: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 6: actual operand index out of range +// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 7: actual operand index out of range +// CHECK: Opcode result: complete match, selecting this opcode pshufb CPI1_0(%rip), %xmm1 sha1rnds4 $1, %xmm1, %xmm2 diff --git a/llvm/utils/TableGen/AsmMatcherEmitter.cpp b/llvm/utils/TableGen/AsmMatcherEmitter.cpp --- a/llvm/utils/TableGen/AsmMatcherEmitter.cpp +++ b/llvm/utils/TableGen/AsmMatcherEmitter.cpp @@ -3666,7 +3666,8 @@ OS << " else\n"; OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \": \");\n"; OS << " if (ActualIdx >= Operands.size()) {\n"; - OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"actual operand index out of range \");\n"; + OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"actual operand " + "index out of range\\n\");\n"; if (ReportMultipleNearMisses) { OS << " bool ThisOperandValid = (Formal == " <<"InvalidMatchClass) || " "isSubclass(Formal, OptionalMatchClass);\n"; @@ -3686,16 +3687,21 @@ OS << " }\n"; OS << " } else {\n"; OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"but formal operand not required\\n\");\n"; - OS << " break;\n"; + OS << " ++ActualIdx;\n"; OS << " }\n"; OS << " continue;\n"; } else { - OS << " OperandsValid = (Formal == InvalidMatchClass) || isSubclass(Formal, OptionalMatchClass);\n"; - OS << " if (!OperandsValid) ErrorInfo = ActualIdx;\n"; if (HasOptionalOperands) { OS << " OptionalOperandsMask.set(FormalIdx, " << MaxNumOperands << ");\n"; } + OS << " OperandsValid = (Formal == InvalidMatchClass) || " + "isSubclass(Formal, OptionalMatchClass);\n"; + OS << " if (OperandsValid) {\n"; + OS << " ++ActualIdx;\n"; + OS << " continue;\n"; + OS << " }\n"; + OS << " ErrorInfo = ActualIdx;\n"; OS << " break;\n"; } OS << " }\n";