[llvm-commits] [llvm] r112825 - in /llvm/trunk: lib/Target/ARM/ARMExpandPseudoInsts.cpp lib/Target/ARM/ARMISelDAGToDAG.cpp lib/Target/ARM/ARMInstrNEON.td lib/Target/ARM/NEONPreAllocPass.cpp test/CodeGen/ARM/reg_sequence.ll
Jakob Stoklund Olesen
stoklund at 2pi.dk
Thu Sep 2 10:53:49 PDT 2010
Hi Bob,
On Sep 2, 2010, at 9:00 AM, Bob Wilson wrote:
> + MIB.addReg(D0).addReg(D1);
> + if (NumRegs > 2)
> + MIB.addReg(D2);
> + if (NumRegs > 3)
> + MIB.addReg(D3);
I think you need to add <dead> flags here.
[...]
> + // Add an implicit def for the super-reg.
> + MIB.addReg(DstReg, (getDefRegState(true) | getDeadRegState(DstIsDead) |
> + getImplRegState(true)));
Just like you did here. (Also note that getDefRegState(true) | getImplRegState(true) can be spelled as RegState::ImplicitDefine)
This part is tricky, but a sub-register <def> takes precedence over a super-register <def,dead>, so the sub-register is resurrected. See the bottom of RegScavenger::forward():
// Commit the changes.
setUnused(KillRegs);
setUnused(DeadRegs);
setUsed(DefRegs);
Same here:
void MachineVerifier::visitMachineInstrAfter(const MachineInstr *MI) {
BBInfo &MInfo = MBBInfoMap[MI->getParent()];
set_union(MInfo.regsKilled, regsKilled);
set_subtract(regsLive, regsKilled); regsKilled.clear();
set_subtract(regsLive, regsDead); regsDead.clear();
set_union(regsLive, regsDefined); regsDefined.clear();
}
In other words, <def> overrides <def,dead> and <kill>
This instruction:
%D0<def>, %D1<def> = VLD ..., %Q0<def,dead>
Leaves %Q0 dead while subregs %D0 and D1 are live. You want:
%D0<def,dead>, %D1<def,dead> = VLD ..., %Q0<def,dead>
To avoid any zombies.
Alternatively, you can use MachineInstr::addRegister{Defined,Dead}(%Q0, TRI, true) which should take care of this, including adding dead flags to the subreg operands.
/jakob
More information about the llvm-commits
mailing list