[llvm] [CodeGen] Transfer implicit-defs to first instruction when lowering multi-instruction COPY (PR #194892)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 16 00:57:27 PDT 2026
================
@@ -870,20 +870,44 @@ TargetInstrInfo::foldMemoryOperand(MachineInstr &MI, ArrayRef<unsigned> Ops,
/// replacement instructions immediately precede it. Copy any implicit
/// operands from MI to the replacement instruction.
static void transferImplicitOperands(MachineInstr *MI,
+ MachineBasicBlock::instr_iterator FirstMI,
const TargetRegisterInfo *TRI) {
- MachineBasicBlock::iterator CopyMI = MI;
- --CopyMI;
+ MachineBasicBlock::instr_iterator LastMI = MI->getIterator();
+ --LastMI;
Register DstReg = MI->getOperand(0).getReg();
for (const MachineOperand &MO : MI->implicit_operands()) {
- CopyMI->addOperand(MO);
+ // If an implicit-def of a super-register left on the last
+ // instruction fully covers a subreg def and no later instruction reads
+ // it to keep it live, it would make that def look dead. So we transfert the
+ // implicit def to the first instruction to keep it alive.
+ if (MO.isDef() && TRI->regsOverlap(DstReg, MO.getReg())) {
+ bool WouldKillEarlierDef =
+ any_of(make_range(FirstMI, LastMI), [&](MachineInstr &Repl) {
+ const MachineOperand &Def = Repl.getOperand(0);
+ if (!Def.isReg() || !Def.getReg() ||
+ !TRI->isSubRegisterEq(MO.getReg(), Def.getReg()))
+ return false;
+ return none_of(
+ make_range(std::next(Repl.getIterator()), MI->getIterator()),
+ [&](const MachineInstr &Later) {
+ return Later.readsRegister(Def.getReg(), TRI);
+ });
----------------
arsenm wrote:
I think this logic needs to be applied when performing the expansion. This is scanning through the instruction sequence to reverse engineer intent after the fact
https://github.com/llvm/llvm-project/pull/194892
More information about the llvm-commits
mailing list