summaryrefslogtreecommitdiffstats
path: root/llvm/test
diff options
context:
space:
mode:
authorNikola Prica <nikola.prica@rt-rk.com>2019-06-10 08:41:06 +0000
committerNikola Prica <nikola.prica@rt-rk.com>2019-06-10 08:41:06 +0000
commitabc1dff7e44a9eed6c2cc9a7d9ee366fbe4abcf7 (patch)
tree53da99a08fdde1c13ce220bc8ca0b9628a371507 /llvm/test
parent44d908d743d2e42206a8884ab2dea35cd29bb2da (diff)
downloadbcm5719-llvm-abc1dff7e44a9eed6c2cc9a7d9ee366fbe4abcf7.tar.gz
bcm5719-llvm-abc1dff7e44a9eed6c2cc9a7d9ee366fbe4abcf7.zip
[DebugInfo] More strict debug range for stack variables
Variable's stack location can stretch longer than it should. If a variable is placed at the stack in a some nested basic block its range can be calculated to be up to the next occurrence of the variable's DBG_VALUE, or up to the end of the function, thus covering a basic blocks that should not be included in the variable’s location range. This happens because the DbgEntityHistoryCalculator ends register locations at the end of a basic block only if the variable’s location register has been changed throughout the function, which is not the case for the register used to reference stack objects. This patch also tries to produce a single value location if the location list builder managed to merge all the locations into one. Reviewers: aprantl, dstenb, jmorse Reviewed By: aprantl, dstenb, jmorse Subscribers: djtodoro, ivanbaev, asowda Tags: #debug-info Differential Revision: https://reviews.llvm.org/D61600 llvm-svn: 362923
Diffstat (limited to 'llvm/test')
-rw-r--r--llvm/test/DebugInfo/MIR/X86/dbg-stack-value-range.mir184
-rw-r--r--llvm/test/DebugInfo/X86/fission-ranges.ll2
2 files changed, 185 insertions, 1 deletions
diff --git a/llvm/test/DebugInfo/MIR/X86/dbg-stack-value-range.mir b/llvm/test/DebugInfo/MIR/X86/dbg-stack-value-range.mir
new file mode 100644
index 00000000000..3863f43b374
--- /dev/null
+++ b/llvm/test/DebugInfo/MIR/X86/dbg-stack-value-range.mir
@@ -0,0 +1,184 @@
+# RUN: llc -start-before=livedebugvalues %s -filetype=asm -o -| FileCheck %s
+#
+# DbgEntityHistoryCalculator should close variable's range at the end of
+# the basic block when variable is referenced through non-changing frame
+# pointer register. Having BB1 that branches to BB2 and BB3, where
+# BB2 falls through to BB3, variable can have different locations at BB1 and BB2.
+# Since input locations at BB3 for same variable are different LiveDebugValues
+# wont generate DBG_VALUE for BB3. If last variable location at BB2 is
+# non-changing register, DbgEntityHistoryCalculator will extend range of
+# DBG_VALUE from BB2 to whole BB3 and thus produce incorrect range for
+# case when we took branch BB3 from BB1.
+#
+# Verifies that "local1" stack location is ended at the end of the block (.Ltmp6).
+#
+# CHECK: .Ltmp4:
+# CHECK-NEXT: #DEBUG_VALUE: foo:local1 <- [DW_OP_constu 4, DW_OP_minus, DW_OP_deref] $rbp
+# CHECK: jmp .LBB0_2
+# CHECK-NEXT: .Ltmp6:
+# CHECK: .Lfunc_end0:
+#
+# CHECK: .Linfo_string7:
+# CHECK-NEXT: .asciz "local1"
+#
+# CHECK: .Ldebug_loc2:
+# CHECK-NEXT: .quad .Ltmp1-.Lfunc_begin0
+# CHECK-NEXT: .quad .Ltmp4-.Lfunc_begin0
+# CHECK-NEXT: .short 1 # Loc expr size
+# CHECK-NEXT: .byte 94 # super-register DW_OP_reg14
+# CHECK-NEXT: .quad .Ltmp4-.Lfunc_begin0
+# CHECK-NEXT: .quad .Ltmp6-.Lfunc_begin0
+# CHECK-NEXT: .short 2 # Loc expr size
+# CHECK-NEXT: .byte 118 # DW_OP_breg6
+# CHECK-NEXT: .byte 124 # -4
+#
+# CHECK: .long .Ldebug_loc2 # DW_AT_location
+# CHECK-NEXT: .long .Linfo_string7 # DW_AT_name
+
+
+--- |
+ ; ModuleID = 'dbg-stack-value-range.ll'
+ source_filename = "dbg-stack-value-range.c"
+ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+ target triple = "x86_64-unknown-linux-gnu"
+
+ ; Function Attrs: nounwind uwtable
+ define dso_local i32 @foo(i32 %X) local_unnamed_addr #0 !dbg !7 {
+ entry:
+ %local1 = alloca i32, align 4
+ call void @llvm.dbg.value(metadata i32 %X, metadata !12, metadata !DIExpression()), !dbg !15
+ %0 = bitcast i32* %local1 to i8*, !dbg !15
+ call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %0), !dbg !15
+ call void @llvm.dbg.value(metadata i32 5, metadata !14, metadata !DIExpression()), !dbg !15
+ %call = tail call i32 (...) @check(), !dbg !15
+ %tobool = icmp eq i32 %call, 0, !dbg !15
+ br i1 %tobool, label %if.else, label %if.then, !dbg !15
+
+ if.then: ; preds = %entry
+ call void @llvm.dbg.value(metadata i32 4, metadata !13, metadata !DIExpression()), !dbg !15
+ store i32 4, i32* %local1, align 4, !dbg !15, !tbaa !16
+ call void @llvm.dbg.value(metadata i32* %local1, metadata !13, metadata !DIExpression(DW_OP_deref)), !dbg !15
+ %call1 = call i32 @init(i32* nonnull %local1), !dbg !15
+ call void @llvm.dbg.value(metadata i32 undef, metadata !14, metadata !DIExpression()), !dbg !15
+ br label %if.end, !dbg !15
+
+ if.else: ; preds = %entry
+ call void @llvm.dbg.value(metadata i32 5, metadata !13, metadata !DIExpression()), !dbg !15
+ store i32 5, i32* %local1, align 4, !dbg !15, !tbaa !16
+ br label %if.end
+
+ if.end: ; preds = %if.else, %if.then
+ %1 = bitcast i32* %local1 to i8*, !dbg !15
+ call void @llvm.dbg.value(metadata i32 undef, metadata !14, metadata !DIExpression()), !dbg !15
+ %call2 = call i32 (...) @init2(), !dbg !15
+ call void @llvm.dbg.value(metadata i32 undef, metadata !14, metadata !DIExpression()), !dbg !15
+ %2 = load i32, i32* %local1, align 4, !dbg !15, !tbaa !16
+ call void @llvm.dbg.value(metadata i32 %2, metadata !13, metadata !DIExpression()), !dbg !15
+ call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %1), !dbg !15
+ ret i32 %2, !dbg !15
+ }
+
+ ; Function Attrs: argmemonly nounwind
+ declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture)
+
+ declare dso_local i32 @check(...) local_unnamed_addr
+
+ declare dso_local i32 @init(i32*) local_unnamed_addr
+
+ declare dso_local i32 @init2(...) local_unnamed_addr
+
+ ; Function Attrs: argmemonly nounwind
+ declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture)
+
+ ; Function Attrs: nounwind readnone speculatable
+ declare void @llvm.dbg.value(metadata, metadata, metadata)
+
+ ; Function Attrs: nounwind
+ declare void @llvm.stackprotector(i8*, i8**)
+
+ attributes #0 = { nounwind uwtable "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf" }
+
+ !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 9.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
+ !1 = !DIFile(filename: "dbg-stack-value-range.c", directory: "/")
+ !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 9.0.0"}
+ !7 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 11, type: !8, scopeLine: 11, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
+ !8 = !DISubroutineType(types: !9)
+ !9 = !{!10, !10}
+ !10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+ !11 = !{!12, !13, !14}
+ !12 = !DILocalVariable(name: "X", arg: 1, scope: !7, file: !1, line: 11, type: !10)
+ !13 = !DILocalVariable(name: "local1", scope: !7, file: !1, line: 12, type: !10)
+ !14 = !DILocalVariable(name: "local2", scope: !7, file: !1, line: 12, type: !10)
+ !15 = !DILocation(line: 11, column: 13, scope: !7)
+ !16 = !{!17, !17, i64 0}
+ !17 = !{!"int", !18, i64 0}
+ !18 = !{!"omnipotent char", !19, i64 0}
+ !19 = !{!"Simple C/C++ TBAA"}
+
+...
+---
+name: foo
+alignment: 4
+frameInfo:
+ stackSize: 24
+ offsetAdjustment: -24
+ maxAlignment: 4
+ adjustsStack: true
+ hasCalls: true
+fixedStack:
+ - { id: 0, type: spill-slot, offset: -16, size: 8, alignment: 16, stack-id: 0,
+ callee-saved-register: '$r14d', callee-saved-restored: true, debug-info-variable: '',
+ debug-info-expression: '', debug-info-location: '' }
+stack:
+ - { id: 0, name: local1, type: default, offset: -20, size: 4, alignment: 4,
+ stack-id: 0, callee-saved-register: '', callee-saved-restored: true,
+ debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+body: |
+ bb.0.entry:
+ successors: %bb.3(0x30000000), %bb.1(0x50000000)
+
+ DBG_VALUE $edi, $noreg, !12, !DIExpression(), debug-location !15
+ frame-setup PUSH64r killed $rbp, implicit-def $rsp, implicit $rsp
+ CFI_INSTRUCTION def_cfa_offset 16
+ CFI_INSTRUCTION offset $rbp, -16
+ $rbp = frame-setup MOV64rr $rsp
+ CFI_INSTRUCTION def_cfa_register $rbp
+ $rsp = frame-setup SUB64ri8 $rsp, 16, implicit-def dead $eflags
+ DBG_VALUE 5, $noreg, !14, !DIExpression(), debug-location !15
+ $r14d = MOV32ri 4, implicit-def $r14
+ DBG_VALUE $r14d, $noreg, !13, !DIExpression(), debug-location !15
+ dead $eax = XOR32rr undef $eax, undef $eax, implicit-def dead $eflags, implicit-def $al, debug-location !15
+ CALL64pcrel32 @check, csr_64, implicit $rsp, implicit $ssp, implicit $al, implicit-def $rsp, implicit-def $ssp, implicit-def $eax, debug-location !15
+ TEST32rr killed renamable $eax, renamable $eax, implicit-def $eflags, debug-location !15
+ JCC_1 %bb.3, 4, implicit killed $eflags, debug-location !15
+
+ bb.1.if.then:
+ successors: %bb.3(0x80000000)
+
+ MOV32mr $rbp, 1, $noreg, -4, $noreg, $r14d, debug-location !15 :: (store 4 into %ir.local1, !tbaa !16)
+ DBG_VALUE $rbp, $noreg, !13, !DIExpression(DW_OP_constu, 4, DW_OP_minus, DW_OP_deref), debug-location !15
+ renamable $rdi = LEA64r $rbp, 1, $noreg, -4, $noreg
+ CALL64pcrel32 @init, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def dead $eax, debug-location !15
+ DBG_VALUE $noreg, $noreg, !14, !DIExpression(), debug-location !15
+ JMP_1 %bb.3
+
+ bb.3.if.end:
+ DBG_VALUE $noreg, $noreg, !14, !DIExpression(), debug-location !15
+ dead $eax = XOR32rr undef $eax, undef $eax, implicit-def dead $eflags, implicit-def $al, debug-location !15
+ CALL64pcrel32 @init2, csr_64, implicit $rsp, implicit $ssp, implicit $al, implicit-def $rsp, implicit-def $ssp, implicit-def dead $eax, debug-location !15
+ DBG_VALUE $noreg, $noreg, !14, !DIExpression(), debug-location !15
+ renamable $eax = MOV32rm $rbp, 1, $noreg, -4, $noreg, debug-location !15 :: (dereferenceable load 4 from %ir.local1, !tbaa !16)
+ $rsp = frame-destroy ADD64ri8 $rsp, 16, implicit-def dead $eflags, debug-location !15
+ $rbp = frame-destroy POP64r implicit-def $rsp, implicit $rsp, debug-location !15
+ CFI_INSTRUCTION def_cfa $rsp, 8, debug-location !15
+ RETQ $eax, debug-location !15
+
+...
diff --git a/llvm/test/DebugInfo/X86/fission-ranges.ll b/llvm/test/DebugInfo/X86/fission-ranges.ll
index e4347736195..fa911cd60f6 100644
--- a/llvm/test/DebugInfo/X86/fission-ranges.ll
+++ b/llvm/test/DebugInfo/X86/fission-ranges.ll
@@ -161,7 +161,7 @@ for.inc10: ; preds = %for.body9
for.inc13: ; preds = %for.inc10
%inc14 = add i32 %d.06, 1, !dbg !37
- tail call void @llvm.dbg.value(metadata i32 %inc14, metadata !16, metadata !DIExpression()), !dbg !37
+ tail call void @llvm.dbg.value(metadata i32 %inc14, metadata !16, metadata !DIExpression()), !dbg !42
%exitcond12 = icmp eq i32 %inc14, 30, !dbg !37
br i1 %exitcond12, label %for.inc16, label %for.cond4.preheader, !dbg !37
OpenPOWER on IntegriCloud