• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; Test the the loop nest depth is correctly calculated for basic blocks.
2
3; REQUIRES: allow_dump
4
5; Single threaded so that the dumps used for checking happen in order.
6; RUN: %p2i --filetype=obj --disassemble -i %s --args -O2 --verbose=loop \
7; RUN:     -log=%t --threads=0 && FileCheck %s < %t
8
9define internal void @test_single_loop(i32 %a32) {
10entry:
11  %a = trunc i32 %a32 to i1
12  br label %loop0
13
14loop0:                               ; <-+
15  br label %loop1                    ;   |
16loop1:                               ;   |
17  br i1 %a, label %loop0, label %out ; --+
18
19out:
20  ret void
21}
22
23; CHECK-LABEL: After loop analysis
24; CHECK-NEXT: entry:
25; CHECK-NEXT: LoopNestDepth = 0
26; CHECK-NEXT: loop0:
27; CHECK-NEXT: LoopNestDepth = 1
28; CHECK-NEXT: loop1:
29; CHECK-NEXT: LoopNestDepth = 1
30; CHECK-NEXT: out:
31; CHECK-NEXT: LoopNestDepth = 0
32; CHECK-LABEL: Before RMW
33
34define internal void @test_single_loop_with_continue(i32 %a32, i32 %b32) {
35entry:
36  %a = trunc i32 %a32 to i1
37  %b = trunc i32 %b32 to i1
38  br label %loop0
39
40loop0:                                 ; <-+
41  br label %loop1                      ;   |
42loop1:                                 ;   |
43  br i1 %a, label %loop0, label %loop2 ; --+
44loop2:                                 ;   |
45  br i1 %b, label %loop0, label %out   ; --+
46
47out:
48  ret void
49}
50
51; CHECK-LABEL: After loop analysis
52; CHECK-NEXT: entry:
53; CHECK-NEXT: LoopNestDepth = 0
54; CHECK-NEXT: loop0:
55; CHECK-NEXT: LoopNestDepth = 1
56; CHECK-NEXT: loop1:
57; CHECK-NEXT: LoopNestDepth = 1
58; CHECK-NEXT: loop2:
59; CHECK-NEXT: LoopNestDepth = 1
60; CHECK-NEXT: out:
61; CHECK-NEXT: LoopNestDepth = 0
62; CHECK-LABEL: Before RMW
63
64define internal void @test_multiple_exits(i32 %a32, i32 %b32) {
65entry:
66  %a = trunc i32 %a32 to i1
67  %b = trunc i32 %b32 to i1
68  br label %loop0
69
70loop0:                               ; <-+
71  br label %loop1                    ;   |
72loop1:                               ;   |
73  br i1 %a, label %loop2, label %out ; --+-+
74loop2:                               ;   | |
75  br i1 %b, label %loop0, label %out ; --+ |
76                                     ;     |
77out:                                 ; <---+
78  ret void
79}
80
81; CHECK-LABEL: After loop analysis
82; CHECK-NEXT: entry:
83; CHECK-NEXT: LoopNestDepth = 0
84; CHECK-NEXT: loop0:
85; CHECK-NEXT: LoopNestDepth = 1
86; CHECK-NEXT: loop1:
87; CHECK-NEXT: LoopNestDepth = 1
88; CHECK-NEXT: loop2:
89; CHECK-NEXT: LoopNestDepth = 1
90; CHECK-NEXT: out:
91; CHECK-NEXT: LoopNestDepth = 0
92; CHECK-LABEL: Before RMW
93
94define internal void @test_two_nested_loops(i32 %a32, i32 %b32) {
95entry:
96  %a = trunc i32 %a32 to i1
97  %b = trunc i32 %b32 to i1
98  br label %loop0_0
99
100loop0_0:                                   ; <---+
101  br label %loop1_0                        ;     |
102loop1_0:                                   ; <-+ |
103  br label %loop1_1                        ;   | |
104loop1_1:                                   ;   | |
105  br i1 %a, label %loop1_0, label %loop0_1 ; --+ |
106loop0_1:                                   ;     |
107  br i1 %b, label %loop0_0, label %out     ; ----+
108
109out:
110  ret void
111}
112
113; CHECK-LABEL: After loop analysis
114; CHECK-NEXT: entry:
115; CHECK-NEXT: LoopNestDepth = 0
116; CHECK-NEXT: loop0_0:
117; CHECK-NEXT: LoopNestDepth = 1
118; CHECK-NEXT: loop1_0:
119; CHECK-NEXT: LoopNestDepth = 2
120; CHECK-NEXT: loop1_1:
121; CHECK-NEXT: LoopNestDepth = 2
122; CHECK-NEXT: loop0_1:
123; CHECK-NEXT: LoopNestDepth = 1
124; CHECK-NEXT: out:
125; CHECK-NEXT: LoopNestDepth = 0
126; CHECK-LABEL: Before RMW
127
128define internal void @test_two_nested_loops_with_continue(i32 %a32, i32 %b32,
129                                                          i32 %c32) {
130entry:
131  %a = trunc i32 %a32 to i1
132  %b = trunc i32 %b32 to i1
133  %c = trunc i32 %c32 to i1
134  br label %loop0_0
135
136loop0_0:                                   ; <---+
137  br label %loop1_0                        ;     |
138loop1_0:                                   ; <-+ |
139  br label %loop1_1                        ;   | |
140loop1_1:                                   ;   | |
141  br i1 %a, label %loop1_0, label %loop1_2 ; --+ |
142loop1_2:                                   ;   | |
143  br i1 %a, label %loop1_0, label %loop0_1 ; --+ |
144loop0_1:                                   ;     |
145  br i1 %b, label %loop0_0, label %out     ; ----+
146
147out:
148  ret void
149}
150
151; CHECK-LABEL: After loop analysis
152; CHECK-NEXT: entry:
153; CHECK-NEXT: LoopNestDepth = 0
154; CHECK-NEXT: loop0_0:
155; CHECK-NEXT: LoopNestDepth = 1
156; CHECK-NEXT: loop1_0:
157; CHECK-NEXT: LoopNestDepth = 2
158; CHECK-NEXT: loop1_1:
159; CHECK-NEXT: LoopNestDepth = 2
160; CHECK-NEXT: loop1_2:
161; CHECK-NEXT: LoopNestDepth = 2
162; CHECK-NEXT: loop0_1:
163; CHECK-NEXT: LoopNestDepth = 1
164; CHECK-NEXT: out:
165; CHECK-NEXT: LoopNestDepth = 0
166; CHECK-LABEL: Before RMW
167
168define internal void @test_multiple_nested_loops(i32 %a32, i32 %b32) {
169entry:
170  %a = trunc i32 %a32 to i1
171  %b = trunc i32 %b32 to i1
172  br label %loop0_0
173
174loop0_0:                                   ; <---+
175  br label %loop1_0                        ;     |
176loop1_0:                                   ; <-+ |
177  br label %loop1_1                        ;   | |
178loop1_1:                                   ;   | |
179  br i1 %a, label %loop1_0, label %loop0_1 ; --+ |
180loop0_1:                                   ;     |
181  br label %loop2_0                        ;     |
182loop2_0:                                   ; <-+ |
183  br label %loop2_1                        ;   | |
184loop2_1:                                   ;   | |
185  br i1 %a, label %loop2_0, label %loop0_2 ; --+ |
186loop0_2:                                   ;     |
187  br i1 %b, label %loop0_0, label %out     ; ----+
188
189out:
190  ret void
191}
192
193; CHECK-LABEL: After loop analysis
194; CHECK-NEXT: entry:
195; CHECK-NEXT: LoopNestDepth = 0
196; CHECK-NEXT: loop0_0:
197; CHECK-NEXT: LoopNestDepth = 1
198; CHECK-NEXT: loop1_0:
199; CHECK-NEXT: LoopNestDepth = 2
200; CHECK-NEXT: loop1_1:
201; CHECK-NEXT: LoopNestDepth = 2
202; CHECK-NEXT: loop0_1:
203; CHECK-NEXT: LoopNestDepth = 1
204; CHECK-NEXT: loop2_0:
205; CHECK-NEXT: LoopNestDepth = 2
206; CHECK-NEXT: loop2_1:
207; CHECK-NEXT: LoopNestDepth = 2
208; CHECK-NEXT: loop0_2:
209; CHECK-NEXT: LoopNestDepth = 1
210; CHECK-NEXT: out:
211; CHECK-NEXT: LoopNestDepth = 0
212; CHECK-LABEL: Before RMW
213
214define internal void @test_three_nested_loops(i32 %a32, i32 %b32, i32 %c32) {
215entry:
216  %a = trunc i32 %a32 to i1
217  %b = trunc i32 %b32 to i1
218  %c = trunc i32 %c32 to i1
219  br label %loop0_0
220
221loop0_0:                                   ; <-----+
222  br label %loop1_0                        ;       |
223loop1_0:                                   ; <---+ |
224  br label %loop2_0                        ;     | |
225loop2_0:                                   ; <-+ | |
226  br label %loop2_1                        ;   | | |
227loop2_1:                                   ;   | | |
228  br i1 %a, label %loop2_0, label %loop1_1 ; --+ | |
229loop1_1:                                   ;     | |
230  br i1 %b, label %loop1_0, label %loop0_1 ; ----+ |
231loop0_1:                                   ;       |
232  br i1 %c, label %loop0_0, label %out     ; ------+
233
234out:
235  ret void
236}
237
238; CHECK-LABEL: After loop analysis
239; CHECK-NEXT: entry:
240; CHECK-NEXT: LoopNestDepth = 0
241; CHECK-NEXT: loop0_0:
242; CHECK-NEXT: LoopNestDepth = 1
243; CHECK-NEXT: loop1_0:
244; CHECK-NEXT: LoopNestDepth = 2
245; CHECK-NEXT: loop2_0:
246; CHECK-NEXT: LoopNestDepth = 3
247; CHECK-NEXT: loop2_1:
248; CHECK-NEXT: LoopNestDepth = 3
249; CHECK-NEXT: loop1_1:
250; CHECK-NEXT: LoopNestDepth = 2
251; CHECK-NEXT: loop0_1:
252; CHECK-NEXT: LoopNestDepth = 1
253; CHECK-NEXT: out:
254; CHECK-NEXT: LoopNestDepth = 0
255; CHECK-LABEL: Before RMW
256
257define internal void @test_diamond(i32 %a32) {
258entry:
259  %a = trunc i32 %a32 to i1
260  br i1 %a, label %left, label %right
261
262left:
263  br label %out
264
265right:
266  br label %out
267
268out:
269  ret void
270}
271
272; CHECK-LABEL: After loop analysis
273; CHECK-NEXT: entry:
274; CHECK-NEXT: LoopNestDepth = 0
275; CHECK-NEXT: left:
276; CHECK-NEXT: LoopNestDepth = 0
277; CHECK-NEXT: right:
278; CHECK-NEXT: LoopNestDepth = 0
279; CHECK-NEXT: out:
280; CHECK-NEXT: LoopNestDepth = 0
281; CHECK-LABEL: Before RMW
282
283define internal void @test_single_block_loop(i32 %count) {
284entry:
285  br label %body
286body:
287;  %i = phi i32 [ 0, %entry ], [ %inc, %body ]
288; A normal loop would have a phi instruction like above for the induction
289; variable, but that may introduce new basic blocks due to phi edge splitting,
290; so we use an alternative definition for %i to make the test more clear.
291  %i = add i32 %count, 1
292  %inc = add i32 %i, 1
293  %cmp = icmp slt i32 %inc, %count
294  br i1 %cmp, label %body, label %exit
295exit:
296  ret void
297}
298
299; CHECK-LABEL: After loop analysis
300; CHECK-NEXT: entry:
301; CHECK-NEXT: LoopNestDepth = 0
302; CHECK-NEXT: body:
303; CHECK-NEXT: LoopNestDepth = 1
304; CHECK-NEXT: exit:
305; CHECK-NEXT: LoopNestDepth = 0
306; CHECK-LABEL: Before RMW
307