Matthias Braun | fdddd8e | 2018-11-02 01:31:52 +0000 | [diff] [blame] | 1 | # RUN: llc -o - %s -start-after=patchable-function -filetype=obj -O0 -mtriple=i386-unknown-linux-gnu -dwarf-version=4 | llvm-dwarfdump -v - | FileCheck %s |
| 2 | |
| 3 | # From the code: |
| 4 | # |
| 5 | # debug-loc-offset1.cc |
| 6 | # int bar (int b) { |
| 7 | # return b+4; |
| 8 | # } |
| 9 | # |
| 10 | # debug-loc-offset2.cc |
| 11 | # struct A { |
| 12 | # int var; |
| 13 | # virtual char foo(); |
| 14 | # }; |
| 15 | # |
| 16 | # void baz(struct A a) { |
| 17 | # int z = 2; |
| 18 | # if (a.var > 2) |
| 19 | # z++; |
| 20 | # if (a.foo() == 'a') |
| 21 | # z++; |
| 22 | # } |
| 23 | # |
| 24 | # Compiled separately for i386-pc-linux-gnu and linked together. |
| 25 | # This ensures that we have multiple compile units and multiple location lists |
| 26 | # so that we can verify that |
| 27 | # debug_loc entries are relative to the low_pc of the CU. The loc entry for |
| 28 | # the byval argument in foo.cpp is in the second CU and so should have |
| 29 | # an offset relative to that CU rather than from the beginning of the text |
| 30 | # section. |
| 31 | # |
| 32 | # Checking that we have two compile units with two sets of high/lo_pc. |
| 33 | # CHECK: .debug_info contents |
| 34 | # CHECK: DW_TAG_compile_unit |
David Blaikie | 2517961 | 2018-12-22 20:34:58 +0000 | [diff] [blame] | 35 | # CHECK: DW_AT_low_pc {{.*}} (0x0000000000000020 ".text") |
Matthias Braun | fdddd8e | 2018-11-02 01:31:52 +0000 | [diff] [blame] | 36 | # CHECK: DW_AT_high_pc |
| 37 | # |
| 38 | # CHECK: DW_TAG_subprogram |
| 39 | # CHECK-NOT: DW_TAG |
| 40 | # CHECK: DW_AT_linkage_name [DW_FORM_strp]{{.*}}"_Z3baz1A" |
| 41 | # CHECK-NOT: {{DW_TAG|NULL}} |
| 42 | # CHECK: DW_TAG_formal_parameter |
| 43 | # CHECK-NOT: DW_TAG |
| 44 | # CHECK: DW_AT_location [DW_FORM_sec_offset] ({{.*}} |
| 45 | # CHECK-NEXT: [0x00000020, 0x00000037): DW_OP_breg0 EAX+0, DW_OP_deref |
| 46 | # CHECK-NEXT: [0x00000037, 0x00000063): DW_OP_breg5 EBP-8, DW_OP_deref, DW_OP_deref |
| 47 | # CHECK-NEXT: DW_AT_name [DW_FORM_strp]{{.*}}"a" |
| 48 | # |
| 49 | # CHECK: DW_TAG_variable |
| 50 | # CHECK: DW_AT_location [DW_FORM_exprloc] |
| 51 | # CHECK-NOT: DW_AT_location |
| 52 | # |
| 53 | # CHECK: DW_TAG_compile_unit |
David Blaikie | 2517961 | 2018-12-22 20:34:58 +0000 | [diff] [blame] | 54 | # CHECK: DW_AT_low_pc {{.*}} (0x0000000000000000 ".text") |
Matthias Braun | fdddd8e | 2018-11-02 01:31:52 +0000 | [diff] [blame] | 55 | # CHECK: DW_AT_high_pc |
| 56 | # |
| 57 | # CHECK: DW_TAG_subprogram |
| 58 | # CHECK-NOT: DW_TAG |
| 59 | # CHECK: DW_AT_linkage_name [DW_FORM_strp]{{.*}}"_Z3bari" |
| 60 | # CHECK-NOT: {{DW_TAG|NULL}} |
| 61 | # CHECK: DW_TAG_formal_parameter |
| 62 | # CHECK-NOT: DW_TAG |
| 63 | # CHECK: DW_AT_location [DW_FORM_sec_offset] ({{.*}} |
| 64 | # CHECK-NEXT: [0x00000000, 0x0000000a): DW_OP_consts +0, DW_OP_stack_value |
| 65 | # CHECK-NEXT: [0x0000000a, 0x00000017): DW_OP_consts +1, DW_OP_stack_value) |
| 66 | # CHECK-NEXT: DW_AT_name [DW_FORM_strp]{{.*}}"b" |
| 67 | # |
| 68 | # CHECK: .debug_loc contents: |
| 69 | # CHECK: 0x00000000: |
| 70 | # CHECK-NEXT: [0x00000000, 0x0000000a): DW_OP_consts +0, DW_OP_stack_value |
| 71 | # CHECK-NEXT: [0x0000000a, 0x00000017): DW_OP_consts +1, DW_OP_stack_value |
| 72 | # CHECK: 0x00000022: |
| 73 | # CHECK-NEXT: [0x00000000, 0x00000017): DW_OP_breg0 EAX+0, DW_OP_deref |
| 74 | # CHECK-NEXT: [0x00000017, 0x00000043): DW_OP_breg5 EBP-8, DW_OP_deref, DW_OP_deref |
| 75 | --- | |
| 76 | target triple = "i386-unknown-linux-gnu" |
| 77 | |
| 78 | %struct.A = type { i32 (...)**, i32 } |
| 79 | |
| 80 | ; Function Attrs: nounwind |
| 81 | define i32 @_Z3bari(i32 %b) #0 !dbg !10 { |
| 82 | entry: |
| 83 | %b.addr = alloca i32, align 4 |
| 84 | store i32 %b, i32* %b.addr, align 4 |
| 85 | call void @llvm.dbg.value(metadata i32 0, metadata !14, metadata !DIExpression()), !dbg !15 |
| 86 | %0 = load i32, i32* %b.addr, align 4, !dbg !16 |
| 87 | call void @llvm.dbg.value(metadata i32 1, metadata !14, metadata !DIExpression()), !dbg !15 |
| 88 | %add = add nsw i32 %0, 4, !dbg !16 |
| 89 | ret i32 %add, !dbg !16 |
| 90 | } |
| 91 | |
| 92 | ; Function Attrs: nounwind readnone speculatable |
| 93 | declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 |
| 94 | |
| 95 | ; Function Attrs: nounwind readnone speculatable |
| 96 | declare void @llvm.dbg.value(metadata, metadata, metadata) #1 |
| 97 | |
| 98 | define void @_Z3baz1A(%struct.A* %a) #2 !dbg !17 { |
| 99 | entry: |
| 100 | %z = alloca i32, align 4 |
| 101 | call void @llvm.dbg.declare(metadata %struct.A* %a, metadata !20, metadata !DIExpression(DW_OP_deref)), !dbg !21 |
| 102 | call void @llvm.dbg.declare(metadata i32* %z, metadata !22, metadata !DIExpression()), !dbg !23 |
| 103 | store i32 2, i32* %z, align 4, !dbg !23 |
| 104 | %var = getelementptr inbounds %struct.A, %struct.A* %a, i32 0, i32 1, !dbg !24 |
| 105 | %0 = load i32, i32* %var, align 4, !dbg !24 |
| 106 | %cmp = icmp sgt i32 %0, 2, !dbg !24 |
| 107 | br i1 %cmp, label %if.then, label %if.end, !dbg !24 |
| 108 | |
| 109 | if.then: ; preds = %entry |
| 110 | %1 = load i32, i32* %z, align 4, !dbg !26 |
| 111 | %inc = add nsw i32 %1, 1, !dbg !26 |
| 112 | store i32 %inc, i32* %z, align 4, !dbg !26 |
| 113 | br label %if.end, !dbg !26 |
| 114 | |
| 115 | if.end: ; preds = %if.then, %entry |
| 116 | %call = call signext i8 @_ZN1A3fooEv(%struct.A* %a), !dbg !27 |
| 117 | %conv = sext i8 %call to i32, !dbg !27 |
| 118 | %cmp1 = icmp eq i32 %conv, 97, !dbg !27 |
| 119 | br i1 %cmp1, label %if.then2, label %if.end4, !dbg !27 |
| 120 | |
| 121 | if.then2: ; preds = %if.end |
| 122 | %2 = load i32, i32* %z, align 4, !dbg !29 |
| 123 | %inc3 = add nsw i32 %2, 1, !dbg !29 |
| 124 | store i32 %inc3, i32* %z, align 4, !dbg !29 |
| 125 | br label %if.end4, !dbg !29 |
| 126 | |
| 127 | if.end4: ; preds = %if.then2, %if.end |
| 128 | ret void, !dbg !30 |
| 129 | } |
| 130 | |
| 131 | declare signext i8 @_ZN1A3fooEv(%struct.A*) #2 |
| 132 | |
| 133 | ; Function Attrs: nounwind |
| 134 | declare void @llvm.stackprotector(i8*, i8**) #3 |
| 135 | |
| 136 | attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } |
| 137 | attributes #1 = { nounwind readnone speculatable } |
| 138 | attributes #2 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } |
| 139 | attributes #3 = { nounwind } |
| 140 | |
| 141 | !llvm.dbg.cu = !{!0, !3} |
| 142 | !llvm.module.flags = !{!7, !8} |
| 143 | !llvm.ident = !{!9, !9} |
| 144 | |
| 145 | !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.5.0 (210479)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !2, globals: !2, imports: !2) |
| 146 | !1 = !DIFile(filename: "debug-loc-offset1.cc", directory: "/llvm_cmake_gcc") |
| 147 | !2 = !{} |
| 148 | !3 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !4, producer: "clang version 3.5.0 (210479)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !5, globals: !2, imports: !2) |
| 149 | !4 = !DIFile(filename: "debug-loc-offset2.cc", directory: "/llvm_cmake_gcc") |
| 150 | !5 = !{!6} |
| 151 | !6 = !DICompositeType(tag: DW_TAG_structure_type, name: "A", file: !4, line: 1, flags: DIFlagFwdDecl, identifier: "_ZTS1A") |
| 152 | !7 = !{i32 2, !"Dwarf Version", i32 4} |
| 153 | !8 = !{i32 2, !"Debug Info Version", i32 3} |
| 154 | !9 = !{!"clang version 3.5.0 (210479)"} |
| 155 | !10 = distinct !DISubprogram(name: "bar", linkageName: "_Z3bari", scope: !1, file: !1, line: 1, type: !11, isLocal: false, isDefinition: true, scopeLine: 1, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !2) |
| 156 | !11 = !DISubroutineType(types: !12) |
| 157 | !12 = !{!13, !13} |
| 158 | !13 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed) |
| 159 | !14 = !DILocalVariable(name: "b", arg: 1, scope: !10, file: !1, line: 1, type: !13) |
| 160 | !15 = !DILocation(line: 1, scope: !10) |
| 161 | !16 = !DILocation(line: 2, scope: !10) |
| 162 | !17 = distinct !DISubprogram(name: "baz", linkageName: "_Z3baz1A", scope: !4, file: !4, line: 6, type: !18, isLocal: false, isDefinition: true, scopeLine: 6, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !3, retainedNodes: !2) |
| 163 | !18 = !DISubroutineType(types: !19) |
| 164 | !19 = !{null, !6} |
| 165 | !20 = !DILocalVariable(name: "a", arg: 1, scope: !17, file: !4, line: 6, type: !6) |
| 166 | !21 = !DILocation(line: 6, scope: !17) |
| 167 | !22 = !DILocalVariable(name: "z", scope: !17, file: !4, line: 7, type: !13) |
| 168 | !23 = !DILocation(line: 7, scope: !17) |
| 169 | !24 = !DILocation(line: 8, scope: !25) |
| 170 | !25 = distinct !DILexicalBlock(scope: !17, file: !4, line: 8) |
| 171 | !26 = !DILocation(line: 9, scope: !25) |
| 172 | !27 = !DILocation(line: 10, scope: !28) |
| 173 | !28 = distinct !DILexicalBlock(scope: !17, file: !4, line: 10) |
| 174 | !29 = !DILocation(line: 11, scope: !28) |
| 175 | !30 = !DILocation(line: 12, scope: !17) |
| 176 | |
| 177 | ... |
| 178 | --- |
| 179 | name: _Z3bari |
| 180 | alignment: 4 |
| 181 | tracksRegLiveness: true |
| 182 | frameInfo: |
| 183 | stackSize: 8 |
| 184 | offsetAdjustment: -4 |
| 185 | maxAlignment: 4 |
| 186 | maxCallFrameSize: 0 |
| 187 | fixedStack: |
| 188 | - { id: 0, type: spill-slot, offset: -8, size: 4, alignment: 8, stack-id: 0 } |
| 189 | - { id: 1, size: 4, alignment: 16, stack-id: 0 } |
| 190 | stack: |
| 191 | - { id: 0, type: spill-slot, offset: -12, size: 4, alignment: 4, stack-id: 0 } |
| 192 | body: | |
| 193 | bb.0.entry: |
| 194 | frame-setup PUSH32r killed $ebp, implicit-def $esp, implicit $esp |
| 195 | CFI_INSTRUCTION def_cfa_offset 8 |
| 196 | CFI_INSTRUCTION offset $ebp, -8 |
| 197 | $ebp = frame-setup MOV32rr $esp |
| 198 | CFI_INSTRUCTION def_cfa_register $ebp |
| 199 | frame-setup PUSH32r undef $eax, implicit-def $esp, implicit $esp |
| 200 | renamable $eax = MOV32rm $ebp, 1, $noreg, 8, $noreg :: (load 4 from %fixed-stack.1) |
| 201 | DBG_VALUE 0, 0, !14, !DIExpression(), debug-location !15 |
| 202 | renamable $ecx = MOV32rm $ebp, 1, $noreg, 8, $noreg, debug-location !16 :: (load 4 from %ir.b.addr) |
| 203 | DBG_VALUE 1, 0, !14, !DIExpression(), debug-location !15 |
| 204 | renamable $ecx = ADD32ri8 renamable $ecx, 4, implicit-def $eflags, debug-location !16 |
| 205 | MOV32mr $ebp, 1, $noreg, -4, $noreg, killed $eax :: (store 4 into %fixed-stack.1) |
| 206 | $eax = MOV32rr killed $ecx, debug-location !16 |
| 207 | $esp = frame-destroy ADD32ri8 $esp, 4, implicit-def dead $eflags, debug-location !16 |
| 208 | $ebp = frame-destroy POP32r implicit-def $esp, implicit $esp, debug-location !16 |
| 209 | CFI_INSTRUCTION def_cfa $esp, 4, debug-location !16 |
| 210 | RETL implicit killed $eax, debug-location !16 |
| 211 | |
| 212 | ... |
| 213 | --- |
| 214 | name: _Z3baz1A |
| 215 | alignment: 4 |
| 216 | tracksRegLiveness: true |
| 217 | frameInfo: |
| 218 | stackSize: 28 |
| 219 | offsetAdjustment: -24 |
| 220 | maxAlignment: 4 |
| 221 | adjustsStack: true |
| 222 | hasCalls: true |
| 223 | maxCallFrameSize: 4 |
| 224 | fixedStack: |
| 225 | - { id: 0, type: spill-slot, offset: -8, size: 4, alignment: 8, stack-id: 0 } |
| 226 | - { id: 1, size: 4, alignment: 16, stack-id: 0, isImmutable: true } |
| 227 | stack: |
| 228 | - { id: 0, name: z, offset: -12, size: 4, alignment: 4, stack-id: 0, |
| 229 | debug-info-variable: '!22', debug-info-expression: '!DIExpression()', |
| 230 | debug-info-location: '!23' } |
| 231 | - { id: 1, type: spill-slot, offset: -16, size: 4, alignment: 4, stack-id: 0 } |
| 232 | body: | |
| 233 | bb.0.entry: |
| 234 | frame-setup PUSH32r killed $ebp, implicit-def $esp, implicit $esp |
| 235 | CFI_INSTRUCTION def_cfa_offset 8 |
| 236 | CFI_INSTRUCTION offset $ebp, -8 |
| 237 | $ebp = frame-setup MOV32rr $esp |
| 238 | CFI_INSTRUCTION def_cfa_register $ebp |
| 239 | $esp = frame-setup SUB32ri8 $esp, 24, implicit-def dead $eflags |
| 240 | renamable $eax = MOV32rm $ebp, 1, $noreg, 8, $noreg :: (load 4 from %fixed-stack.1) |
| 241 | DBG_VALUE renamable $eax, 0, !20, !DIExpression(DW_OP_deref), debug-location !21 |
| 242 | MOV32mi $ebp, 1, $noreg, -4, $noreg, 2, debug-location !23 :: (store 4 into %ir.z) |
| 243 | CMP32mi8 renamable $eax, 1, $noreg, 4, $noreg, 2, implicit-def $eflags, debug-location !24 :: (load 4 from %ir.var) |
| 244 | MOV32mr $ebp, 1, $noreg, -8, $noreg, killed $eax :: (store 4 into %stack.1) |
| 245 | DBG_VALUE $ebp, 0, !20, !DIExpression(DW_OP_constu, 8, DW_OP_minus, DW_OP_deref, DW_OP_deref), debug-location !21 |
| 246 | JLE_1 %bb.2, implicit $eflags, debug-location !24 |
| 247 | |
| 248 | bb.1.if.then: |
| 249 | DBG_VALUE $ebp, 0, !20, !DIExpression(DW_OP_constu, 8, DW_OP_minus, DW_OP_deref, DW_OP_deref), debug-location !21 |
| 250 | renamable $eax = MOV32rm $ebp, 1, $noreg, -4, $noreg, debug-location !26 :: (load 4 from %ir.z) |
| 251 | renamable $eax = ADD32ri8 renamable $eax, 1, implicit-def $eflags, debug-location !26 |
| 252 | MOV32mr $ebp, 1, $noreg, -4, $noreg, killed renamable $eax, debug-location !26 :: (store 4 into %ir.z) |
| 253 | |
| 254 | bb.2.if.end: |
| 255 | DBG_VALUE $ebp, 0, !20, !DIExpression(DW_OP_constu, 8, DW_OP_minus, DW_OP_deref, DW_OP_deref), debug-location !21 |
| 256 | $eax = MOV32rm $ebp, 1, $noreg, -8, $noreg :: (load 4 from %stack.1) |
| 257 | MOV32mr $esp, 1, $noreg, 0, $noreg, killed renamable $eax, debug-location !27 :: (store 4 into stack) |
| 258 | CALLpcrel32 @_ZN1A3fooEv, csr_32, implicit $esp, implicit $ssp, implicit-def $al, debug-location !27 |
| 259 | renamable $ecx = MOVSX32rr8 killed renamable $al, debug-location !27 |
| 260 | CMP32ri8 killed renamable $ecx, 97, implicit-def $eflags, debug-location !27 |
| 261 | JNE_1 %bb.4, implicit $eflags, debug-location !27 |
| 262 | |
| 263 | bb.3.if.then2: |
| 264 | DBG_VALUE $ebp, 0, !20, !DIExpression(DW_OP_constu, 8, DW_OP_minus, DW_OP_deref, DW_OP_deref), debug-location !21 |
| 265 | renamable $eax = MOV32rm $ebp, 1, $noreg, -4, $noreg, debug-location !29 :: (load 4 from %ir.z) |
| 266 | renamable $eax = ADD32ri8 renamable $eax, 1, implicit-def $eflags, debug-location !29 |
| 267 | MOV32mr $ebp, 1, $noreg, -4, $noreg, killed renamable $eax, debug-location !29 :: (store 4 into %ir.z) |
| 268 | |
| 269 | bb.4.if.end4: |
| 270 | DBG_VALUE $ebp, 0, !20, !DIExpression(DW_OP_constu, 8, DW_OP_minus, DW_OP_deref, DW_OP_deref), debug-location !21 |
| 271 | $esp = frame-destroy ADD32ri8 $esp, 24, implicit-def dead $eflags, debug-location !30 |
| 272 | $ebp = frame-destroy POP32r implicit-def $esp, implicit $esp, debug-location !30 |
| 273 | CFI_INSTRUCTION def_cfa $esp, 4, debug-location !30 |
| 274 | RETL debug-location !30 |
| 275 | |
| 276 | ... |