Index: llvm/trunk/lib/CodeGen/LiveDebugVariables.cpp =================================================================== --- llvm/trunk/lib/CodeGen/LiveDebugVariables.cpp +++ llvm/trunk/lib/CodeGen/LiveDebugVariables.cpp @@ -224,7 +224,12 @@ return L1; } - /// getLocationNo - Return the location number that matches Loc. + /// Return the location number that matches Loc. + /// + /// For undef values we always return location number UndefLocNo without + /// inserting anything in locations. Since locations is a vector and the + /// location number is the position in the vector and UndefLocNo is ~0, + /// we would need a very big vector to put the value at the right position. unsigned getLocationNo(const MachineOperand &LocMO) { if (LocMO.isReg()) { if (LocMO.getReg() == 0) @@ -761,13 +766,6 @@ // function). } - // Erase all the undefs. - for (LocMap::iterator I = locInts.begin(); I.valid();) - if (I.value().isUndef()) - I.erase(); - else - ++I; - // The computed intervals may extend beyond the range of the debug // location's lexical scope. In this case, splitting of an interval // can result in an interval outside of the scope being created, @@ -990,7 +988,9 @@ << LocMapI.stop() << ")\n"); LocMapI.erase(); } else { - if (v.locNo() > OldLocNo) + // Undef values always have location number UndefLocNo, so don't change + // locNo in that case. See getLocationNo(). + if (!v.isUndef() && v.locNo() > OldLocNo) LocMapI.setValueUnchecked(v.changeLocNo(v.locNo() - 1)); ++LocMapI; } @@ -1099,6 +1099,10 @@ // physical register. for (LocMap::iterator I = locInts.begin(); I.valid(); ++I) { DbgValueLocation Loc = I.value(); + // Undef values don't exist in locations (and thus not in LocNoMap either) + // so skip over them. See getLocationNo(). + if (Loc.isUndef()) + continue; unsigned NewLocNo = LocNoMap[Loc.locNo()]; I.setValueUnchecked(Loc.changeLocNo(NewLocNo)); I.setStart(I.start()); @@ -1163,7 +1167,15 @@ // Only search within the current MBB. StopIdx = (MBBEndIdx < StopIdx) ? MBBEndIdx : StopIdx; MachineBasicBlock::iterator I = findInsertLocation(MBB, StartIdx, LIS); - MachineOperand &MO = locations[Loc.locNo()]; + // Undef values don't exist in locations so create new "noreg" register MOs + // for them. See getLocationNo(). + MachineOperand MO = !Loc.isUndef() ? + locations[Loc.locNo()] : + MachineOperand::CreateReg(/* Reg */ 0, /* isDef */ false, /* isImp */ false, + /* isKill */ false, /* isDead */ false, + /* isUndef */ false, /* isEarlyClobber */ false, + /* SubReg */ 0, /* isDebug */ true); + ++NumInsertedDebugValues; assert(cast(Variable) Index: llvm/trunk/test/DebugInfo/X86/live-debug-vars-discard-invalid.mir =================================================================== --- llvm/trunk/test/DebugInfo/X86/live-debug-vars-discard-invalid.mir +++ llvm/trunk/test/DebugInfo/X86/live-debug-vars-discard-invalid.mir @@ -106,17 +106,11 @@ # CHECK-LABEL: name: foobar # CHECK-LABEL: bb.1: -## After solving https://bugs.llvm.org/show_bug.cgi?id=36579 we expect to get a -## DBG_VALUE debug-use $noreg -## here. -# CHECK-NOT: DBG_VALUE +# CHECK: DBG_VALUE debug-use $noreg # CHECK-LABEL: bb.2: -## After solving https://bugs.llvm.org/show_bug.cgi?id=36579 we expect to get a -## DBG_VALUE debug-use $noreg -## here. -# CHECK-NOT: DBG_VALUE -# CHECK: dead renamable $rcx = IMPLICIT_DEF +# CHECK: DBG_VALUE debug-use $noreg +# CHECK-NEXT: dead renamable $rcx = IMPLICIT_DEF # CHECK-NEXT: dead renamable $rcx = IMPLICIT_DEF # CHECK-NEXT: dead renamable $rcx = IMPLICIT_DEF # CHECK-NEXT: dead renamable $rcx = IMPLICIT_DEF Index: llvm/trunk/test/DebugInfo/X86/live-debug-vars-keep-undef.ll =================================================================== --- llvm/trunk/test/DebugInfo/X86/live-debug-vars-keep-undef.ll +++ llvm/trunk/test/DebugInfo/X86/live-debug-vars-keep-undef.ll @@ -0,0 +1,65 @@ +; RUN: llc -O1 -o - %s | FileCheck %s + +; Check that dbg.value(undef) calls are not simply discarded. + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @foo() !dbg !7 { +entry: + call void @llvm.dbg.value(metadata i32 42, metadata !11, metadata !DIExpression()), !dbg !13 + call void (...) @bar(), !dbg !14 + call void @llvm.dbg.value(metadata i32 undef, metadata !11, metadata !DIExpression()), !dbg !13 + call void (...) @bar(), !dbg !15 + ret void, !dbg !16 +} + +declare void @bar(...) + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #0 + +attributes #0 = { nounwind readnone speculatable } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 7.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) +!1 = !DIFile(filename: "test.c", directory: "/tmp") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 7.0.0"} +!7 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 3, type: !8, isLocal: false, isDefinition: true, scopeLine: 3, isOptimized: true, unit: !0, retainedNodes: !10) +!8 = !DISubroutineType(types: !9) +!9 = !{null} +!10 = !{!11} +!11 = !DILocalVariable(name: "x", scope: !7, file: !1, line: 4, type: !12) +!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!13 = !DILocation(line: 4, column: 7, scope: !7) +!14 = !DILocation(line: 5, column: 3, scope: !7) +!15 = !DILocation(line: 7, column: 3, scope: !7) +!16 = !DILocation(line: 8, column: 1, scope: !7) + +; Original C program: +; void bar(); +; +; void foo() { +; int x = 42; +; bar(); +; x = 23; +; bar(); +; } +; +; Then the dbg.value for the x = 23 setting has been replaced with dbg.value(undef) +; in this ll file to provoke the wanted behavior in LiveDebugVariables. + +; Variable 'x' should thus be updated two times, first to 42 and then to undef. + +; CHECK-LABEL: foo: +; CHECK: #DEBUG_VALUE: foo:x <- 42 +; CHECK: callq bar +; CHECK: #DEBUG_VALUE: foo:x <- undef +; CHECK: callq bar