Index: lib/CodeGen/LiveDebugValues.cpp =================================================================== --- lib/CodeGen/LiveDebugValues.cpp +++ lib/CodeGen/LiveDebugValues.cpp @@ -77,6 +77,7 @@ #define DEBUG_TYPE "livedebugvalues" STATISTIC(NumInserted, "Number of DBG_VALUE instructions inserted"); +STATISTIC(NumRemoved, "Number of DBG_VALUE instructions removed"); // If @MI is a DBG_VALUE with debug value described by a defined // register, returns the number of this register. In the other case, returns 0. @@ -942,7 +943,7 @@ VarLocIDs[ID].dump(); }); VarLocSet &VLS = OutLocs[CurMBB]; - Changed = VLS |= OpenRanges.getVarLocs(); + Changed = VLS != OpenRanges.getVarLocs(); // New OutLocs set may be different due to spill, restore or register // copy instruction processing. if (Changed) @@ -1101,8 +1102,6 @@ // is the entry block which has no predecessor. assert((NumVisited || MBB.pred_empty()) && "Should have processed at least one predecessor"); - if (InLocsT.empty()) - return false; VarLocSet &ILS = InLocs[&MBB]; VarLocSet &Pending = PendingInLocs[&MBB]; @@ -1118,6 +1117,19 @@ ++NumInserted; Changed = true; } + + // We may have lost locations by learning about a predecessor that either + // loses or moves a variable. Find any locations in ILS that are not in the + // new in-locations, and delete those. + VarLocSet Removed = ILS; + Removed.intersectWithComplement(InLocsT); + for (auto ID : Removed) { + Pending.reset(ID); + ILS.reset(ID); + ++NumRemoved; + Changed = true; + } + return Changed; } Index: test/DebugInfo/COFF/pieces.ll =================================================================== --- test/DebugInfo/COFF/pieces.ll +++ test/DebugInfo/COFF/pieces.ll @@ -43,7 +43,6 @@ ; ASM: [[oy_ox_start:\.Ltmp[0-9]+]]: ; ASM: .p2align 4, 0x90 ; ASM: .LBB0_3: # %for.body -; ASM: #DEBUG_VALUE: loop_csr:o <- [DW_OP_LLVM_fragment 0 32] 0 ; ASM: #DEBUG_VALUE: loop_csr:o <- [DW_OP_LLVM_fragment 0 32] $edi ; ASM: #DEBUG_VALUE: loop_csr:o <- [DW_OP_LLVM_fragment 32 32] $esi ; ASM: .cv_loc 0 1 13 11 # t.c:13:11 Index: test/DebugInfo/X86/fission-ranges.ll =================================================================== --- test/DebugInfo/X86/fission-ranges.ll +++ test/DebugInfo/X86/fission-ranges.ll @@ -45,7 +45,7 @@ ; if they've changed due to a bugfix, change in register allocation, etc. ; CHECK: [[A]]: -; CHECK-NEXT: Addr idx 2 (w/ length 169): DW_OP_consts +0, DW_OP_stack_value +; CHECK-NEXT: Addr idx 2 (w/ length 15): DW_OP_consts +0, DW_OP_stack_value ; CHECK-NEXT: Addr idx 3 (w/ length 15): DW_OP_reg0 RAX ; CHECK-NEXT: Addr idx 4 (w/ length 18): DW_OP_breg7 RSP-8 ; CHECK: [[E]]: Index: test/DebugInfo/X86/live-debug-values-remove-range.ll =================================================================== --- /dev/null +++ test/DebugInfo/X86/live-debug-values-remove-range.ll @@ -0,0 +1,49 @@ +; RUN: llc -mtriple=x86_64-unknown-unknown %s -o - -stop-after=livedebugvalues | FileCheck %s +; +; In the simple loop below, the location of the variable "toast" is %bar in +; the entry block, then set to constant zero at the end of the loop. We cannot +; know the location of "toast" at the start of the %loop block. Test that no +; location is given until after the call to @booler. +; +; CHECK: ![[VARNUM:[0-9]+]] = !DILocalVariable(name: "toast" +; +; CHECK-LABEL: bb.1.loop +; CHECK-NOT: DBG_VALUE +; CHECK-LABEL: CALL64pcrel32 @booler +; CHECK: DBG_VALUE 0, $noreg, ![[VARNUM]] + +declare i1 @booler() +declare void @escape(i32) +declare void @llvm.dbg.value(metadata, metadata, metadata) +@glob = global i32 0 + +define i32 @foo(i32 %bar) !dbg !4 { +entry: + call void @llvm.dbg.value(metadata i32 %bar, metadata !3, metadata !DIExpression()), !dbg !6 + br label %loop +loop: + call void @escape(i32 %bar) + %retval = call i1 @booler(), !dbg !6 + call void @llvm.dbg.value(metadata i32 0, metadata !3, metadata !DIExpression()), !dbg !6 + br i1 %retval, label %loop2, label %exit +loop2: + store i32 %bar, i32 *@glob + br label %loop +exit: + ret i32 %bar +} + +!llvm.module.flags = !{!0, !100} +!llvm.dbg.cu = !{!1} + +!100 = !{i32 2, !"Dwarf Version", i32 4} +!0 = !{i32 2, !"Debug Info Version", i32 3} +!1 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !2, producer: "beards", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug) +!2 = !DIFile(filename: "bees.cpp", directory: ".") +!3 = !DILocalVariable(name: "toast", scope: !4, file: !2, line: 1, type: !16) +!4 = distinct !DISubprogram(name: "nope", scope: !2, file: !2, line: 1, spFlags: DISPFlagDefinition, unit: !1, retainedNodes: !13, type: !14, isDefinition: true) +!6 = !DILocation(line: 1, scope: !4) +!13 = !{!3} +!14 = !DISubroutineType(types: !15) +!15 = !{!16} +!16 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)