Fix sub-register operand verification.

PhysReg operands are not allowed to have sub-register indices at all.

For virtual registers with sub-reg indices, check that all registers in
the register class support the sub-reg index.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141220 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jakob Stoklund Olesen 2011-10-05 22:12:57 +00:00
parent ef8a4c2a65
commit b4a0221e85

View File

@ -735,20 +735,14 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
unsigned SubIdx = MO->getSubReg(); unsigned SubIdx = MO->getSubReg();
if (TargetRegisterInfo::isPhysicalRegister(Reg)) { if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
unsigned sr = Reg;
if (SubIdx) { if (SubIdx) {
unsigned s = TRI->getSubReg(Reg, SubIdx); report("Illegal subregister index for physical register", MO, MONum);
if (!s) { return;
report("Invalid subregister index for physical register",
MO, MONum);
return;
}
sr = s;
} }
if (const TargetRegisterClass *DRC = TII->getRegClass(MCID,MONum,TRI)) { if (const TargetRegisterClass *DRC = TII->getRegClass(MCID,MONum,TRI)) {
if (!DRC->contains(sr)) { if (!DRC->contains(Reg)) {
report("Illegal physical register for instruction", MO, MONum); report("Illegal physical register for instruction", MO, MONum);
*OS << TRI->getName(sr) << " is not a " *OS << TRI->getName(Reg) << " is not a "
<< DRC->getName() << " register.\n"; << DRC->getName() << " register.\n";
} }
} }
@ -756,16 +750,35 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
// Virtual register. // Virtual register.
const TargetRegisterClass *RC = MRI->getRegClass(Reg); const TargetRegisterClass *RC = MRI->getRegClass(Reg);
if (SubIdx) { if (SubIdx) {
const TargetRegisterClass *SRC = RC->getSubRegisterRegClass(SubIdx); const TargetRegisterClass *SRC =
TRI->getSubClassWithSubReg(RC, SubIdx);
if (!SRC) { if (!SRC) {
report("Invalid subregister index for virtual register", MO, MONum); report("Invalid subregister index for virtual register", MO, MONum);
*OS << "Register class " << RC->getName() *OS << "Register class " << RC->getName()
<< " does not support subreg index " << SubIdx << "\n"; << " does not support subreg index " << SubIdx << "\n";
return; return;
} }
RC = SRC; if (RC != SRC) {
report("Invalid register class for subregister index", MO, MONum);
*OS << "Register class " << RC->getName()
<< " does not fully support subreg index " << SubIdx << "\n";
return;
}
} }
if (const TargetRegisterClass *DRC = TII->getRegClass(MCID,MONum,TRI)) { if (const TargetRegisterClass *DRC = TII->getRegClass(MCID,MONum,TRI)) {
if (SubIdx) {
const TargetRegisterClass *SuperRC =
TRI->getLargestLegalSuperClass(RC);
if (!SuperRC) {
report("No largest legal super class exists.", MO, MONum);
return;
}
DRC = TRI->getMatchingSuperRegClass(SuperRC, DRC, SubIdx);
if (!DRC) {
report("No matching super-reg register class.", MO, MONum);
return;
}
}
if (!RC->hasSuperClassEq(DRC)) { if (!RC->hasSuperClassEq(DRC)) {
report("Illegal virtual register for instruction", MO, MONum); report("Illegal virtual register for instruction", MO, MONum);
*OS << "Expected a " << DRC->getName() << " register, but got a " *OS << "Expected a " << DRC->getName() << " register, but got a "