[InstCombine] Signed saturation patterns
[llvm-core.git] / test / Transforms / IRCE / with-parent-loops.ll
blob16c20b1948d38e0c520789037a9ec8d088e90b4f
1 ; RUN: opt -verify-loop-info -irce-print-changed-loops -irce < %s 2>&1 | FileCheck %s
2 ; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require<branch-prob>,loop(irce)' < %s 2>&1 | FileCheck %s
4 ; This test checks if we update the LoopInfo correctly in the presence
5 ; of parents, uncles and cousins.
7 ; Function Attrs: alwaysinline
8 define void @inner_loop(i32* %arr, i32* %a_len_ptr, i32 %n) #0 {
9 ; CHECK: irce: in function inner_loop: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
11 entry:
12   %len = load i32, i32* %a_len_ptr, !range !0
13   %first.itr.check = icmp sgt i32 %n, 0
14   br i1 %first.itr.check, label %loop, label %exit
16 loop:                                             ; preds = %in.bounds, %entry
17   %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]
18   %idx.next = add i32 %idx, 1
19   %abc = icmp slt i32 %idx, %len
20   br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !1
22 in.bounds:                                        ; preds = %loop
23   %addr = getelementptr i32, i32* %arr, i32 %idx
24   store i32 0, i32* %addr
25   %next = icmp slt i32 %idx.next, %n
26   br i1 %next, label %loop, label %exit
28 out.of.bounds:                                    ; preds = %loop
29   ret void
31 exit:                                             ; preds = %in.bounds, %entry
32   ret void
35 ; Function Attrs: alwaysinline
36 define void @with_parent(i32* %arr, i32* %a_len_ptr, i32 %n, i32 %parent.count) #0 {
37 ; CHECK: irce: in function with_parent: constrained Loop at depth 2 containing: %loop.i<header><exiting>,%in.bounds.i<latch><exiting>
39 entry:
40   br label %loop
42 loop:                                             ; preds = %inner_loop.exit, %entry
43   %idx = phi i32 [ 0, %entry ], [ %idx.next, %inner_loop.exit ]
44   %idx.next = add i32 %idx, 1
45   %next = icmp ult i32 %idx.next, %parent.count
46   %len.i = load i32, i32* %a_len_ptr, !range !0
47   %first.itr.check.i = icmp sgt i32 %n, 0
48   br i1 %first.itr.check.i, label %loop.i, label %exit.i
50 loop.i:                                           ; preds = %in.bounds.i, %loop
51   %idx.i = phi i32 [ 0, %loop ], [ %idx.next.i, %in.bounds.i ]
52   %idx.next.i = add i32 %idx.i, 1
53   %abc.i = icmp slt i32 %idx.i, %len.i
54   br i1 %abc.i, label %in.bounds.i, label %out.of.bounds.i, !prof !1
56 in.bounds.i:                                      ; preds = %loop.i
57   %addr.i = getelementptr i32, i32* %arr, i32 %idx.i
58   store i32 0, i32* %addr.i
59   %next.i = icmp slt i32 %idx.next.i, %n
60   br i1 %next.i, label %loop.i, label %exit.i
62 out.of.bounds.i:                                  ; preds = %loop.i
63   br label %inner_loop.exit
65 exit.i:                                           ; preds = %in.bounds.i, %loop
66   br label %inner_loop.exit
68 inner_loop.exit:                                  ; preds = %exit.i, %out.of.bounds.i
69   br i1 %next, label %loop, label %exit
71 exit:                                             ; preds = %inner_loop.exit
72   ret void
75 ; Function Attrs: alwaysinline
76 define void @with_grandparent(i32* %arr, i32* %a_len_ptr, i32 %n, i32 %parent.count, i32 %grandparent.count) #0 {
77 ; CHECK: irce: in function with_grandparent: constrained Loop at depth 3 containing: %loop.i.i<header><exiting>,%in.bounds.i.i<latch><exiting>
79 entry:
80   br label %loop
82 loop:                                             ; preds = %with_parent.exit, %entry
83   %idx = phi i32 [ 0, %entry ], [ %idx.next, %with_parent.exit ]
84   %idx.next = add i32 %idx, 1
85   %next = icmp ult i32 %idx.next, %grandparent.count
86   br label %loop.i
88 loop.i:                                           ; preds = %inner_loop.exit.i, %loop
89   %idx.i = phi i32 [ 0, %loop ], [ %idx.next.i, %inner_loop.exit.i ]
90   %idx.next.i = add i32 %idx.i, 1
91   %next.i = icmp ult i32 %idx.next.i, %parent.count
92   %len.i.i = load i32, i32* %a_len_ptr, !range !0
93   %first.itr.check.i.i = icmp sgt i32 %n, 0
94   br i1 %first.itr.check.i.i, label %loop.i.i, label %exit.i.i
96 loop.i.i:                                         ; preds = %in.bounds.i.i, %loop.i
97   %idx.i.i = phi i32 [ 0, %loop.i ], [ %idx.next.i.i, %in.bounds.i.i ]
98   %idx.next.i.i = add i32 %idx.i.i, 1
99   %abc.i.i = icmp slt i32 %idx.i.i, %len.i.i
100   br i1 %abc.i.i, label %in.bounds.i.i, label %out.of.bounds.i.i, !prof !1
102 in.bounds.i.i:                                    ; preds = %loop.i.i
103   %addr.i.i = getelementptr i32, i32* %arr, i32 %idx.i.i
104   store i32 0, i32* %addr.i.i
105   %next.i.i = icmp slt i32 %idx.next.i.i, %n
106   br i1 %next.i.i, label %loop.i.i, label %exit.i.i
108 out.of.bounds.i.i:                                ; preds = %loop.i.i
109   br label %inner_loop.exit.i
111 exit.i.i:                                         ; preds = %in.bounds.i.i, %loop.i
112   br label %inner_loop.exit.i
114 inner_loop.exit.i:                                ; preds = %exit.i.i, %out.of.bounds.i.i
115   br i1 %next.i, label %loop.i, label %with_parent.exit
117 with_parent.exit:                                 ; preds = %inner_loop.exit.i
118   br i1 %next, label %loop, label %exit
120 exit:                                             ; preds = %with_parent.exit
121   ret void
124 ; Function Attrs: alwaysinline
125 define void @with_sibling(i32* %arr, i32* %a_len_ptr, i32 %n, i32 %parent.count) #0 {
126 ; CHECK: irce: in function with_sibling: constrained Loop at depth 2 containing: %loop.i<header><exiting>,%in.bounds.i<latch><exiting>
127 ; CHECK: irce: in function with_sibling: constrained Loop at depth 2 containing: %loop.i6<header><exiting>,%in.bounds.i9<latch><exiting>
129 entry:
130   br label %loop
132 loop:                                             ; preds = %inner_loop.exit12, %entry
133   %idx = phi i32 [ 0, %entry ], [ %idx.next, %inner_loop.exit12 ]
134   %idx.next = add i32 %idx, 1
135   %next = icmp ult i32 %idx.next, %parent.count
136   %len.i = load i32, i32* %a_len_ptr, !range !0
137   %first.itr.check.i = icmp sgt i32 %n, 0
138   br i1 %first.itr.check.i, label %loop.i, label %exit.i
140 loop.i:                                           ; preds = %in.bounds.i, %loop
141   %idx.i = phi i32 [ 0, %loop ], [ %idx.next.i, %in.bounds.i ]
142   %idx.next.i = add i32 %idx.i, 1
143   %abc.i = icmp slt i32 %idx.i, %len.i
144   br i1 %abc.i, label %in.bounds.i, label %out.of.bounds.i, !prof !1
146 in.bounds.i:                                      ; preds = %loop.i
147   %addr.i = getelementptr i32, i32* %arr, i32 %idx.i
148   store i32 0, i32* %addr.i
149   %next.i = icmp slt i32 %idx.next.i, %n
150   br i1 %next.i, label %loop.i, label %exit.i
152 out.of.bounds.i:                                  ; preds = %loop.i
153   br label %inner_loop.exit
155 exit.i:                                           ; preds = %in.bounds.i, %loop
156   br label %inner_loop.exit
158 inner_loop.exit:                                  ; preds = %exit.i, %out.of.bounds.i
159   %len.i1 = load i32, i32* %a_len_ptr, !range !0
160   %first.itr.check.i2 = icmp sgt i32 %n, 0
161   br i1 %first.itr.check.i2, label %loop.i6, label %exit.i11
163 loop.i6:                                          ; preds = %in.bounds.i9, %inner_loop.exit
164   %idx.i3 = phi i32 [ 0, %inner_loop.exit ], [ %idx.next.i4, %in.bounds.i9 ]
165   %idx.next.i4 = add i32 %idx.i3, 1
166   %abc.i5 = icmp slt i32 %idx.i3, %len.i1
167   br i1 %abc.i5, label %in.bounds.i9, label %out.of.bounds.i10, !prof !1
169 in.bounds.i9:                                     ; preds = %loop.i6
170   %addr.i7 = getelementptr i32, i32* %arr, i32 %idx.i3
171   store i32 0, i32* %addr.i7
172   %next.i8 = icmp slt i32 %idx.next.i4, %n
173   br i1 %next.i8, label %loop.i6, label %exit.i11
175 out.of.bounds.i10:                                ; preds = %loop.i6
176   br label %inner_loop.exit12
178 exit.i11:                                         ; preds = %in.bounds.i9, %inner_loop.exit
179   br label %inner_loop.exit12
181 inner_loop.exit12:                                ; preds = %exit.i11, %out.of.bounds.i10
182   br i1 %next, label %loop, label %exit
184 exit:                                             ; preds = %inner_loop.exit12
185   ret void
188 ; Function Attrs: alwaysinline
189 define void @with_cousin(i32* %arr, i32* %a_len_ptr, i32 %n, i32 %parent.count, i32 %grandparent.count) #0 {
190 ; CHECK: irce: in function with_cousin: constrained Loop at depth 3 containing: %loop.i.i<header><exiting>,%in.bounds.i.i<latch><exiting>
191 ; CHECK: irce: in function with_cousin: constrained Loop at depth 3 containing: %loop.i.i10<header><exiting>,%in.bounds.i.i13<latch><exiting>
193 entry:
194   br label %loop
196 loop:                                             ; preds = %with_parent.exit17, %entry
197   %idx = phi i32 [ 0, %entry ], [ %idx.next, %with_parent.exit17 ]
198   %idx.next = add i32 %idx, 1
199   %next = icmp ult i32 %idx.next, %grandparent.count
200   br label %loop.i
202 loop.i:                                           ; preds = %inner_loop.exit.i, %loop
203   %idx.i = phi i32 [ 0, %loop ], [ %idx.next.i, %inner_loop.exit.i ]
204   %idx.next.i = add i32 %idx.i, 1
205   %next.i = icmp ult i32 %idx.next.i, %parent.count
206   %len.i.i = load i32, i32* %a_len_ptr, !range !0
207   %first.itr.check.i.i = icmp sgt i32 %n, 0
208   br i1 %first.itr.check.i.i, label %loop.i.i, label %exit.i.i
210 loop.i.i:                                         ; preds = %in.bounds.i.i, %loop.i
211   %idx.i.i = phi i32 [ 0, %loop.i ], [ %idx.next.i.i, %in.bounds.i.i ]
212   %idx.next.i.i = add i32 %idx.i.i, 1
213   %abc.i.i = icmp slt i32 %idx.i.i, %len.i.i
214   br i1 %abc.i.i, label %in.bounds.i.i, label %out.of.bounds.i.i, !prof !1
216 in.bounds.i.i:                                    ; preds = %loop.i.i
217   %addr.i.i = getelementptr i32, i32* %arr, i32 %idx.i.i
218   store i32 0, i32* %addr.i.i
219   %next.i.i = icmp slt i32 %idx.next.i.i, %n
220   br i1 %next.i.i, label %loop.i.i, label %exit.i.i
222 out.of.bounds.i.i:                                ; preds = %loop.i.i
223   br label %inner_loop.exit.i
225 exit.i.i:                                         ; preds = %in.bounds.i.i, %loop.i
226   br label %inner_loop.exit.i
228 inner_loop.exit.i:                                ; preds = %exit.i.i, %out.of.bounds.i.i
229   br i1 %next.i, label %loop.i, label %with_parent.exit
231 with_parent.exit:                                 ; preds = %inner_loop.exit.i
232   br label %loop.i6
234 loop.i6:                                          ; preds = %inner_loop.exit.i16, %with_parent.exit
235   %idx.i1 = phi i32 [ 0, %with_parent.exit ], [ %idx.next.i2, %inner_loop.exit.i16 ]
236   %idx.next.i2 = add i32 %idx.i1, 1
237   %next.i3 = icmp ult i32 %idx.next.i2, %parent.count
238   %len.i.i4 = load i32, i32* %a_len_ptr, !range !0
239   %first.itr.check.i.i5 = icmp sgt i32 %n, 0
240   br i1 %first.itr.check.i.i5, label %loop.i.i10, label %exit.i.i15
242 loop.i.i10:                                       ; preds = %in.bounds.i.i13, %loop.i6
243   %idx.i.i7 = phi i32 [ 0, %loop.i6 ], [ %idx.next.i.i8, %in.bounds.i.i13 ]
244   %idx.next.i.i8 = add i32 %idx.i.i7, 1
245   %abc.i.i9 = icmp slt i32 %idx.i.i7, %len.i.i4
246   br i1 %abc.i.i9, label %in.bounds.i.i13, label %out.of.bounds.i.i14, !prof !1
248 in.bounds.i.i13:                                  ; preds = %loop.i.i10
249   %addr.i.i11 = getelementptr i32, i32* %arr, i32 %idx.i.i7
250   store i32 0, i32* %addr.i.i11
251   %next.i.i12 = icmp slt i32 %idx.next.i.i8, %n
252   br i1 %next.i.i12, label %loop.i.i10, label %exit.i.i15
254 out.of.bounds.i.i14:                              ; preds = %loop.i.i10
255   br label %inner_loop.exit.i16
257 exit.i.i15:                                       ; preds = %in.bounds.i.i13, %loop.i6
258   br label %inner_loop.exit.i16
260 inner_loop.exit.i16:                              ; preds = %exit.i.i15, %out.of.bounds.i.i14
261   br i1 %next.i3, label %loop.i6, label %with_parent.exit17
263 with_parent.exit17:                               ; preds = %inner_loop.exit.i16
264   br i1 %next, label %loop, label %exit
266 exit:                                             ; preds = %with_parent.exit17
267   ret void
270 ; Function Attrs: alwaysinline
271 define void @with_uncle(i32* %arr, i32* %a_len_ptr, i32 %n, i32 %parent.count, i32 %grandparent.count) #0 {
272 ; CHECK: irce: in function with_uncle: constrained Loop at depth 2 containing: %loop.i<header><exiting>,%in.bounds.i<latch><exiting>
273 ; CHECK: irce: in function with_uncle: constrained Loop at depth 3 containing: %loop.i.i<header><exiting>,%in.bounds.i.i<latch><exiting>
275 entry:
276   br label %loop
278 loop:                                             ; preds = %with_parent.exit, %entry
279   %idx = phi i32 [ 0, %entry ], [ %idx.next, %with_parent.exit ]
280   %idx.next = add i32 %idx, 1
281   %next = icmp ult i32 %idx.next, %grandparent.count
282   %len.i = load i32, i32* %a_len_ptr, !range !0
283   %first.itr.check.i = icmp sgt i32 %n, 0
284   br i1 %first.itr.check.i, label %loop.i, label %exit.i
286 loop.i:                                           ; preds = %in.bounds.i, %loop
287   %idx.i = phi i32 [ 0, %loop ], [ %idx.next.i, %in.bounds.i ]
288   %idx.next.i = add i32 %idx.i, 1
289   %abc.i = icmp slt i32 %idx.i, %len.i
290   br i1 %abc.i, label %in.bounds.i, label %out.of.bounds.i, !prof !1
292 in.bounds.i:                                      ; preds = %loop.i
293   %addr.i = getelementptr i32, i32* %arr, i32 %idx.i
294   store i32 0, i32* %addr.i
295   %next.i = icmp slt i32 %idx.next.i, %n
296   br i1 %next.i, label %loop.i, label %exit.i
298 out.of.bounds.i:                                  ; preds = %loop.i
299   br label %inner_loop.exit
301 exit.i:                                           ; preds = %in.bounds.i, %loop
302   br label %inner_loop.exit
304 inner_loop.exit:                                  ; preds = %exit.i, %out.of.bounds.i
305   br label %loop.i4
307 loop.i4:                                          ; preds = %inner_loop.exit.i, %inner_loop.exit
308   %idx.i1 = phi i32 [ 0, %inner_loop.exit ], [ %idx.next.i2, %inner_loop.exit.i ]
309   %idx.next.i2 = add i32 %idx.i1, 1
310   %next.i3 = icmp ult i32 %idx.next.i2, %parent.count
311   %len.i.i = load i32, i32* %a_len_ptr, !range !0
312   %first.itr.check.i.i = icmp sgt i32 %n, 0
313   br i1 %first.itr.check.i.i, label %loop.i.i, label %exit.i.i
315 loop.i.i:                                         ; preds = %in.bounds.i.i, %loop.i4
316   %idx.i.i = phi i32 [ 0, %loop.i4 ], [ %idx.next.i.i, %in.bounds.i.i ]
317   %idx.next.i.i = add i32 %idx.i.i, 1
318   %abc.i.i = icmp slt i32 %idx.i.i, %len.i.i
319   br i1 %abc.i.i, label %in.bounds.i.i, label %out.of.bounds.i.i, !prof !1
321 in.bounds.i.i:                                    ; preds = %loop.i.i
322   %addr.i.i = getelementptr i32, i32* %arr, i32 %idx.i.i
323   store i32 0, i32* %addr.i.i
324   %next.i.i = icmp slt i32 %idx.next.i.i, %n
325   br i1 %next.i.i, label %loop.i.i, label %exit.i.i
327 out.of.bounds.i.i:                                ; preds = %loop.i.i
328   br label %inner_loop.exit.i
330 exit.i.i:                                         ; preds = %in.bounds.i.i, %loop.i4
331   br label %inner_loop.exit.i
333 inner_loop.exit.i:                                ; preds = %exit.i.i, %out.of.bounds.i.i
334   br i1 %next.i3, label %loop.i4, label %with_parent.exit
336 with_parent.exit:                                 ; preds = %inner_loop.exit.i
337   br i1 %next, label %loop, label %exit
339 exit:                                             ; preds = %with_parent.exit
340   ret void
343 attributes #0 = { alwaysinline }
345 !0 = !{i32 0, i32 2147483647}
346 !1 = !{!"branch_weights", i32 64, i32 4}