[llvm-bugs] [Bug 41992] New: [DebugInfo at O2] LiveDebugVariables can drop DBG_VALUEs through misinterpreting fragments
via llvm-bugs
llvm-bugs at lists.llvm.org
Thu May 23 03:55:53 PDT 2019
https://bugs.llvm.org/show_bug.cgi?id=41992
Bug ID: 41992
Summary: [DebugInfo at O2] LiveDebugVariables can drop DBG_VALUEs
through misinterpreting fragments
Product: libraries
Version: trunk
Hardware: PC
OS: Linux
Status: NEW
Keywords: wrong-debug
Severity: normal
Priority: P
Component: Common Code Generator Code
Assignee: unassignedbugs at nondot.org
Reporter: jeremy.morse.llvm at gmail.com
CC: aprantl at apple.com, chackz0x12 at gmail.com,
david.stenberg at ericsson.com, greg.bedwell at sony.com,
llvm-bugs at lists.llvm.org, orlando.hyams at sony.com,
paul.robinson at am.sony.com, stephen.tozer at sony.com
With LLVM/clang 361045, it seems LiveDebugVariables can drop DBG_VALUE
instructions in the presence of complex expressions, as demonstrated in the
code below, when fed into "llc -stop-after=virtregrewriter -o -". The code is
adapted from the dbg-addr-dse.ll test, and after virtregrewriter the third
DBG_VALUE instruction is not re-inserted, which makes an assignment disappear.
The cause seems to be this check [0] in LiveDebugVariables: it intends to
ensure that fragments are recorded as different "UserValue"s. However the fact
it's only comparing Expression pointers means that any complex expression at
all will be considered a different fragment of the variable. Thus the
DW_OP_deref's in the code below effectively make the dbg.value's refer to
different fragments, according to LiveDebugVariables.
In the example code, after calling collectDebugValues,
LiveDebugVariables::print represents the program state thus:
!"x,3" [32r;32d):0 [128r;128d):0 Loc0=%stack.0
!"x,3" [112r;112d):0 Loc0=1
Here the first and last DBG_VALUE insts are recorded in the first line as being
in location 0 (%stack.0) at slot indexes 32 and 128. The second line represents
the middle DBG_VALUE, as a different fragment, having location const-1 at slot
index 112. (The DIExpressions aren't printed).
After calling computeIntervals the LiveDebugVariables state becomes:
!"x,3" [48B;240B):0 Loc0=%stack.0
!"x,3" [112r;240B):0 Loc0=1
The first line coalesces its locations to the end of the block (240B) because
that "fragment" always appears to be in %stack.0. Then when virtregrewriter
re-inserts DBG_VALUEs, it doesn't see any reason to replace what was the third
DBG_VALUE in the original code: as far as it sees it, there are two different
fragments that get their locations defined once each, and that's it. Thus, the
third DBG_VALUE goes missing.
I anticipate LiveDebugVariables could be convinced to insert fresh DBG_VALUEs
where it shouldn't in a similar way. UserValue::extendDef can be convinced to
extend the lifetime of a fragment to a copy of a register location, if the
original register is killed. That would then lead to it inserting a fresh
DBG_VALUE, possibly terminating an earlier DBG_VALUE for the same (but
unrecognised) fragment.
(I was going to just submit a patch for this, but I think some non-trivial
datastructure changes are required, and it's not something I'm immediately
working on).
[0]
https://github.com/llvm/llvm-project/blob/e85bbf564de9adfe09d6b24b9861b28e2b78e9ad/llvm/lib/CodeGen/LiveDebugVariables.cpp#L207
--------8<--------
target triple = "x86_64-unknown-linux"
declare void @llvm.dbg.addr(metadata, metadata, metadata)
declare void @llvm.dbg.value(metadata, metadata, metadata)
declare void @escape(i32*)
@global = external global i32, align 4
define void @f(i32 %x) !dbg !8 {
entry:
%x.addr = alloca i32, align 4
store i32 %x, i32* %x.addr, align 4
call void @llvm.dbg.value(metadata i32* %x.addr, metadata !13, metadata
!DIExpression(DW_OP_deref)), !dbg !18
call void @escape(i32* %x.addr), !dbg !18
call void @llvm.dbg.value(metadata i32 1, metadata !13, metadata
!DIExpression()), !dbg !18
store i32 1, i32* @global, align 4, !dbg !18
call void @llvm.dbg.value(metadata i32* %x.addr, metadata !13, metadata
!DIExpression(DW_OP_deref)), !dbg !18
store i32 2, i32* %x.addr, align 4, !dbg !18
call void @escape(i32* %x.addr), !dbg !18
ret void, !dbg !18
}
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3, !4}
!llvm.ident = !{!7}
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang
version 6.0.0 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug,
enums: !2)
!1 = !DIFile(filename: "dse.c", directory: "C:\5Csrc\5Cllvm-project\5Cbuild")
!2 = !{}
!3 = !{i32 2, !"Dwarf Version", i32 4}
!4 = !{i32 2, !"Debug Info Version", i32 3}
!7 = !{!"clang version 6.0.0 "}
!8 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 3, type: !9,
isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped,
isOptimized: true, unit: !0, retainedNodes: !12)
!9 = !DISubroutineType(types: !10)
!10 = !{null, !11}
!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!12 = !{!13}
!13 = !DILocalVariable(name: "x", arg: 1, scope: !8, file: !1, line: 3, type:
!11)
!18 = !DILocation(line: 3, column: 12, scope: !8)
-------->8--------
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20190523/4c443cce/attachment.html>
More information about the llvm-bugs
mailing list