diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp --- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp +++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp @@ -545,9 +545,6 @@ bool assignRegisterTies(MachineInstr &MI, ArrayRef Operands); - bool verifyImplicitOperands(ArrayRef Operands, - const MCInstrDesc &MCID); - const BasicBlock *getIRBlock(unsigned Slot); const BasicBlock *getIRBlock(unsigned Slot, const Function &F); @@ -1116,12 +1113,6 @@ } const auto &MCID = MF.getSubtarget().getInstrInfo()->get(OpCode); - if (!MCID.isVariadic()) { - // FIXME: Move the implicit operand verification to the machine verifier. - if (verifyImplicitOperands(Operands, MCID)) - return true; - } - MI = MF.CreateMachineInstr(MCID, DebugLocation, /*NoImplicit=*/true); MI->setFlags(Flags); @@ -1364,58 +1355,6 @@ return false; } -static const char *printImplicitRegisterFlag(const MachineOperand &MO) { - assert(MO.isImplicit()); - return MO.isDef() ? "implicit-def" : "implicit"; -} - -static std::string getRegisterName(const TargetRegisterInfo *TRI, - Register Reg) { - assert(Register::isPhysicalRegister(Reg) && "expected phys reg"); - return StringRef(TRI->getName(Reg)).lower(); -} - -/// Return true if the parsed machine operands contain a given machine operand. -static bool isImplicitOperandIn(const MachineOperand &ImplicitOperand, - ArrayRef Operands) { - for (const auto &I : Operands) { - if (ImplicitOperand.isIdenticalTo(I.Operand)) - return true; - } - return false; -} - -bool MIParser::verifyImplicitOperands(ArrayRef Operands, - const MCInstrDesc &MCID) { - if (MCID.isCall()) - // We can't verify call instructions as they can contain arbitrary implicit - // register and register mask operands. - return false; - - // Gather all the expected implicit operands. - SmallVector ImplicitOperands; - if (MCID.getImplicitDefs()) - for (const MCPhysReg *ImpDefs = MCID.getImplicitDefs(); *ImpDefs; ++ImpDefs) - ImplicitOperands.push_back( - MachineOperand::CreateReg(*ImpDefs, true, true)); - if (MCID.getImplicitUses()) - for (const MCPhysReg *ImpUses = MCID.getImplicitUses(); *ImpUses; ++ImpUses) - ImplicitOperands.push_back( - MachineOperand::CreateReg(*ImpUses, false, true)); - - const auto *TRI = MF.getSubtarget().getRegisterInfo(); - assert(TRI && "Expected target register info"); - for (const auto &I : ImplicitOperands) { - if (isImplicitOperandIn(I, Operands)) - continue; - return error(Operands.empty() ? Token.location() : Operands.back().End, - Twine("missing implicit register operand '") + - printImplicitRegisterFlag(I) + " $" + - getRegisterName(TRI, I.getReg()) + "'"); - } - return false; -} - bool MIParser::parseInstruction(unsigned &OpCode, unsigned &Flags) { // Allow frame and fast math flags for OPCODE while (Token.is(MIToken::kw_frame_setup) || diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp --- a/llvm/lib/CodeGen/MachineVerifier.cpp +++ b/llvm/lib/CodeGen/MachineVerifier.cpp @@ -1759,6 +1759,28 @@ << MI->getNumOperands() << " given.\n"; } + if (MCID.getImplicitDefs()) { + for (const MCPhysReg *I = MCID.getImplicitDefs(); *I; ++I) { + if (none_of(MI->implicit_operands(), [I](const MachineOperand &Op) { + return Op.isReg() && Op.isDef() && Op.getReg() == *I; + })) { + report("Missing implicit def", MI); + report_context(MCPhysReg(*I)); + } + } + } + + if (MCID.getImplicitUses()) { + for (const MCPhysReg *I = MCID.getImplicitUses(); *I; ++I) { + if (none_of(MI->implicit_operands(), [I](const MachineOperand &Op) { + return Op.isReg() && Op.isUse() && Op.getReg() == *I; + })) { + report("Missing implicit use", MI); + report_context(MCPhysReg(*I)); + } + } + } + if (MI->isPHI()) { if (MF->getProperties().hasProperty( MachineFunctionProperties::Property::NoPHIs))