240 lines · plain
1# RUN: llc -O1 -start-after=livedebugvalues -o - %s | FileCheck %s2 3# Reproducer based on the following C file:4#5# int global1, global2, global3;6#7# extern void ext1(int);8# extern void ext2(int, int);9# extern void ext3(int, int, int);10#11# int test1() {12# int local[3] = {global1, 123, 456};13# ext2(local[0], local[1]);14# return local[1];15# }16#17# int test2() {18# int local[3] = {global1, global2, global3};19# ext3(local[0], local[1], local[2]);20# return local[0];21# }22#23# Compiled using -O1 -g.24 25--- |26 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"27 target triple = "x86_64-unknown-linux-gnu"28 29 @global1 = common global i32 0, align 430 @global2 = common global i32 0, align 431 @global3 = common global i32 0, align 432 33 ; Function Attrs: nounwind uwtable34 define i32 @test1() #0 !dbg !8 {35 entry:36 %0 = load i32, ptr @global1, align 4, !dbg !1637 call void @llvm.dbg.value(metadata i32 %0, metadata !12, metadata !DIExpression(DW_OP_LLVM_fragment, 0, 32)), !dbg !1638 call void @llvm.dbg.value(metadata i32 123, metadata !12, metadata !DIExpression(DW_OP_LLVM_fragment, 32, 32)), !dbg !1639 call void @llvm.dbg.value(metadata i32 456, metadata !12, metadata !DIExpression(DW_OP_LLVM_fragment, 64, 32)), !dbg !1640 tail call void @ext2(i32 %0, i32 123), !dbg !1641 ret i32 123, !dbg !1742 }43 44 declare void @ext2(i32, i32)45 46 ; Function Attrs: nounwind uwtable47 define i32 @test2() #0 !dbg !18 {48 entry:49 %0 = load i32, ptr @global1, align 4, !dbg !2050 call void @llvm.dbg.value(metadata i32 %0, metadata !19, metadata !DIExpression(DW_OP_LLVM_fragment, 0, 32)), !dbg !2051 %1 = load i32, ptr @global2, align 4, !dbg !2052 call void @llvm.dbg.value(metadata i32 %1, metadata !19, metadata !DIExpression(DW_OP_LLVM_fragment, 32, 32)), !dbg !2053 %2 = load i32, ptr @global3, align 4, !dbg !2054 call void @llvm.dbg.value(metadata i32 %2, metadata !19, metadata !DIExpression(DW_OP_LLVM_fragment, 64, 32)), !dbg !2055 tail call void @ext3(i32 %0, i32 %1, i32 %2) #3, !dbg !2056 ret i32 %0, !dbg !2157 }58 59 declare void @ext3(i32, i32, i32)60 61 ; Function Attrs: nounwind readnone speculatable62 declare void @llvm.dbg.value(metadata, metadata, metadata) #163 64 attributes #0 = { nounwind uwtable }65 attributes #1 = { nounwind readnone speculatable }66 67 !llvm.dbg.cu = !{!1}68 !llvm.module.flags = !{!5, !6}69 !llvm.ident = !{!7}70 71 !1 = distinct !DICompileUnit(language: DW_LANG_C99, file: !2, producer: "clang version 9.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !3, globals: !3, nameTableKind: None)72 !2 = !DIFile(filename: "foo.c", directory: "/")73 !3 = !{}74 !4 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)75 !5 = !{i32 2, !"Dwarf Version", i32 4}76 !6 = !{i32 2, !"Debug Info Version", i32 3}77 !7 = !{!"clang version 9.0.0"}78 !8 = distinct !DISubprogram(name: "test1", scope: !2, file: !2, line: 7, type: !9, scopeLine: 7, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !1, retainedNodes: !11)79 !9 = !DISubroutineType(types: !10)80 !10 = !{!4}81 !11 = !{!12}82 !12 = !DILocalVariable(name: "local", scope: !8, file: !2, line: 8, type: !13)83 !13 = !DICompositeType(tag: DW_TAG_array_type, baseType: !4, size: 96, elements: !14)84 !14 = !{!15}85 !15 = !DISubrange(count: 3)86 !16 = !DILocation(line: 8, scope: !8)87 !17 = !DILocation(line: 9, scope: !8)88 !18 = distinct !DISubprogram(name: "test2", scope: !2, file: !2, line: 7, type: !9, scopeLine: 7, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !1, retainedNodes: !22)89 !19 = !DILocalVariable(name: "local", scope: !18, file: !2, line: 8, type: !13)90 !20 = !DILocation(line: 15, scope: !18)91 !21 = !DILocation(line: 16, scope: !18)92 !22 = !{!19}93 94...95---96name: test197tracksRegLiveness: true98body: |99 bb.0.entry:100 frame-setup PUSH64r undef $rax, implicit-def $rsp, implicit $rsp101 renamable $edi = MOV32rm $rip, 1, $noreg, @global1, $noreg, debug-location !16 :: (dereferenceable load (s32) from @global1)102 DBG_VALUE 456, $noreg, !12, !DIExpression(DW_OP_LLVM_fragment, 64, 32), debug-location !16103 DBG_VALUE 123, $noreg, !12, !DIExpression(DW_OP_LLVM_fragment, 32, 32), debug-location !16104 DBG_VALUE $edi, $noreg, !12, !DIExpression(DW_OP_LLVM_fragment, 0, 32), debug-location !16105 $esi = MOV32ri 123, debug-location !16106 CALL64pcrel32 @ext2, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit killed $esi, implicit-def $rsp, implicit-def $ssp, debug-location !16107 $eax = MOV32ri 123, debug-location !17108 $rcx = frame-destroy POP64r implicit-def $rsp, implicit $rsp, debug-location !17109 RET64 killed $eax, debug-location !17110 111...112 113# CHECK: .Ltmp1114# CHECK-NEXT: #DEBUG_VALUE: test1:local <- [DW_OP_LLVM_fragment 64 32] 456115# CHECK-NEXT: #DEBUG_VALUE: test1:local <- [DW_OP_LLVM_fragment 32 32] 123116# CHECK-NEXT: #DEBUG_VALUE: test1:local <- [DW_OP_LLVM_fragment 0 32] $edi117# CHECK: callq ext2118# CHECK-NEXT: .Ltmp2:119 120...121---122name: test2123tracksRegLiveness: true124body: |125 bb.0.entry:126 liveins: $rbx127 128 frame-setup PUSH64r killed $rbx, implicit-def $rsp, implicit $rsp, debug-location !20129 renamable $ebx = MOV32rm $rip, 1, $noreg, @global1, $noreg, debug-location !20 :: (dereferenceable load (s32) from @global1)130 DBG_VALUE $ebx, $noreg, !19, !DIExpression(DW_OP_LLVM_fragment, 0, 32), debug-location !20131 renamable $esi = MOV32rm $rip, 1, $noreg, @global2, $noreg, debug-location !20 :: (dereferenceable load (s32) from @global2)132 DBG_VALUE $esi, $noreg, !19, !DIExpression(DW_OP_LLVM_fragment, 32, 32), debug-location !20133 renamable $edx = MOV32rm $rip, 1, $noreg, @global3, $noreg, debug-location !20 :: (dereferenceable load (s32) from @global3)134 DBG_VALUE $edx, $noreg, !19, !DIExpression(DW_OP_LLVM_fragment, 64, 32), debug-location !20135 $edi = MOV32rr $ebx, debug-location !20136 CALL64pcrel32 @ext3, csr_64, implicit $rsp, implicit $ssp, implicit killed $edi, implicit $esi, implicit $edx, implicit-def $rsp, implicit-def $ssp, debug-location !20137 $eax = MOV32rr killed $ebx, debug-location !20138 $rbx = frame-destroy POP64r implicit-def $rsp, implicit $rsp, debug-location !20139 RET64 killed $eax, debug-location !21140 141...142 143# CHECK: .Ltmp4:144# CHECK-NEXT: #DEBUG_VALUE: test2:local <- [DW_OP_LLVM_fragment 0 32] $ebx145# CHECK: .Ltmp5:146# CHECK-NEXT: #DEBUG_VALUE: test2:local <- [DW_OP_LLVM_fragment 32 32] $esi147# CHECK: .Ltmp6:148# CHECK-NEXT: #DEBUG_VALUE: test2:local <- [DW_OP_LLVM_fragment 64 32] $edx149# CHECK: callq ext3150# CHECK-NEXT: .Ltmp7:151# CHECK: popq %rbx152# CHECK-NEXT: .Ltmp8:153 154#### Location list for test1:local.155 156# Verify that a location list entry, which does not contain the fragment that157# is described by the clobbered $edi, is emitted directly after the call to158# ext2().159 160# CHECK: .Ldebug_loc0:161# CHECK-NEXT: .quad .Ltmp1-.Lfunc_begin0162# CHECK-NEXT: .quad .Ltmp2-.Lfunc_begin0163# CHECK-NEXT: .short 14 # Loc expr size164# CHECK-NEXT: .byte 85 # super-register DW_OP_reg5165# CHECK-NEXT: .byte 147 # DW_OP_piece166# CHECK-NEXT: .byte 4 # 4167# CHECK-NEXT: .byte 16 # DW_OP_constu168# CHECK-NEXT: .byte 123 # 123169# CHECK-NEXT: .byte 159 # DW_OP_stack_value170# CHECK-NEXT: .byte 147 # DW_OP_piece171# CHECK-NEXT: .byte 4 # 4172# CHECK-NEXT: .byte 16 # DW_OP_constu173# CHECK-NEXT: .byte 200 # 456174# CHECK-NEXT: .byte 3 #175# CHECK-NEXT: .byte 159 # DW_OP_stack_value176# CHECK-NEXT: .byte 147 # DW_OP_piece177# CHECK-NEXT: .byte 4 # 4178# CHECK-NEXT: .quad .Ltmp2-.Lfunc_begin0179# CHECK-NEXT: .quad .Lfunc_end0-.Lfunc_begin0180# CHECK-NEXT: .short 13 # Loc expr size181# CHECK-NEXT: .byte 147 # DW_OP_piece182# CHECK-NEXT: .byte 4 # 4183# CHECK-NEXT: .byte 16 # DW_OP_constu184# CHECK-NEXT: .byte 123 # 123185# CHECK-NEXT: .byte 159 # DW_OP_stack_value186# CHECK-NEXT: .byte 147 # DW_OP_piece187# CHECK-NEXT: .byte 4 # 4188# CHECK-NEXT: .byte 16 # DW_OP_constu189# CHECK-NEXT: .byte 200 # 456190# CHECK-NEXT: .byte 3 #191# CHECK-NEXT: .byte 159 # DW_OP_stack_value192# CHECK-NEXT: .byte 147 # DW_OP_piece193# CHECK-NEXT: .byte 4 # 4194# CHECK-NEXT: .quad 0195# CHECK-NEXT: .quad 0196 197#### Location list for test2:local.198 199# Verify that the debug values that are described by $edi and $edx are200# considered clobbered by the call to ext3(), leaving a location list entry201# after the call where the first 32 bits are still described by $ebx.202# That location list entry is valid until the restore of the register.203 204# CHECK: .Ldebug_loc1:205# CHECK-NEXT: .quad .Ltmp4-.Lfunc_begin0206# CHECK-NEXT: .quad .Ltmp5-.Lfunc_begin0207# CHECK-NEXT: .short 3 # Loc expr size208# CHECK-NEXT: .byte 83 # super-register DW_OP_reg3209# CHECK-NEXT: .byte 147 # DW_OP_piece210# CHECK-NEXT: .byte 4 # 4211# CHECK-NEXT: .quad .Ltmp5-.Lfunc_begin0212# CHECK-NEXT: .quad .Ltmp6-.Lfunc_begin0213# CHECK-NEXT: .short 6 # Loc expr size214# CHECK-NEXT: .byte 83 # super-register DW_OP_reg3215# CHECK-NEXT: .byte 147 # DW_OP_piece216# CHECK-NEXT: .byte 4 # 4217# CHECK-NEXT: .byte 84 # super-register DW_OP_reg4218# CHECK-NEXT: .byte 147 # DW_OP_piece219# CHECK-NEXT: .byte 4 # 4220# CHECK-NEXT: .quad .Ltmp6-.Lfunc_begin0221# CHECK-NEXT: .quad .Ltmp7-.Lfunc_begin0222# CHECK-NEXT: .short 9 # Loc expr size223# CHECK-NEXT: .byte 83 # super-register DW_OP_reg3224# CHECK-NEXT: .byte 147 # DW_OP_piece225# CHECK-NEXT: .byte 4 # 4226# CHECK-NEXT: .byte 84 # super-register DW_OP_reg4227# CHECK-NEXT: .byte 147 # DW_OP_piece228# CHECK-NEXT: .byte 4 # 4229# CHECK-NEXT: .byte 81 # super-register DW_OP_reg1230# CHECK-NEXT: .byte 147 # DW_OP_piece231# CHECK-NEXT: .byte 4 # 4232# CHECK-NEXT: .quad .Ltmp7-.Lfunc_begin0233# CHECK-NEXT: .quad .Ltmp8-.Lfunc_begin0234# CHECK-NEXT: .short 3 # Loc expr size235# CHECK-NEXT: .byte 83 # super-register DW_OP_reg3236# CHECK-NEXT: .byte 147 # DW_OP_piece237# CHECK-NEXT: .byte 4 # 4238# CHECK-NEXT: .quad 0239# CHECK-NEXT: .quad 0240