This repository has been archived by the owner on Apr 23, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[DebugInfo] Discard invalid DBG_VALUE instructions in LiveDebugVariables
Summary: This is a workaround for pr36417 https://bugs.llvm.org/show_bug.cgi?id=36417 LiveDebugVariables will now verify that the DBG_VALUE instructions are sane (prior to register allocation) by asking LIS if a virtual register used in the DBG_VALUE is live (or dead def) in the slot index before the DBG_VALUE. If it isn't sane the DBG_VALUE is discarded. One pass that was identified as introducing non-sane DBG_VALUE instructtons, when analysing pr36417, was the DAG->DAG Instruction Selection. It sometimes inserts DBG_VALUE instructions referring to a virtual register that is defined later in the same basic block. So it is a use before def kind of problem. The DBG_VALUE is typically inserted in the beginning of a basic block when this happens. The problem can be seen in the test case test/DebugInfo/X86/dbg-value-inlined-parameter.ll Reviewers: aprantl, rnk, probinson Reviewed By: aprantl Subscribers: vsk, davide, alexcrichton, Ka-Ka, eraman, llvm-commits, JDevlieghere Differential Revision: https://reviews.llvm.org/D43956 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@326769 91177308-0d34-0410-b5e6-96231b3b80d8
- Loading branch information
Showing
3 changed files
with
181 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
# RUN: llc -mtriple=x86_64-linux-gnu -start-before greedy -stop-after virtregrewriter -o - %s | FileCheck %s | ||
|
||
--- | | ||
; ModuleID = '<stdin>' | ||
source_filename = "test/DebugInfo/X86/dbg-value-inlined-parameter.ll" | ||
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" | ||
target triple = "x86_64-apple-darwin" | ||
|
||
%struct.S1 = type { float*, i32 } | ||
|
||
@p = common global %struct.S1 zeroinitializer, align 8, !dbg !0 | ||
|
||
; Function Attrs: nounwind optsize ssp | ||
define void @foobar() !dbg !15 { | ||
entry: | ||
tail call void @llvm.dbg.value(metadata %struct.S1* @p, metadata !18, metadata !DIExpression()) , !dbg !25 | ||
ret void, !dbg !32 | ||
} | ||
|
||
; Function Attrs: nounwind readnone speculatable | ||
declare void @llvm.dbg.value(metadata, metadata, metadata) #2 | ||
|
||
!llvm.dbg.cu = !{!2} | ||
!llvm.module.flags = !{!14} | ||
|
||
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) | ||
!1 = !DIGlobalVariable(name: "p", scope: !2, file: !3, line: 14, type: !6, isLocal: false, isDefinition: true) | ||
!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 2.9 (trunk 125693)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !4, globals: !5, imports: !4) | ||
!3 = !DIFile(filename: "nm2.c", directory: "/private/tmp") | ||
!4 = !{} | ||
!5 = !{!0} | ||
!6 = !DIDerivedType(tag: DW_TAG_typedef, name: "S1", scope: !2, file: !3, line: 4, baseType: !7) | ||
!7 = !DICompositeType(tag: DW_TAG_structure_type, name: "S1", scope: !2, file: !3, line: 1, size: 128, align: 64, elements: !8) | ||
!8 = !{!9, !12} | ||
!9 = !DIDerivedType(tag: DW_TAG_member, name: "m", scope: !3, file: !3, line: 2, baseType: !10, size: 64, align: 64) | ||
!10 = !DIDerivedType(tag: DW_TAG_pointer_type, scope: !2, baseType: !11, size: 64, align: 64) | ||
!11 = !DIBasicType(name: "float", size: 32, align: 32, encoding: DW_ATE_float) | ||
!12 = !DIDerivedType(tag: DW_TAG_member, name: "nums", scope: !3, file: !3, line: 3, baseType: !13, size: 32, align: 32, offset: 64) | ||
!13 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed) | ||
!14 = !{i32 1, !"Debug Info Version", i32 3} | ||
!15 = distinct !DISubprogram(name: "foobar", scope: !3, file: !3, line: 15, type: !16, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: true, unit: !2) | ||
!16 = !DISubroutineType(types: !17) | ||
!17 = !{null} | ||
!18 = !DILocalVariable(name: "sp", arg: 1, scope: !19, file: !3, line: 7, type: !24) | ||
!19 = distinct !DISubprogram(name: "foo", scope: !3, file: !3, line: 8, type: !20, isLocal: false, isDefinition: true, scopeLine: 8, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !2, variables: !22) | ||
!20 = !DISubroutineType(types: !21) | ||
!21 = !{!13} | ||
!22 = !{!18, !23} | ||
!23 = !DILocalVariable(name: "nums", arg: 2, scope: !19, file: !3, line: 7, type: !13) | ||
!24 = !DIDerivedType(tag: DW_TAG_pointer_type, scope: !2, baseType: !6, size: 64, align: 64) | ||
!25 = !DILocation(line: 7, column: 13, scope: !19, inlinedAt: !26) | ||
!26 = !DILocation(line: 16, column: 3, scope: !27) | ||
!27 = distinct !DILexicalBlock(scope: !15, file: !3, line: 15, column: 15) | ||
!32 = !DILocation(line: 17, column: 1, scope: !27) | ||
|
||
... | ||
--- | ||
name: foobar | ||
tracksRegLiveness: true | ||
body: | | ||
bb.0: | ||
%1:gr64 = IMPLICIT_DEF | ||
%2:gr64 = IMPLICIT_DEF | ||
bb.1: | ||
; This DBG_VALUE will be discarded (use before def of %0). | ||
DBG_VALUE debug-use %0, debug-use $noreg, !18, !DIExpression(), debug-location !25 | ||
%0:gr64 = IMPLICIT_DEF | ||
%0:gr64 = IMPLICIT_DEF | ||
%0:gr64 = IMPLICIT_DEF | ||
%0:gr64 = IMPLICIT_DEF | ||
bb.2: | ||
; This DBG_VALUE will be discarded (%1 is defined earlier, but it is not live in, so we do not know where %1 is stored). | ||
DBG_VALUE debug-use %1, debug-use $noreg, !18, !DIExpression(), debug-location !25 | ||
%1:gr64 = IMPLICIT_DEF | ||
%1:gr64 = IMPLICIT_DEF | ||
%1:gr64 = IMPLICIT_DEF | ||
%1:gr64 = IMPLICIT_DEF | ||
; This DBG_VALUE is kept, even if %1 is dead, it was defined in the prev instruction, | ||
; so the value should be available for as long as the register allocated to %1 is live. | ||
DBG_VALUE debug-use %1, debug-use $noreg, !18, !DIExpression(), debug-location !25 | ||
bb.3: | ||
%1:gr64 = IMPLICIT_DEF | ||
DBG_VALUE 0, debug-use $noreg, !23, !DIExpression(), debug-location !25 | ||
; This DBG_VALUE is kept, even if %1 is dead, it was defined in the prev non-dbg instruction, | ||
; so the value should be available for as long as the register allocated to %1 is live. | ||
DBG_VALUE debug-use %1, debug-use $noreg, !18, !DIExpression(), debug-location !25 | ||
bb.4: | ||
; All DBG_VALUEs here should survive. %2 is livein as it was defined in bb.0, and it has use/def in the BTS64rr instruction. | ||
DBG_VALUE debug-use %2, debug-use $noreg, !18, !DIExpression(), debug-location !25 | ||
%2:gr64 = BTS64rr %2, 0, implicit-def $eflags | ||
DBG_VALUE 0, debug-use $noreg, !23, !DIExpression(), debug-location !25 | ||
DBG_VALUE debug-use %2, debug-use $noreg, !18, !DIExpression(), debug-location !25 | ||
%2:gr64 = BTS64rr %2, 0, implicit-def $eflags | ||
DBG_VALUE debug-use %2, debug-use $noreg, !18, !DIExpression(), debug-location !25 | ||
%2:gr64 = BTS64rr %2, 0, implicit-def $eflags | ||
DBG_VALUE debug-use %2, debug-use $noreg, !18, !DIExpression(), debug-location !25 | ||
bb.5: | ||
RET 0, debug-location !32 | ||
... | ||
|
||
# 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-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-NEXT: dead renamable $rcx = IMPLICIT_DEF | ||
# CHECK-NEXT: dead renamable $rcx = IMPLICIT_DEF | ||
# CHECK-NEXT: dead renamable $rcx = IMPLICIT_DEF | ||
# CHECK-NEXT: DBG_VALUE debug-use $rcx, debug-use $noreg, !18, !DIExpression() | ||
|
||
# CHECK-LABEL: bb.3: | ||
# CHECK: dead renamable $rcx = IMPLICIT_DEF | ||
# CHECK-NEXT: DBG_VALUE 0, debug-use $noreg, !23, !DIExpression() | ||
# CHECK-NEXT: DBG_VALUE debug-use $rcx, debug-use $noreg, !18, !DIExpression() | ||
|
||
# CHECK-LABEL: bb.4: | ||
# CHECK: liveins: $rax | ||
# CHECK: DBG_VALUE debug-use $rax, debug-use $noreg, !18, !DIExpression() | ||
# CHECK-NEXT: renamable $rax = BTS64rr killed renamable $rax, 0, implicit-def $eflags | ||
# CHECK-NEXT: DBG_VALUE 0, debug-use $noreg, !23, !DIExpression() | ||
# CHECK-NEXT: DBG_VALUE debug-use $rax, debug-use $noreg, !18, !DIExpression() | ||
# CHECK-NEXT: renamable $rax = BTS64rr killed renamable $rax, 0, implicit-def $eflags | ||
# CHECK-NEXT: DBG_VALUE debug-use $rax, debug-use $noreg, !18, !DIExpression() | ||
# CHECK-NEXT: dead renamable $rax = BTS64rr killed renamable $rax, 0, implicit-def $eflags | ||
|
||
# CHECK-LABEL: bb.5: | ||
# CHECK-NEXT: RET 0 |