diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -1993,6 +1993,17 @@ MIRBuilder.buildIndirectDbgValue(0, DI.getVariable(), DI.getExpression()); } else if (const auto *CI = dyn_cast(V)) { MIRBuilder.buildConstDbgValue(*CI, DI.getVariable(), DI.getExpression()); + } else if (auto *AI = dyn_cast(V); + AI && AI->isStaticAlloca() && + DI.getExpression()->startsWithDeref()) { + // If the value is an alloca and the expression starts with a + // dereference, track a stack slot instead of a register, as registers + // may be clobbered. + auto ExprOperands = DI.getExpression()->getElements(); + auto *ExprDerefRemoved = + DIExpression::get(AI->getContext(), ExprOperands.drop_front()); + MIRBuilder.buildFIDbgValue(getOrCreateFrameIndex(*AI), DI.getVariable(), + ExprDerefRemoved); } else { for (Register Reg : getOrCreateVRegs(*V)) { // FIXME: This does not handle register-indirect values at offset 0. The diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp --- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp +++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp @@ -80,11 +80,11 @@ assert( cast(Variable)->isValidLocationForIntrinsic(getDL()) && "Expected inlined-at fields to agree"); - return buildInstr(TargetOpcode::DBG_VALUE) - .addFrameIndex(FI) - .addImm(0) - .addMetadata(Variable) - .addMetadata(Expr); + return insertInstr(buildInstrNoInsert(TargetOpcode::DBG_VALUE) + .addFrameIndex(FI) + .addImm(0) + .addMetadata(Variable) + .addMetadata(Expr)); } MachineInstrBuilder MachineIRBuilder::buildConstDbgValue(const Constant &C, diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/debug-insts.ll b/llvm/test/CodeGen/AArch64/GlobalISel/debug-insts.ll --- a/llvm/test/CodeGen/AArch64/GlobalISel/debug-insts.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/debug-insts.ll @@ -28,13 +28,16 @@ @gv = global i32 zeroinitializer ; CHECK-LABEL: name: debug_value +; CHECK: stack: +; CHECK: - { id: {{.*}}, name: addr ; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $w0 define void @debug_value(i32 %in) #0 !dbg !16 { +; CHECK: G_FRAME_INDEX %[[stack_slot:.*]] %addr = alloca i32 ; CHECK: DBG_VALUE [[IN]](s32), $noreg, !17, !DIExpression(), debug-location !18 call void @llvm.dbg.value(metadata i32 %in, i64 0, metadata !17, metadata !DIExpression()), !dbg !18 store i32 %in, ptr %addr -; CHECK: DBG_VALUE %1(p0), $noreg, !17, !DIExpression(DW_OP_deref), debug-location !18 +; CHECK: DBG_VALUE %[[stack_slot]], 0, !17, !DIExpression(), debug-location !18 call void @llvm.dbg.value(metadata ptr %addr, i64 0, metadata !17, metadata !DIExpression(DW_OP_deref)), !dbg !18 ; CHECK: DBG_VALUE 123, 0, !17, !DIExpression(), debug-location !18 call void @llvm.dbg.value(metadata i32 123, i64 0, metadata !17, metadata !DIExpression()), !dbg !18