summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Morse <jeremy.morse@sony.com>2021-10-18 11:37:51 +0100
committerJeremy Morse <jeremy.morse@sony.com>2021-10-18 11:52:45 +0100
commitc4ede6d60892a5101d159b4876ad76fc8eefc837 (patch)
tree60f282b78328d09cbd6a889eecedcb773319bab1
parentd8bc7e40ce1cdd8c1a3fac7937ce1ea85c262728 (diff)
downloadllvm-c4ede6d60892a5101d159b4876ad76fc8eefc837.tar.gz
[DebugInfo][InstrRef] Avoid a crash during DBG_PHI maintenence
With D110105, the isDebug flag for register uses is now a proxy for whether the instruction is a debug instruction; that causes DBG_PHIs to have their operands updated by calls to updateDbgUsersToReg, which is the correct behaviour. However: that function only expects to receive DBG_VALUE instructions and asserts such. This patch splits the updating-action into a lambda, and applies it to the appropriate operands for each kind of debug instruction. Tested with an ARM test that stimulates this function: I've added some DBG_PHI instructions that should be updated in the same way as DBG_VALUEs. Differential Revision: https://reviews.llvm.org/D108641
-rw-r--r--llvm/include/llvm/CodeGen/MachineRegisterInfo.h39
-rw-r--r--llvm/test/DebugInfo/ARM/machine-cp-updates-dbg-reg.mir4
2 files changed, 30 insertions, 13 deletions
diff --git a/llvm/include/llvm/CodeGen/MachineRegisterInfo.h b/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
index 3756dc1b4588..dbabfe5f0f32 100644
--- a/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
+++ b/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -821,7 +821,7 @@ public:
/// deleted during LiveDebugVariables analysis.
void markUsesInDebugValueAsUndef(Register Reg) const;
- /// updateDbgUsersToReg - Update a collection of DBG_VALUE instructions
+ /// updateDbgUsersToReg - Update a collection of debug instructions
/// to refer to the designated register.
void updateDbgUsersToReg(MCRegister OldReg, MCRegister NewReg,
ArrayRef<MachineInstr *> Users) const {
@@ -829,21 +829,34 @@ public:
for (MCRegUnitIterator RUI(OldReg, getTargetRegisterInfo()); RUI.isValid();
++RUI)
OldRegUnits.insert(*RUI);
- for (MachineInstr *MI : Users) {
- assert(MI->isDebugValue());
- for (auto &Op : MI->debug_operands()) {
- if (Op.isReg()) {
- for (MCRegUnitIterator RUI(OldReg, getTargetRegisterInfo());
- RUI.isValid(); ++RUI) {
- if (OldRegUnits.contains(*RUI)) {
- Op.setReg(NewReg);
- break;
- }
+
+ // If this operand is a register, check whether it overlaps with OldReg.
+ // If it does, replace with NewReg.
+ auto UpdateOp = [this, &NewReg, &OldReg, &OldRegUnits](MachineOperand &Op) {
+ if (Op.isReg()) {
+ for (MCRegUnitIterator RUI(OldReg, getTargetRegisterInfo());
+ RUI.isValid(); ++RUI) {
+ if (OldRegUnits.contains(*RUI)) {
+ Op.setReg(NewReg);
+ break;
}
}
}
- assert(MI->hasDebugOperandForReg(NewReg) &&
- "Expected debug value to have some overlap with OldReg");
+ };
+
+ // Iterate through (possibly several) operands to DBG_VALUEs and update
+ // each. For DBG_PHIs, only one operand will be present.
+ for (MachineInstr *MI : Users) {
+ if (MI->isDebugValue()) {
+ for (auto &Op : MI->debug_operands())
+ UpdateOp(Op);
+ assert(MI->hasDebugOperandForReg(NewReg) &&
+ "Expected debug value to have some overlap with OldReg");
+ } else if (MI->isDebugPHI()) {
+ UpdateOp(MI->getOperand(0));
+ } else {
+ llvm_unreachable("Non-DBG_VALUE, Non-DBG_PHI debug instr updated");
+ }
}
}
diff --git a/llvm/test/DebugInfo/ARM/machine-cp-updates-dbg-reg.mir b/llvm/test/DebugInfo/ARM/machine-cp-updates-dbg-reg.mir
index 3e7003d878f3..8e25f8b92d3e 100644
--- a/llvm/test/DebugInfo/ARM/machine-cp-updates-dbg-reg.mir
+++ b/llvm/test/DebugInfo/ARM/machine-cp-updates-dbg-reg.mir
@@ -3,10 +3,13 @@
## Ensure that when the destination register of a copy instruction is used by a
## DBG_VALUE/DBG_VALUE_LIST, and then that instruction is deleted during copy
## propagation, the debug use is updated to the source register.
+##
+## Do the same for DBG_PHI instructions.
# CHECK: ![[VAR_V:[0-9]+]] = !DILocalVariable(name: "v"
# CHECK-LABEL: body:
+# CHECK: DBG_PHI $r0, 1
# CHECK: DBG_VALUE $r0, $noreg, ![[VAR_V]], !DIExpression()
# CHECK: DBG_VALUE_LIST ![[VAR_V]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_constu, 4, DW_OP_mul, DW_OP_plus, DW_OP_stack_value), $r0, 0
@@ -179,6 +182,7 @@ body: |
dead renamable $r1 = LDRi12 undef renamable $r0, 0, 14 /* CC::al */, $noreg :: (volatile load (s32) from `i32* undef`)
renamable $r4 = COPY killed renamable $r0
+ DBG_PHI $r4, 1
DBG_VALUE $r4, $noreg, !30, !DIExpression(), debug-location !40
DBG_VALUE_LIST !30, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_constu, 4, DW_OP_mul, DW_OP_plus, DW_OP_stack_value), $r4, 0, debug-location !40
$r0 = COPY killed renamable $r4