diff --git a/src/llvm/lib/Target/W65816/W65816StackSlotMerge.cpp b/src/llvm/lib/Target/W65816/W65816StackSlotMerge.cpp index 908a52e..216404f 100644 --- a/src/llvm/lib/Target/W65816/W65816StackSlotMerge.cpp +++ b/src/llvm/lib/Target/W65816/W65816StackSlotMerge.cpp @@ -549,12 +549,16 @@ bool W65816StackSlotMerge::runOnMachineFunction(MachineFunction &MF) { // a DBG_VALUE that still points at slot-X reads stale data. // // For DBG_VALUEs whose DIExpression has a leading constant offset that - // matches a renamed slot, we mark them as undef. This loses debug - // info at the affected PC range but never reports a wrong variable - // value. A future enhancement could rewrite the offset to point at - // the merged slot Y (the merge proves they hold equivalent values - // function-wide), but that requires DIExpression rewriting and - // re-uniquing which is non-trivial in this position. + // matches a renamed slot X, relocate them to the merged slot Y by + // rewriting that leading offset (the merge proved X and Y hold + // equivalent values function-wide, so Y's memory is a correct location + // for the variable). The trailing ops are preserved verbatim and the + // offset is re-encoded with the canonical appendOffset form, which is + // exactly what extractLeadingOffset decodes -- so this is faithful. + // This keeps the variable's location live across the rename; previously + // we dropped it (setDebugValueUndef), losing debug info at those PCs. + // Falls back to undef only if re-encoding somehow fails. + LLVMContext &Ctx = MF.getFunction().getContext(); bool Changed = false; for (MachineBasicBlock &MBB : MF) { for (MachineInstr &MI : MBB) { @@ -565,14 +569,21 @@ bool W65816StackSlotMerge::runOnMachineFunction(MachineFunction &MF) { SmallVector Remaining; if (!Expr->extractLeadingOffset(LeadingOff, Remaining)) continue; - if (!Renames.count(LeadingOff)) continue; - // Match: this DBG_VALUE points at slot X (now renamed). Undef - // every register debug operand to drop the location at this PC. - for (MachineOperand &Op : MI.debug_operands()) { - if (Op.isReg()) { - Op.setReg(0); - Op.setSubReg(0); - } + auto RIt = Renames.find(LeadingOff); + if (RIt == Renames.end()) continue; + // Match: this DBG_VALUE points at slot X (now renamed to Y). + SmallVector NewOps; + DIExpression::appendOffset(NewOps, RIt->second); + NewOps.append(Remaining.begin(), Remaining.end()); + if (const DIExpression *NewExpr = DIExpression::get(Ctx, NewOps)) { + MI.getDebugExpressionOp().setMetadata(NewExpr); + } else { + // Should not happen; keep the old fail-safe behavior. + for (MachineOperand &Op : MI.debug_operands()) + if (Op.isReg()) { + Op.setReg(0); + Op.setSubReg(0); + } } Changed = true; }