1; RUN: llc -O0 %s -mtriple=msp430 -filetype=obj -o - -minimize-addr-in-v5=Ranges \
2; RUN:   | llvm-dwarfdump -debug-info -debug-addr -debug-rnglists -v - \
3; RUN:   | FileCheck --check-prefix=CHECK --check-prefix=RNG \
4; RUN:     --implicit-check-not=DW_TAG --implicit-check-not=NULL --implicit-check-not=_pc %s
5
6; RUN: llc -O0 %s -mtriple=msp430 -filetype=obj -o - -minimize-addr-in-v5=Expressions \
7; RUN:   | llvm-dwarfdump -debug-info -debug-addr -debug-rnglists -v - \
8; RUN:   | FileCheck --check-prefix=CHECK --check-prefix=EXPRORFORM --check-prefix=EXPR\
9; RUN:     --implicit-check-not=DW_TAG --implicit-check-not=NULL --implicit-check-not=_pc %s
10
11; RUN: llc -O0 %s -mtriple=msp430 -filetype=obj -o - -minimize-addr-in-v5=Form \
12; RUN:   | llvm-dwarfdump -debug-info -debug-addr -debug-rnglists -v - \
13; RUN:   | FileCheck --check-prefix=CHECK --check-prefix=EXPRORFORM --check-prefix=FORM \
14; RUN:     --implicit-check-not=DW_TAG --implicit-check-not=NULL --implicit-check-not=_pc %s
15
16; Ported from X86 test to cover 2-byte address size case
17
18; Generated from the following source. f4 is used to put a hole in the CU
19; ranges while keeping f2 and f4 in the same section (as opposed to
20; -ffunction-sections, which would produce CU ranges, but each function would
21; be in a different section, so unable to share addresses). The call to f1 at
22; the start of f3 ensures the range for the inlined subroutine doesn't share
23; the starting address with f3 (so it can be improved by using a rnglist to
24; allow it to share an address it wouldn't already be sharing).
25
26; Without f6 being in another section, technically we could use a non-zero CU
27; low_pc that could act as a base address for all the addresses in the CU & avoid
28; the need for these forced rnglists - we don't do that currently, but f6 ensures
29; that this test will remain meaningful even if that improvement is made in the
30; future. (implementing that would require detecting that all the addresses in
31; the CU ranges are in the same section, then picking the lowest such address as
32; the base address to make all other addresses relative to)
33
34; IR from the following, compiled with:
35; $ clang -g -c -gdwarf-5 -O1
36; __attribute__((optnone)) void f1() { }
37; __attribute__((always_inline)) inline void f2() {
38;   f1();
39; }
40; void f3() {
41;   f1();
42;   f2();
43; }
44; __attribute__((nodebug)) void f4() {
45; }
46; void f5() {
47; }
48; __attribute__((section(".other"))) void f6() {
49; }
50
51; CHECK-LABEL: .debug_info contents:
52; CHECK: DW_TAG_compile_unit
53; CHECK:   DW_AT_low_pc
54; CHECK-SAME: (0x0000)
55; RNG:     DW_AT_ranges
56; RNG-SAME:  (indexed (0x3) rangelist = [[CU_RANGE:.*]]
57; EXPRORFORM: DW_AT_ranges
58; EXPRORFORM-SAME: (indexed (0x0) rangelist = [[CU_RANGE:.*]]
59; CHECK:   DW_TAG_subprogram
60; CHECK:     DW_AT_low_pc
61; CHECK-SAME:  (indexed (00000000) address = 0x0000 ".text")
62; CHECK:     DW_AT_high_pc
63; CHECK-SAME:  (0x00000002)
64; CHECK:     DW_AT_name
65; CHECK-SAME:  "f1"
66; CHECK:   DW_TAG_subprogram
67; CHECK:     DW_AT_name
68; CHECK-SAME:  "f2"
69; CHECK:   DW_TAG_subprogram
70; EXPR:      DW_AT_low_pc
71; EXPR-SAME:   (DW_OP_addrx 0x0, DW_OP_const4u 0x2, DW_OP_plus)
72; FORM:      DW_AT_low_pc
73; FORM-SAME:   [DW_FORM_LLVM_addrx_offset] (indexed (00000000) + 0x2 address = 0x0002 ".text")
74; EXPRORFORM: DW_AT_high_pc
75; EXPRORFORM-SAME: (0x0000000a)
76; RNG:       DW_AT_ranges
77; RNG-SAME:    (indexed (0x0) rangelist = [[F3_RANGE:.*]]
78; CHECK:     DW_AT_name
79; CHECK-SAME: "f3"
80; CHECK:     DW_TAG_inlined_subroutine
81; EXPR:        DW_AT_low_pc
82; EXPR-SAME:     [DW_FORM_exprloc] (DW_OP_addrx 0x0, DW_OP_const4u 0x6, DW_OP_plus)
83; FORM:        DW_AT_low_pc
84; FORM-SAME:     [DW_FORM_LLVM_addrx_offset] (indexed (00000000) + 0x6 address = 0x0006 ".text")
85; EXPRORFORM:  DW_AT_high_pc
86; EXPRORFORM-SAME: (0x00000004)
87; RNG:         DW_AT_ranges
88; RNG-SAME:      (indexed (0x1) rangelist = [[INL_RANGE:.*]]
89; CHECK:     DW_TAG_call_site
90; RNG:         DW_AT_call_return_pc
91; RNG-SAME:      (indexed (00000001) address = 0x0006 ".text")
92; EXPR:        DW_AT_call_return_pc
93; EXPR-SAME:     [DW_FORM_exprloc] (DW_OP_addrx 0x0, DW_OP_const4u 0x6, DW_OP_plus)
94; FORM:        DW_AT_call_return_pc
95; FORM-SAME:     [DW_FORM_LLVM_addrx_offset] (indexed (00000000) + 0x6 address = 0x0006 ".text")
96; CHECK:     DW_TAG_call_site
97; RNG:         DW_AT_call_return_pc
98; RNG-SAME:      (indexed (00000002) address = 0x000a ".text")
99; EXPR:        DW_AT_call_return_pc
100; EXPR-SAME:     [DW_FORM_exprloc] (DW_OP_addrx 0x0, DW_OP_const4u 0xa, DW_OP_plus)
101; FORM:        DW_AT_call_return_pc
102; FORM-SAME:     [DW_FORM_LLVM_addrx_offset] (indexed (00000000) + 0xa address = 0x000a ".text")
103; CHECK:     NULL
104; CHECK:   DW_TAG_subprogram
105; EXPR:      DW_AT_low_pc
106; EXPR-SAME:   [DW_FORM_exprloc] (DW_OP_addrx 0x0, DW_OP_const4u 0xe, DW_OP_plus)
107; FORM:      DW_AT_low_pc
108; FORM-SAME:   [DW_FORM_LLVM_addrx_offset] (indexed (00000000) + 0xe address = 0x000e ".text")
109; EXPRORFORM: DW_AT_high_pc
110; EXPRORFORM-SAME: (0x00000002)
111; RNG:       DW_AT_ranges
112; RNG-SAME:    (indexed (0x2) rangelist = [[F5_RANGE:.*]]
113; CHECK:     DW_AT_name
114; CHECK-SAME:  "f5"
115; CHECK:   DW_TAG_subprogram
116; CHECK:     DW_AT_low_pc [DW_FORM_addrx]    (indexed (
117; RNG-SAME: 00000003
118; EXPRORFORM-SAME: 00000001
119; CHECK: ) address = 0x0000 ".other")
120; CHECK:     DW_AT_high_pc
121; CHECK-SAME:  (0x00000006)
122; CHECK:     DW_AT_name
123; CHECK-SAME: "f6"
124; CHECK:       DW_TAG_inlined_subroutine
125; RNG:           DW_AT_low_pc
126; RNG-SAME:        (indexed (00000003) address = 0x0000 ".other")
127; EXPRORFORM:    DW_AT_low_pc
128; EXPRORFORM-SAME: (indexed (00000001) address = 0x0000 ".other")
129; CHECK:         DW_AT_high_pc
130; CHECK-SAME:      (0x00000004)
131; CHECK:       DW_TAG_call_site
132; CHECK:         DW_AT_call_return_pc
133; CHECK:       NULL
134; CHECK:   NULL
135
136; CHECK-LABEL: .debug_addr contents:
137; CHECK: 0x00000000: Address table
138; CHECK-NEXT: Addrs: [
139; CHECK-NEXT: 0x0000
140; RNG-NEXT:   0x0006
141; RNG-NEXT:   0x000a
142; CHECK-NEXT: 0x0000
143; RNG-NEXT:   0x0004
144; CHECK-NEXT: ]
145
146; CHECK-LABEL: .debug_rnglists contents:
147; RNG: 0x00000000: range list header: {{.*}}, offset_entry_count = 0x00000004
148; EXPRORFORM: 0x00000000: range list header: {{.*}}, offset_entry_count = 0x00000001
149; CHECK: ranges:
150; RNG-NEXT:   [[F3_RANGE]]: [DW_RLE_base_addressx]:
151; RNG-SAME:                   0x0000
152; RNG-NEXT:                 [DW_RLE_offset_pair  ]
153; RNG-NEXT:                 [DW_RLE_end_of_list  ]
154
155; RNG-NEXT:   [[INL_RANGE]]: [DW_RLE_base_addressx]:
156; RNG-SAME:                    0x0000
157; RNG-NEXT:                  [DW_RLE_offset_pair  ]
158; RNG-NEXT:                  [DW_RLE_end_of_list  ]
159
160; RNG-NEXT:   [[F5_RANGE]]: [DW_RLE_base_addressx]:
161; RNG-SAME:                   0x0000
162; RNG-NEXT:                 [DW_RLE_offset_pair  ]
163; RNG-NEXT:                 [DW_RLE_end_of_list  ]
164
165; CHECK-NEXT: [[CU_RANGE]]: [DW_RLE_base_addressx]:
166; CHECK-SAME:                 0x0000
167; CHECK-NEXT:               [DW_RLE_offset_pair  ]
168; CHECK-NEXT:               [DW_RLE_offset_pair  ]
169; RNG-NEXT:                 [DW_RLE_startx_length]:
170; RNG-SAME:                   0x0003
171; EXPRORFORM-NEXT:          [DW_RLE_startx_length]:
172; EXPRORFORM-SAME:            0x0001
173; CHECK-NEXT:               [DW_RLE_end_of_list  ]
174
175; Function Attrs: mustprogress noinline nounwind optnone uwtable
176define dso_local void @_Z2f1v() local_unnamed_addr #0 !dbg !7 {
177entry:
178  ret void, !dbg !12
179}
180
181; Function Attrs: mustprogress nounwind uwtable
182define dso_local void @_Z2f3v() local_unnamed_addr #1 !dbg !13 {
183entry:
184  call void @_Z2f1v(), !dbg !14
185  call void @_Z2f1v() #3, !dbg !15
186  ret void, !dbg !18
187}
188
189; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone uwtable willreturn
190define dso_local void @_Z2f4v() local_unnamed_addr #2 {
191entry:
192  ret void
193}
194
195; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone uwtable willreturn
196define dso_local void @_Z2f5v() local_unnamed_addr #2 !dbg !19 {
197entry:
198  ret void, !dbg !20
199}
200
201; Function Attrs: mustprogress nounwind uwtable
202define dso_local void @_Z2f6v() local_unnamed_addr #1 section ".other" !dbg !21 {
203entry:
204  call void @_Z2f1v() #3, !dbg !22
205  ret void, !dbg !24
206}
207
208attributes #0 = { mustprogress noinline nounwind optnone uwtable "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
209attributes #1 = { mustprogress nounwind uwtable "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
210attributes #2 = { mustprogress nofree norecurse nosync nounwind readnone uwtable willreturn "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
211attributes #3 = { nounwind }
212
213!llvm.dbg.cu = !{!0}
214!llvm.module.flags = !{!2, !3, !4, !5}
215!llvm.ident = !{!6}
216
217!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 14.0.0 ([email protected]:llvm/llvm-project.git e2c3dc6fc76e767f08249f6d2c36e41660a4e331)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
218!1 = !DIFile(filename: "/usr/local/google/home/blaikie/dev/scratch/test.cpp", directory: "/usr/local/google/home/blaikie/dev/llvm/src", checksumkind: CSK_MD5, checksum: "e70db21a276125757057e729999c09c7")
219!2 = !{i32 7, !"Dwarf Version", i32 5}
220!3 = !{i32 2, !"Debug Info Version", i32 3}
221!4 = !{i32 1, !"wchar_size", i32 4}
222!5 = !{i32 7, !"uwtable", i32 1}
223!6 = !{!"clang version 14.0.0 ([email protected]:llvm/llvm-project.git e2c3dc6fc76e767f08249f6d2c36e41660a4e331)"}
224!7 = distinct !DISubprogram(name: "f1", linkageName: "_Z2f1v", scope: !8, file: !8, line: 1, type: !9, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
225!8 = !DIFile(filename: "scratch/test.cpp", directory: "/usr/local/google/home/blaikie/dev", checksumkind: CSK_MD5, checksum: "e70db21a276125757057e729999c09c7")
226!9 = !DISubroutineType(types: !10)
227!10 = !{null}
228!11 = !{}
229!12 = !DILocation(line: 1, column: 38, scope: !7)
230!13 = distinct !DISubprogram(name: "f3", linkageName: "_Z2f3v", scope: !8, file: !8, line: 5, type: !9, scopeLine: 5, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
231!14 = !DILocation(line: 6, column: 3, scope: !13)
232!15 = !DILocation(line: 3, column: 3, scope: !16, inlinedAt: !17)
233!16 = distinct !DISubprogram(name: "f2", linkageName: "_Z2f2v", scope: !8, file: !8, line: 2, type: !9, scopeLine: 2, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
234!17 = distinct !DILocation(line: 7, column: 3, scope: !13)
235!18 = !DILocation(line: 8, column: 1, scope: !13)
236!19 = distinct !DISubprogram(name: "f5", linkageName: "_Z2f5v", scope: !8, file: !8, line: 11, type: !9, scopeLine: 11, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
237!20 = !DILocation(line: 12, column: 1, scope: !19)
238!21 = distinct !DISubprogram(name: "f6", linkageName: "_Z2f6v", scope: !8, file: !8, line: 13, type: !9, scopeLine: 13, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
239!22 = !DILocation(line: 3, column: 3, scope: !16, inlinedAt: !23)
240!23 = distinct !DILocation(line: 14, column: 3, scope: !21)
241!24 = !DILocation(line: 15, column: 1, scope: !21)
242