1; RUN: llc -mcpu=core2 -mtriple=i686-pc-win32 < %s | FileCheck %s --check-prefix=ASM
2; RUN: llc -mcpu=core2 -mtriple=i686-pc-win32 < %s -filetype=obj | llvm-readobj -codeview | FileCheck %s --check-prefix=OBJ
3
4; This LL file was generated by running 'clang -O1 -g -gcodeview' on the
5; following code:
6;  1: extern volatile int x;
7;  2: static inline void foo() {
8;  3:   int y = 1;
9;  4:   x += (int)&y;
10;  5:   x += 2;
11;  6:   x += 3;
12;  7: }
13;  8: static inline void bar() {
14;  9:   x += 4;
15; 10:   foo();
16; 11:   x += 5;
17; 12: }
18; 13: void baz() {
19; 14:   x += 6;
20; 15:   bar();
21; 16:   x += 7;
22; 17: }
23
24; ASM: .cv_func_id 0
25; ASM: .cv_loc 0 1 13 0 is_stmt 0      # t.cpp:13:0
26; ASM: .cv_loc 0 1 14 5                # t.cpp:14:5
27; ASM: addl    $6, "?x@@3HC"
28; ASM: .cv_inline_site_id 1 within 0 inlined_at 1 15 3
29; ASM: .cv_loc 1 1 9 5                 # t.cpp:9:5
30; ASM: addl    $4, "?x@@3HC"
31; ASM: .cv_inline_site_id 2 within 1 inlined_at 1 10 3
32; ASM: .cv_loc 2 1 3 7                 # t.cpp:3:7
33; ASM: .cv_loc 2 1 4 5                 # t.cpp:4:5
34; ASM: addl    {{.*}}, "?x@@3HC"
35; ASM: .cv_loc 2 1 5 5                 # t.cpp:5:5
36; ASM: addl    $2, "?x@@3HC"
37; ASM: .cv_loc 2 1 6 5                 # t.cpp:6:5
38; ASM: addl    $3, "?x@@3HC"
39; ASM: .cv_loc 1 1 11 5                # t.cpp:11:5
40; ASM: addl    $5, "?x@@3HC"
41; ASM: .cv_loc 0 1 16 5                # t.cpp:16:5
42; ASM: addl    $7, "?x@@3HC"
43; ASM: .cv_loc 0 1 17 1                # t.cpp:17:1
44
45; ASM: .section .debug$S,"dr"
46; ASM: .long   246                     # Inlinee lines subsection
47; ASM: .long   [[inline_end:.*]]-[[inline_beg:.*]] #
48; ASM: [[inline_beg]]:
49; ASM: .long   0
50; ASM: # Inlined function bar starts at t.cpp:8
51; ASM: .long   4098                    # Type index of inlined function
52; ASM: .cv_filechecksumoffset 1        # Offset into filechecksum table
53; ASM: .long   8                       # Starting line number
54; ASM: # Inlined function foo starts at t.cpp:2
55; ASM: .long   4099
56; ASM: .cv_filechecksumoffset 1        # Offset into filechecksum table
57; ASM: .long   2
58; ASM: [[inline_end]]:
59
60; ASM: .long   241                     # Symbol subsection for baz
61; ASM: .long   {{.*}} # Subsection size
62; ASM: .short 4429
63; ASM: .long
64; ASM: .long
65; ASM: .long
66; ASM: .cv_inline_linetable 1 1 8 Lfunc_begin0 Lfunc_end0
67; ASM: .short 4429
68; ASM: .long
69; ASM: .long
70; ASM: .long
71; ASM: .cv_inline_linetable 2 1 2 Lfunc_begin0 Lfunc_end0
72; ASM: .short  4430
73; ASM: .short  4430
74
75; ASM: .cv_filechecksums
76
77; ASM: .section .debug$T,"dr"
78; ASM: .long 4 # Debug section magic
79; ASM: # ArgList (0x1000) {
80; ASM: #   TypeLeafKind: LF_ARGLIST (0x1201)
81; ASM: #   NumArgs: 0
82; ASM: #   Arguments [
83; ASM: #   ]
84; ASM: # }
85; ASM: .byte   0x06, 0x00, 0x01, 0x12
86; ASM: .byte   0x00, 0x00, 0x00, 0x00
87; ASM: # Procedure (0x1001) {
88; ASM: #   TypeLeafKind: LF_PROCEDURE (0x1008)
89; ASM: #   ReturnType: void (0x3)
90; ASM: #   CallingConvention: NearC (0x0)
91; ASM: #   FunctionOptions [ (0x0)
92; ASM: #   ]
93; ASM: #   NumParameters: 0
94; ASM: #   ArgListType: () (0x1000)
95; ASM: # }
96; ASM: .byte   0x0e, 0x00, 0x08, 0x10
97; ASM: .byte   0x03, 0x00, 0x00, 0x00
98; ASM: .byte   0x00, 0x00, 0x00, 0x00
99; ASM: .byte   0x00, 0x10, 0x00, 0x00
100; ASM: # FuncId (0x1002) {
101; ASM: #   TypeLeafKind: LF_FUNC_ID (0x1601)
102; ASM: #   ParentScope: 0x0
103; ASM: #   FunctionType: void () (0x1001)
104; ASM: #   Name: bar
105; ASM: # }
106; ASM: .byte   0x0e, 0x00, 0x01, 0x16
107; ASM: .byte   0x00, 0x00, 0x00, 0x00
108; ASM: .byte   0x01, 0x10, 0x00, 0x00
109; ASM: .byte   0x62, 0x61, 0x72, 0x00
110; ASM: # FuncId (0x1003) {
111; ASM: #   TypeLeafKind: LF_FUNC_ID (0x1601)
112; ASM: #   ParentScope: 0x0
113; ASM: #   FunctionType: void () (0x1001)
114; ASM: #   Name: foo
115; ASM: # }
116; ASM: .byte   0x0e, 0x00, 0x01, 0x16
117; ASM: .byte   0x00, 0x00, 0x00, 0x00
118; ASM: .byte   0x01, 0x10, 0x00, 0x00
119; ASM: .byte   0x66, 0x6f, 0x6f, 0x00
120
121; We should only the LF_FUNC_ID records that we needed to reference.
122; OBJ: CodeViewTypes [
123; OBJ:   Section: .debug$T
124; OBJ:   ArgList (0x1000) {
125; OBJ:     TypeLeafKind: LF_ARGLIST (0x1201)
126; OBJ:     NumArgs: 0
127; OBJ:   }
128; OBJ:   Procedure (0x1001) {
129; OBJ:     TypeLeafKind: LF_PROCEDURE (0x1008)
130; OBJ:     ReturnType: void (0x3)
131; OBJ:     NumParameters: 0
132; OBJ:     ArgListType: () (0x1000)
133; OBJ:   }
134; OBJ:   FuncId (0x1002) {
135; OBJ:     TypeLeafKind: LF_FUNC_ID (0x1601)
136; OBJ:     ParentScope: 0x0
137; OBJ:     FunctionType: void () (0x1001)
138; OBJ:     Name: bar
139; OBJ:   }
140; OBJ:   FuncId (0x1003) {
141; OBJ:     TypeLeafKind: LF_FUNC_ID (0x1601)
142; OBJ:     ParentScope: 0x0
143; OBJ:     FunctionType: void () (0x1001)
144; OBJ:     Name: foo
145; OBJ:   }
146; OBJ:   FuncId (0x1004) {
147; OBJ:     TypeLeafKind: LF_FUNC_ID (0x1601)
148; OBJ:     ParentScope: 0x0
149; OBJ:     FunctionType: void () (0x1001)
150; OBJ:     Name: baz
151; OBJ:   }
152; OBJ-NOT: TypeLeafKind: LF_FUNC_ID
153; OBJ: ]
154
155; OBJ: Subsection [
156; OBJ:   SubSectionType: InlineeLines (0xF6)
157; OBJ:   SubSectionSize: 0x1C
158; OBJ:   InlineeSourceLine {
159; OBJ:     Inlinee: bar (0x1002)
160; OBJ:     FileID: D:\src\llvm\build\t.cpp (0x0)
161; OBJ:     SourceLineNum: 8
162; OBJ:   }
163; OBJ:   InlineeSourceLine {
164; OBJ:     Inlinee: foo (0x1003)
165; OBJ:     FileID: D:\src\llvm\build\t.cpp (0x0)
166; OBJ:     SourceLineNum: 2
167; OBJ:   }
168; OBJ: ]
169; OBJ: Subsection [
170; OBJ:   SubSectionType: Symbols (0xF1)
171; OBJ:   {{.*}}Proc{{.*}}Sym {
172; OBJ:     PtrParent: 0x0
173; OBJ:     PtrEnd: 0x0
174; OBJ:     PtrNext: 0x0
175; OBJ:     CodeSize: 0x3C
176; OBJ:     DbgStart: 0x0
177; OBJ:     DbgEnd: 0x0
178; OBJ:     FunctionType: baz (0x1004)
179; OBJ:     CodeOffset: ?baz@@YAXXZ+0x0
180; OBJ:     Segment: 0x0
181; OBJ:     Flags [ (0x0)
182; OBJ:     ]
183; OBJ:     DisplayName: baz
184; OBJ:     LinkageName: ?baz@@YAXXZ
185; OBJ:   }
186; OBJ:   InlineSiteSym {
187; OBJ:     PtrParent: 0x0
188; OBJ:     PtrEnd: 0x0
189; OBJ:     Inlinee: bar (0x1002)
190; OBJ:      BinaryAnnotations [
191; OBJ-NEXT:   ChangeCodeOffsetAndLineOffset: {CodeOffset: 0x8, LineOffset: 1}
192; OBJ-NEXT:   ChangeCodeOffsetAndLineOffset: {CodeOffset: 0x7, LineOffset: 1}
193; OBJ-NEXT:   ChangeLineOffset: 1
194; OBJ-NEXT:   ChangeCodeOffset: 0x1D
195; OBJ-NEXT:   ChangeCodeLength: 0x7
196; OBJ:      ]
197; OBJ:   }
198; OBJ:   InlineSiteSym {
199; OBJ:     PtrParent: 0x0
200; OBJ:     PtrEnd: 0x0
201; OBJ:     Inlinee: foo (0x1003)
202; OBJ:     BinaryAnnotations [
203; OBJ-NEXT:  ChangeCodeOffsetAndLineOffset: {CodeOffset: 0xF, LineOffset: 1}
204; OBJ-NEXT:  ChangeCodeOffsetAndLineOffset: {CodeOffset: 0x9, LineOffset: 1}
205; OBJ-NEXT:  ChangeCodeOffsetAndLineOffset: {CodeOffset: 0x6, LineOffset: 1}
206; OBJ-NEXT:  ChangeCodeOffsetAndLineOffset: {CodeOffset: 0x7, LineOffset: 1}
207; OBJ-NEXT:  ChangeCodeLength: 0x7
208; OBJ:     ]
209; OBJ:   }
210; OBJ:   InlineSiteEnd {
211; OBJ:   }
212; OBJ:   InlineSiteEnd {
213; OBJ:   }
214; OBJ:   ProcEnd
215; OBJ: ]
216
217; ModuleID = 't.cpp'
218target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
219target triple = "x86_64-pc-windows-msvc18.0.0"
220
221@"\01?x@@3HC" = external global i32, align 4
222
223; Function Attrs: norecurse nounwind uwtable
224define void @"\01?baz@@YAXXZ"() #0 !dbg !4 {
225entry:
226  %y.i.i = alloca i32, align 4
227  %0 = load volatile i32, i32* @"\01?x@@3HC", align 4, !dbg !12, !tbaa !13
228  %add = add nsw i32 %0, 6, !dbg !12
229  store volatile i32 %add, i32* @"\01?x@@3HC", align 4, !dbg !12, !tbaa !13
230  %1 = load volatile i32, i32* @"\01?x@@3HC", align 4, !dbg !17, !tbaa !13
231  %add.i = add nsw i32 %1, 4, !dbg !17
232  store volatile i32 %add.i, i32* @"\01?x@@3HC", align 4, !dbg !17, !tbaa !13
233  %2 = bitcast i32* %y.i.i to i8*, !dbg !19
234  call void @llvm.lifetime.start(i64 4, i8* %2) #2, !dbg !19
235  store i32 1, i32* %y.i.i, align 4, !dbg !21, !tbaa !13
236  %3 = ptrtoint i32* %y.i.i to i64, !dbg !22
237  %4 = trunc i64 %3 to i32, !dbg !22
238  %5 = load volatile i32, i32* @"\01?x@@3HC", align 4, !dbg !23, !tbaa !13
239  %add.i.i = add nsw i32 %5, %4, !dbg !23
240  store volatile i32 %add.i.i, i32* @"\01?x@@3HC", align 4, !dbg !23, !tbaa !13
241  %6 = load volatile i32, i32* @"\01?x@@3HC", align 4, !dbg !24, !tbaa !13
242  %add1.i.i = add nsw i32 %6, 2, !dbg !24
243  store volatile i32 %add1.i.i, i32* @"\01?x@@3HC", align 4, !dbg !24, !tbaa !13
244  %7 = load volatile i32, i32* @"\01?x@@3HC", align 4, !dbg !25, !tbaa !13
245  %add2.i.i = add nsw i32 %7, 3, !dbg !25
246  store volatile i32 %add2.i.i, i32* @"\01?x@@3HC", align 4, !dbg !25, !tbaa !13
247  call void @llvm.lifetime.end(i64 4, i8* %2) #2, !dbg !26
248  %8 = load volatile i32, i32* @"\01?x@@3HC", align 4, !dbg !27, !tbaa !13
249  %add1.i = add nsw i32 %8, 5, !dbg !27
250  store volatile i32 %add1.i, i32* @"\01?x@@3HC", align 4, !dbg !27, !tbaa !13
251  %9 = load volatile i32, i32* @"\01?x@@3HC", align 4, !dbg !28, !tbaa !13
252  %add1 = add nsw i32 %9, 7, !dbg !28
253  store volatile i32 %add1, i32* @"\01?x@@3HC", align 4, !dbg !28, !tbaa !13
254  ret void, !dbg !29
255}
256
257; Function Attrs: argmemonly nounwind
258declare void @llvm.lifetime.start(i64, i8* nocapture) #1
259
260; Function Attrs: argmemonly nounwind
261declare void @llvm.lifetime.end(i64, i8* nocapture) #1
262
263attributes #0 = { norecurse nounwind uwtable "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
264attributes #1 = { argmemonly nounwind }
265attributes #2 = { nounwind }
266
267!llvm.dbg.cu = !{!0}
268!llvm.module.flags = !{!8, !9, !10}
269!llvm.ident = !{!11}
270
271!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.9.0 ", isOptimized: true, runtimeVersion: 0, emissionKind: LineTablesOnly, enums: !2)
272!1 = !DIFile(filename: "t.cpp", directory: "D:\5Csrc\5Cllvm\5Cbuild")
273!2 = !{}
274!4 = distinct !DISubprogram(name: "baz", scope: !1, file: !1, line: 13, type: !5, isLocal: false, isDefinition: true, scopeLine: 13, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !2)
275!5 = !DISubroutineType(types: !2)
276!6 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 8, type: !5, isLocal: true, isDefinition: true, scopeLine: 8, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !2)
277!7 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 2, type: !5, isLocal: true, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !2)
278!8 = !{i32 2, !"CodeView", i32 1}
279!9 = !{i32 2, !"Debug Info Version", i32 3}
280!10 = !{i32 1, !"PIC Level", i32 2}
281!11 = !{!"clang version 3.9.0 "}
282!12 = !DILocation(line: 14, column: 5, scope: !4)
283!13 = !{!14, !14, i64 0}
284!14 = !{!"int", !15, i64 0}
285!15 = !{!"omnipotent char", !16, i64 0}
286!16 = !{!"Simple C/C++ TBAA"}
287!17 = !DILocation(line: 9, column: 5, scope: !6, inlinedAt: !18)
288!18 = distinct !DILocation(line: 15, column: 3, scope: !4)
289!19 = !DILocation(line: 3, column: 3, scope: !7, inlinedAt: !20)
290!20 = distinct !DILocation(line: 10, column: 3, scope: !6, inlinedAt: !18)
291!21 = !DILocation(line: 3, column: 7, scope: !7, inlinedAt: !20)
292!22 = !DILocation(line: 4, column: 8, scope: !7, inlinedAt: !20)
293!23 = !DILocation(line: 4, column: 5, scope: !7, inlinedAt: !20)
294!24 = !DILocation(line: 5, column: 5, scope: !7, inlinedAt: !20)
295!25 = !DILocation(line: 6, column: 5, scope: !7, inlinedAt: !20)
296!26 = !DILocation(line: 7, column: 1, scope: !7, inlinedAt: !20)
297!27 = !DILocation(line: 11, column: 5, scope: !6, inlinedAt: !18)
298!28 = !DILocation(line: 16, column: 5, scope: !4)
299!29 = !DILocation(line: 17, column: 1, scope: !4)
300