MachineVerifier: Move verification of G_* instructions to function

llvm-svn: 353111
This commit is contained in:
Matt Arsenault 2019-02-04 23:29:11 +00:00
parent d2a42c3815
commit 46f9c6cf0b
1 changed files with 116 additions and 99 deletions

View File

@ -230,6 +230,8 @@ namespace {
void visitMachineFunctionBefore();
void visitMachineBasicBlockBefore(const MachineBasicBlock *MBB);
void visitMachineBundleBefore(const MachineInstr *MI);
void verifyPreISelGenericInstruction(const MachineInstr *MI);
void visitMachineInstrBefore(const MachineInstr *MI);
void visitMachineOperand(const MachineOperand *MO, unsigned MONum);
void visitMachineInstrAfter(const MachineInstr *MI);
@ -888,58 +890,11 @@ void MachineVerifier::verifyInlineAsm(const MachineInstr *MI) {
}
}
void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) {
const MCInstrDesc &MCID = MI->getDesc();
if (MI->getNumOperands() < MCID.getNumOperands()) {
report("Too few operands", MI);
errs() << MCID.getNumOperands() << " operands expected, but "
<< MI->getNumOperands() << " given.\n";
}
if (MI->isPHI()) {
if (MF->getProperties().hasProperty(
MachineFunctionProperties::Property::NoPHIs))
report("Found PHI instruction with NoPHIs property set", MI);
if (FirstNonPHI)
report("Found PHI instruction after non-PHI", MI);
} else if (FirstNonPHI == nullptr)
FirstNonPHI = MI;
// Check the tied operands.
if (MI->isInlineAsm())
verifyInlineAsm(MI);
// Check the MachineMemOperands for basic consistency.
for (MachineInstr::mmo_iterator I = MI->memoperands_begin(),
E = MI->memoperands_end();
I != E; ++I) {
if ((*I)->isLoad() && !MI->mayLoad())
report("Missing mayLoad flag", MI);
if ((*I)->isStore() && !MI->mayStore())
report("Missing mayStore flag", MI);
}
// Debug values must not have a slot index.
// Other instructions must have one, unless they are inside a bundle.
if (LiveInts) {
bool mapped = !LiveInts->isNotInMIMap(*MI);
if (MI->isDebugInstr()) {
if (mapped)
report("Debug instruction has a slot index", MI);
} else if (MI->isInsideBundle()) {
if (mapped)
report("Instruction inside bundle has a slot index", MI);
} else {
if (!mapped)
report("Missing slot index", MI);
}
}
if (isPreISelGenericOpcode(MCID.getOpcode())) {
void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
if (isFunctionSelected)
report("Unexpected generic instruction in a Selected function", MI);
const MCInstrDesc &MCID = MI->getDesc();
unsigned NumOps = MI->getNumOperands();
// Check types.
@ -980,16 +935,13 @@ void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) {
// Avoid out of bounds in checks below. This was already reported earlier.
if (MI->getNumOperands() < MCID.getNumOperands())
return;
}
StringRef ErrorInfo;
if (!TII->verifyInstruction(*MI, ErrorInfo))
report(ErrorInfo.data(), MI);
// Verify properties of various specific instruction types
switch(MI->getOpcode()) {
default:
break;
switch (MI->getOpcode()) {
case TargetOpcode::G_CONSTANT:
case TargetOpcode::G_FCONSTANT: {
if (MI->getNumOperands() < MCID.getNumOperands())
@ -1238,6 +1190,81 @@ void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) {
report("G_CONCAT_VECTOR num dest and source elements should match", MI);
break;
}
case TargetOpcode::G_ICMP:
case TargetOpcode::G_FCMP: {
LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
LLT SrcTy = MRI->getType(MI->getOperand(2).getReg());
if ((DstTy.isVector() != SrcTy.isVector()) ||
(DstTy.isVector() && DstTy.getNumElements() != SrcTy.getNumElements()))
report("Generic vector icmp/fcmp must preserve number of lanes", MI);
break;
}
default:
break;
}
}
void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) {
const MCInstrDesc &MCID = MI->getDesc();
if (MI->getNumOperands() < MCID.getNumOperands()) {
report("Too few operands", MI);
errs() << MCID.getNumOperands() << " operands expected, but "
<< MI->getNumOperands() << " given.\n";
}
if (MI->isPHI()) {
if (MF->getProperties().hasProperty(
MachineFunctionProperties::Property::NoPHIs))
report("Found PHI instruction with NoPHIs property set", MI);
if (FirstNonPHI)
report("Found PHI instruction after non-PHI", MI);
} else if (FirstNonPHI == nullptr)
FirstNonPHI = MI;
// Check the tied operands.
if (MI->isInlineAsm())
verifyInlineAsm(MI);
// Check the MachineMemOperands for basic consistency.
for (MachineInstr::mmo_iterator I = MI->memoperands_begin(),
E = MI->memoperands_end();
I != E; ++I) {
if ((*I)->isLoad() && !MI->mayLoad())
report("Missing mayLoad flag", MI);
if ((*I)->isStore() && !MI->mayStore())
report("Missing mayStore flag", MI);
}
// Debug values must not have a slot index.
// Other instructions must have one, unless they are inside a bundle.
if (LiveInts) {
bool mapped = !LiveInts->isNotInMIMap(*MI);
if (MI->isDebugInstr()) {
if (mapped)
report("Debug instruction has a slot index", MI);
} else if (MI->isInsideBundle()) {
if (mapped)
report("Instruction inside bundle has a slot index", MI);
} else {
if (!mapped)
report("Missing slot index", MI);
}
}
if (isPreISelGenericOpcode(MCID.getOpcode())) {
verifyPreISelGenericInstruction(MI);
return;
}
StringRef ErrorInfo;
if (!TII->verifyInstruction(*MI, ErrorInfo))
report(ErrorInfo.data(), MI);
// Verify properties of various specific instruction types
switch (MI->getOpcode()) {
case TargetOpcode::COPY: {
if (foundErrors)
break;
@ -1268,17 +1295,6 @@ void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) {
}
break;
}
case TargetOpcode::G_ICMP:
case TargetOpcode::G_FCMP: {
LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
LLT SrcTy = MRI->getType(MI->getOperand(2).getReg());
if ((DstTy.isVector() != SrcTy.isVector()) ||
(DstTy.isVector() && DstTy.getNumElements() != SrcTy.getNumElements()))
report("Generic vector icmp/fcmp must preserve number of lanes", MI);
break;
}
case TargetOpcode::STATEPOINT:
if (!MI->getOperand(StatepointOpers::IDPos).isImm() ||
!MI->getOperand(StatepointOpers::NBytesPos).isImm() ||
@ -1298,7 +1314,8 @@ void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) {
VerifyStackMapConstant(VarStart + StatepointOpers::NumDeoptOperandsOffset);
// TODO: verify we have properly encoded deopt arguments
};
break;
}
}
void