Skip to content

Commit

Permalink
MachineVerifier: Improve register operand checks
Browse files Browse the repository at this point in the history
This fixes cases where we wouldn't perform various register operand
checks just because we didn't happen to have a definition in the
MCInstrDesc. This changes the code to only skip the tests that actually
depend on the MCInstrDesc definition.

This makes the machine verifier spot the problem from
https://llvm.org/PR33071 after the pass that actually caused it.

llvm-svn: 319141
  • Loading branch information
MatzeB committed Nov 28, 2017
1 parent a6d5374 commit eca9858
Showing 1 changed file with 81 additions and 78 deletions.
159 changes: 81 additions & 78 deletions llvm/lib/CodeGen/MachineVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1085,14 +1085,14 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
report("Two-address instruction operands must be identical", MO, MONum);

// Check register classes.
if (MONum < MCID.getNumOperands() && !MO->isImplicit()) {
unsigned SubIdx = MO->getSubReg();
unsigned SubIdx = MO->getSubReg();

if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
if (SubIdx) {
report("Illegal subregister index for physical register", MO, MONum);
return;
}
if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
if (SubIdx) {
report("Illegal subregister index for physical register", MO, MONum);
return;
}
if (MONum < MCID.getNumOperands()) {
if (const TargetRegisterClass *DRC =
TII->getRegClass(MCID, MONum, TRI, *MF)) {
if (!DRC->contains(Reg)) {
Expand All @@ -1101,85 +1101,88 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
<< TRI->getRegClassName(DRC) << " register.\n";
}
}
} else {
// Virtual register.
const TargetRegisterClass *RC = MRI->getRegClassOrNull(Reg);
if (!RC) {
// This is a generic virtual register.

// If we're post-Select, we can't have gvregs anymore.
if (isFunctionSelected) {
report("Generic virtual register invalid in a Selected function",
MO, MONum);
return;
}
}
} else {
// Virtual register.
const TargetRegisterClass *RC = MRI->getRegClassOrNull(Reg);
if (!RC) {
// This is a generic virtual register.

// If we're post-Select, we can't have gvregs anymore.
if (isFunctionSelected) {
report("Generic virtual register invalid in a Selected function",
MO, MONum);
return;
}

// The gvreg must have a type and it must not have a SubIdx.
LLT Ty = MRI->getType(Reg);
if (!Ty.isValid()) {
report("Generic virtual register must have a valid type", MO,
MONum);
return;
}
// The gvreg must have a type and it must not have a SubIdx.
LLT Ty = MRI->getType(Reg);
if (!Ty.isValid()) {
report("Generic virtual register must have a valid type", MO,
MONum);
return;
}

const RegisterBank *RegBank = MRI->getRegBankOrNull(Reg);
const RegisterBank *RegBank = MRI->getRegBankOrNull(Reg);

// If we're post-RegBankSelect, the gvreg must have a bank.
if (!RegBank && isFunctionRegBankSelected) {
report("Generic virtual register must have a bank in a "
"RegBankSelected function",
MO, MONum);
return;
}
// If we're post-RegBankSelect, the gvreg must have a bank.
if (!RegBank && isFunctionRegBankSelected) {
report("Generic virtual register must have a bank in a "
"RegBankSelected function",
MO, MONum);
return;
}

// Make sure the register fits into its register bank if any.
if (RegBank && Ty.isValid() &&
RegBank->getSize() < Ty.getSizeInBits()) {
report("Register bank is too small for virtual register", MO,
MONum);
errs() << "Register bank " << RegBank->getName() << " too small("
<< RegBank->getSize() << ") to fit " << Ty.getSizeInBits()
<< "-bits\n";
return;
}
if (SubIdx) {
report("Generic virtual register does not subregister index", MO,
MONum);
return;
}
// Make sure the register fits into its register bank if any.
if (RegBank && Ty.isValid() &&
RegBank->getSize() < Ty.getSizeInBits()) {
report("Register bank is too small for virtual register", MO,
MONum);
errs() << "Register bank " << RegBank->getName() << " too small("
<< RegBank->getSize() << ") to fit " << Ty.getSizeInBits()
<< "-bits\n";
return;
}
if (SubIdx) {
report("Generic virtual register does not subregister index", MO,
MONum);
return;
}

// If this is a target specific instruction and this operand
// has register class constraint, the virtual register must
// comply to it.
if (!isPreISelGenericOpcode(MCID.getOpcode()) &&
TII->getRegClass(MCID, MONum, TRI, *MF)) {
report("Virtual register does not match instruction constraint", MO,
MONum);
errs() << "Expect register class "
<< TRI->getRegClassName(
TII->getRegClass(MCID, MONum, TRI, *MF))
<< " but got nothing\n";
return;
}
// If this is a target specific instruction and this operand
// has register class constraint, the virtual register must
// comply to it.
if (!isPreISelGenericOpcode(MCID.getOpcode()) &&
MONum < MCID.getNumOperands() &&
TII->getRegClass(MCID, MONum, TRI, *MF)) {
report("Virtual register does not match instruction constraint", MO,
MONum);
errs() << "Expect register class "
<< TRI->getRegClassName(
TII->getRegClass(MCID, MONum, TRI, *MF))
<< " but got nothing\n";
return;
}

break;
break;
}
if (SubIdx) {
const TargetRegisterClass *SRC =
TRI->getSubClassWithSubReg(RC, SubIdx);
if (!SRC) {
report("Invalid subregister index for virtual register", MO, MONum);
errs() << "Register class " << TRI->getRegClassName(RC)
<< " does not support subreg index " << SubIdx << "\n";
return;
}
if (SubIdx) {
const TargetRegisterClass *SRC =
TRI->getSubClassWithSubReg(RC, SubIdx);
if (!SRC) {
report("Invalid subregister index for virtual register", MO, MONum);
errs() << "Register class " << TRI->getRegClassName(RC)
<< " does not support subreg index " << SubIdx << "\n";
return;
}
if (RC != SRC) {
report("Invalid register class for subregister index", MO, MONum);
errs() << "Register class " << TRI->getRegClassName(RC)
<< " does not fully support subreg index " << SubIdx << "\n";
return;
}
if (RC != SRC) {
report("Invalid register class for subregister index", MO, MONum);
errs() << "Register class " << TRI->getRegClassName(RC)
<< " does not fully support subreg index " << SubIdx << "\n";
return;
}
}
if (MONum < MCID.getNumOperands()) {
if (const TargetRegisterClass *DRC =
TII->getRegClass(MCID, MONum, TRI, *MF)) {
if (SubIdx) {
Expand Down

0 comments on commit eca9858

Please sign in to comment.