[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Transforms / LoopBoundSplit / loop-bound-split.ll
blob1ad93f550e13df3d7ad3a4053fbeeaa4dc76fc18
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt  -passes=loop-bound-split -S < %s | FileCheck %s
4 define void @split_loop_bound_inc_with_sgt(i64 %a, i64* noalias %src, i64* noalias %dst, i64 %n) {
5 ; CHECK-LABEL: @split_loop_bound_inc_with_sgt(
6 ; CHECK-NEXT:  loop.ph:
7 ; CHECK-NEXT:    br label [[LOOP_PH_SPLIT:%.*]]
8 ; CHECK:       loop.ph.split:
9 ; CHECK-NEXT:    [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[N:%.*]], i64 0)
10 ; CHECK-NEXT:    [[NEW_BOUND:%.*]] = call i64 @llvm.smin.i64(i64 [[A:%.*]], i64 [[SMAX]])
11 ; CHECK-NEXT:    br label [[LOOP:%.*]]
12 ; CHECK:       loop:
13 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[LOOP_PH_SPLIT]] ]
14 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i64 [[IV]], [[A]]
15 ; CHECK-NEXT:    br i1 true, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
16 ; CHECK:       if.then:
17 ; CHECK-NEXT:    [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, i64* [[SRC:%.*]], i64 [[IV]]
18 ; CHECK-NEXT:    [[VAL:%.*]] = load i64, i64* [[SRC_ARRAYIDX]], align 4
19 ; CHECK-NEXT:    [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, i64* [[DST:%.*]], i64 [[IV]]
20 ; CHECK-NEXT:    store i64 [[VAL]], i64* [[DST_ARRAYIDX]], align 4
21 ; CHECK-NEXT:    br label [[FOR_INC]]
22 ; CHECK:       if.else:
23 ; CHECK-NEXT:    br label [[FOR_INC]]
24 ; CHECK:       for.inc:
25 ; CHECK-NEXT:    [[INC]] = add nuw nsw i64 [[IV]], 1
26 ; CHECK-NEXT:    [[COND:%.*]] = icmp sgt i64 [[INC]], [[NEW_BOUND]]
27 ; CHECK-NEXT:    br i1 [[COND]], label [[LOOP_PH_SPLIT_SPLIT:%.*]], label [[LOOP]]
28 ; CHECK:       loop.ph.split.split:
29 ; CHECK-NEXT:    [[INC_LCSSA:%.*]] = phi i64 [ [[INC]], [[FOR_INC]] ]
30 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp ne i64 [[INC_LCSSA]], [[N]]
31 ; CHECK-NEXT:    br i1 [[TMP0]], label [[LOOP_SPLIT_PREHEADER:%.*]], label [[EXIT:%.*]]
32 ; CHECK:       loop.split.preheader:
33 ; CHECK-NEXT:    br label [[LOOP_SPLIT:%.*]]
34 ; CHECK:       loop.split:
35 ; CHECK-NEXT:    [[IV_SPLIT:%.*]] = phi i64 [ [[INC_SPLIT:%.*]], [[FOR_INC_SPLIT:%.*]] ], [ [[NEW_BOUND]], [[LOOP_SPLIT_PREHEADER]] ]
36 ; CHECK-NEXT:    [[CMP_SPLIT:%.*]] = icmp slt i64 [[IV_SPLIT]], [[A]]
37 ; CHECK-NEXT:    br i1 false, label [[IF_THEN_SPLIT:%.*]], label [[IF_ELSE_SPLIT:%.*]]
38 ; CHECK:       if.else.split:
39 ; CHECK-NEXT:    br label [[FOR_INC_SPLIT]]
40 ; CHECK:       if.then.split:
41 ; CHECK-NEXT:    [[SRC_ARRAYIDX_SPLIT:%.*]] = getelementptr inbounds i64, i64* [[SRC]], i64 [[IV_SPLIT]]
42 ; CHECK-NEXT:    [[VAL_SPLIT:%.*]] = load i64, i64* [[SRC_ARRAYIDX_SPLIT]], align 4
43 ; CHECK-NEXT:    [[DST_ARRAYIDX_SPLIT:%.*]] = getelementptr inbounds i64, i64* [[DST]], i64 [[IV_SPLIT]]
44 ; CHECK-NEXT:    store i64 [[VAL_SPLIT]], i64* [[DST_ARRAYIDX_SPLIT]], align 4
45 ; CHECK-NEXT:    br label [[FOR_INC_SPLIT]]
46 ; CHECK:       for.inc.split:
47 ; CHECK-NEXT:    [[INC_SPLIT]] = add nuw nsw i64 [[IV_SPLIT]], 1
48 ; CHECK-NEXT:    [[COND_SPLIT:%.*]] = icmp sgt i64 [[INC_SPLIT]], [[N]]
49 ; CHECK-NEXT:    br i1 [[COND_SPLIT]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP_SPLIT]]
50 ; CHECK:       exit.loopexit:
51 ; CHECK-NEXT:    br label [[EXIT]]
52 ; CHECK:       exit:
53 ; CHECK-NEXT:    ret void
55 loop.ph:
56   br label %loop
58 loop:
59   %iv = phi i64 [ %inc, %for.inc ], [ 0, %loop.ph ]
60   %cmp = icmp slt i64 %iv, %a
61   br i1 %cmp, label %if.then, label %if.else
63 if.then:
64   %src.arrayidx = getelementptr inbounds i64, i64* %src, i64 %iv
65   %val = load i64, i64* %src.arrayidx
66   %dst.arrayidx = getelementptr inbounds i64, i64* %dst, i64 %iv
67   store i64 %val, i64* %dst.arrayidx
68   br label %for.inc
70 if.else:
71   br label %for.inc
73 for.inc:
74   %inc = add nuw nsw i64 %iv, 1
75   %cond = icmp sgt i64 %inc, %n
76   br i1 %cond, label %exit, label %loop
78 exit:
79   ret void
82 define void @split_loop_bound_inc_with_eq(i64 %a, i64* noalias %src, i64* noalias %dst, i64 %n) {
83 ; CHECK-LABEL: @split_loop_bound_inc_with_eq(
84 ; CHECK-NEXT:  loop.ph:
85 ; CHECK-NEXT:    br label [[LOOP_PH_SPLIT:%.*]]
86 ; CHECK:       loop.ph.split:
87 ; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[N:%.*]], -1
88 ; CHECK-NEXT:    [[NEW_BOUND:%.*]] = call i64 @llvm.umin.i64(i64 [[A:%.*]], i64 [[TMP0]])
89 ; CHECK-NEXT:    br label [[LOOP:%.*]]
90 ; CHECK:       loop:
91 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[LOOP_PH_SPLIT]] ]
92 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i64 [[IV]], [[A]]
93 ; CHECK-NEXT:    br i1 true, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
94 ; CHECK:       if.then:
95 ; CHECK-NEXT:    [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, i64* [[SRC:%.*]], i64 [[IV]]
96 ; CHECK-NEXT:    [[VAL:%.*]] = load i64, i64* [[SRC_ARRAYIDX]], align 4
97 ; CHECK-NEXT:    [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, i64* [[DST:%.*]], i64 [[IV]]
98 ; CHECK-NEXT:    store i64 [[VAL]], i64* [[DST_ARRAYIDX]], align 4
99 ; CHECK-NEXT:    br label [[FOR_INC]]
100 ; CHECK:       if.else:
101 ; CHECK-NEXT:    br label [[FOR_INC]]
102 ; CHECK:       for.inc:
103 ; CHECK-NEXT:    [[INC]] = add nuw nsw i64 [[IV]], 1
104 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INC]], [[NEW_BOUND]]
105 ; CHECK-NEXT:    br i1 [[COND]], label [[LOOP_PH_SPLIT_SPLIT:%.*]], label [[LOOP]]
106 ; CHECK:       loop.ph.split.split:
107 ; CHECK-NEXT:    [[INC_LCSSA:%.*]] = phi i64 [ [[INC]], [[FOR_INC]] ]
108 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i64 [[INC_LCSSA]], [[N]]
109 ; CHECK-NEXT:    br i1 [[TMP1]], label [[LOOP_SPLIT_PREHEADER:%.*]], label [[EXIT:%.*]]
110 ; CHECK:       loop.split.preheader:
111 ; CHECK-NEXT:    br label [[LOOP_SPLIT:%.*]]
112 ; CHECK:       loop.split:
113 ; CHECK-NEXT:    [[IV_SPLIT:%.*]] = phi i64 [ [[INC_SPLIT:%.*]], [[FOR_INC_SPLIT:%.*]] ], [ [[NEW_BOUND]], [[LOOP_SPLIT_PREHEADER]] ]
114 ; CHECK-NEXT:    [[CMP_SPLIT:%.*]] = icmp slt i64 [[IV_SPLIT]], [[A]]
115 ; CHECK-NEXT:    br i1 false, label [[IF_THEN_SPLIT:%.*]], label [[IF_ELSE_SPLIT:%.*]]
116 ; CHECK:       if.else.split:
117 ; CHECK-NEXT:    br label [[FOR_INC_SPLIT]]
118 ; CHECK:       if.then.split:
119 ; CHECK-NEXT:    [[SRC_ARRAYIDX_SPLIT:%.*]] = getelementptr inbounds i64, i64* [[SRC]], i64 [[IV_SPLIT]]
120 ; CHECK-NEXT:    [[VAL_SPLIT:%.*]] = load i64, i64* [[SRC_ARRAYIDX_SPLIT]], align 4
121 ; CHECK-NEXT:    [[DST_ARRAYIDX_SPLIT:%.*]] = getelementptr inbounds i64, i64* [[DST]], i64 [[IV_SPLIT]]
122 ; CHECK-NEXT:    store i64 [[VAL_SPLIT]], i64* [[DST_ARRAYIDX_SPLIT]], align 4
123 ; CHECK-NEXT:    br label [[FOR_INC_SPLIT]]
124 ; CHECK:       for.inc.split:
125 ; CHECK-NEXT:    [[INC_SPLIT]] = add nuw nsw i64 [[IV_SPLIT]], 1
126 ; CHECK-NEXT:    [[COND_SPLIT:%.*]] = icmp eq i64 [[INC_SPLIT]], [[N]]
127 ; CHECK-NEXT:    br i1 [[COND_SPLIT]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP_SPLIT]]
128 ; CHECK:       exit.loopexit:
129 ; CHECK-NEXT:    br label [[EXIT]]
130 ; CHECK:       exit:
131 ; CHECK-NEXT:    ret void
133 loop.ph:
134   br label %loop
136 loop:
137   %iv = phi i64 [ %inc, %for.inc ], [ 0, %loop.ph ]
138   %cmp = icmp slt i64 %iv, %a
139   br i1 %cmp, label %if.then, label %if.else
141 if.then:
142   %src.arrayidx = getelementptr inbounds i64, i64* %src, i64 %iv
143   %val = load i64, i64* %src.arrayidx
144   %dst.arrayidx = getelementptr inbounds i64, i64* %dst, i64 %iv
145   store i64 %val, i64* %dst.arrayidx
146   br label %for.inc
148 if.else:
149   br label %for.inc
151 for.inc:
152   %inc = add nuw nsw i64 %iv, 1
153   %cond = icmp eq i64 %inc, %n
154   br i1 %cond, label %exit, label %loop
156 exit:
157   ret void
160 define void @split_loop_bound_inc_with_sge(i64 %a, i64* noalias %src, i64* noalias %dst, i64 %n) {
161 ; CHECK-LABEL: @split_loop_bound_inc_with_sge(
162 ; CHECK-NEXT:  loop.ph:
163 ; CHECK-NEXT:    br label [[LOOP_PH_SPLIT:%.*]]
164 ; CHECK:       loop.ph.split:
165 ; CHECK-NEXT:    [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[N:%.*]], i64 1)
166 ; CHECK-NEXT:    [[TMP0:%.*]] = add nsw i64 [[SMAX]], -1
167 ; CHECK-NEXT:    [[NEW_BOUND:%.*]] = call i64 @llvm.smin.i64(i64 [[A:%.*]], i64 [[TMP0]])
168 ; CHECK-NEXT:    br label [[LOOP:%.*]]
169 ; CHECK:       loop:
170 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[LOOP_PH_SPLIT]] ]
171 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i64 [[IV]], [[A]]
172 ; CHECK-NEXT:    br i1 true, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
173 ; CHECK:       if.then:
174 ; CHECK-NEXT:    [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, i64* [[SRC:%.*]], i64 [[IV]]
175 ; CHECK-NEXT:    [[VAL:%.*]] = load i64, i64* [[SRC_ARRAYIDX]], align 4
176 ; CHECK-NEXT:    [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, i64* [[DST:%.*]], i64 [[IV]]
177 ; CHECK-NEXT:    store i64 [[VAL]], i64* [[DST_ARRAYIDX]], align 4
178 ; CHECK-NEXT:    br label [[FOR_INC]]
179 ; CHECK:       if.else:
180 ; CHECK-NEXT:    br label [[FOR_INC]]
181 ; CHECK:       for.inc:
182 ; CHECK-NEXT:    [[INC]] = add nuw nsw i64 [[IV]], 1
183 ; CHECK-NEXT:    [[COND:%.*]] = icmp sge i64 [[INC]], [[NEW_BOUND]]
184 ; CHECK-NEXT:    br i1 [[COND]], label [[LOOP_PH_SPLIT_SPLIT:%.*]], label [[LOOP]]
185 ; CHECK:       loop.ph.split.split:
186 ; CHECK-NEXT:    [[INC_LCSSA:%.*]] = phi i64 [ [[INC]], [[FOR_INC]] ]
187 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i64 [[INC_LCSSA]], [[N]]
188 ; CHECK-NEXT:    br i1 [[TMP1]], label [[LOOP_SPLIT_PREHEADER:%.*]], label [[EXIT:%.*]]
189 ; CHECK:       loop.split.preheader:
190 ; CHECK-NEXT:    br label [[LOOP_SPLIT:%.*]]
191 ; CHECK:       loop.split:
192 ; CHECK-NEXT:    [[IV_SPLIT:%.*]] = phi i64 [ [[INC_SPLIT:%.*]], [[FOR_INC_SPLIT:%.*]] ], [ [[NEW_BOUND]], [[LOOP_SPLIT_PREHEADER]] ]
193 ; CHECK-NEXT:    [[CMP_SPLIT:%.*]] = icmp slt i64 [[IV_SPLIT]], [[A]]
194 ; CHECK-NEXT:    br i1 false, label [[IF_THEN_SPLIT:%.*]], label [[IF_ELSE_SPLIT:%.*]]
195 ; CHECK:       if.else.split:
196 ; CHECK-NEXT:    br label [[FOR_INC_SPLIT]]
197 ; CHECK:       if.then.split:
198 ; CHECK-NEXT:    [[SRC_ARRAYIDX_SPLIT:%.*]] = getelementptr inbounds i64, i64* [[SRC]], i64 [[IV_SPLIT]]
199 ; CHECK-NEXT:    [[VAL_SPLIT:%.*]] = load i64, i64* [[SRC_ARRAYIDX_SPLIT]], align 4
200 ; CHECK-NEXT:    [[DST_ARRAYIDX_SPLIT:%.*]] = getelementptr inbounds i64, i64* [[DST]], i64 [[IV_SPLIT]]
201 ; CHECK-NEXT:    store i64 [[VAL_SPLIT]], i64* [[DST_ARRAYIDX_SPLIT]], align 4
202 ; CHECK-NEXT:    br label [[FOR_INC_SPLIT]]
203 ; CHECK:       for.inc.split:
204 ; CHECK-NEXT:    [[INC_SPLIT]] = add nuw nsw i64 [[IV_SPLIT]], 1
205 ; CHECK-NEXT:    [[COND_SPLIT:%.*]] = icmp sge i64 [[INC_SPLIT]], [[N]]
206 ; CHECK-NEXT:    br i1 [[COND_SPLIT]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP_SPLIT]]
207 ; CHECK:       exit.loopexit:
208 ; CHECK-NEXT:    br label [[EXIT]]
209 ; CHECK:       exit:
210 ; CHECK-NEXT:    ret void
212 loop.ph:
213   br label %loop
215 loop:
216   %iv = phi i64 [ %inc, %for.inc ], [ 0, %loop.ph ]
217   %cmp = icmp slt i64 %iv, %a
218   br i1 %cmp, label %if.then, label %if.else
220 if.then:
221   %src.arrayidx = getelementptr inbounds i64, i64* %src, i64 %iv
222   %val = load i64, i64* %src.arrayidx
223   %dst.arrayidx = getelementptr inbounds i64, i64* %dst, i64 %iv
224   store i64 %val, i64* %dst.arrayidx
225   br label %for.inc
227 if.else:
228   br label %for.inc
230 for.inc:
231   %inc = add nuw nsw i64 %iv, 1
232   %cond = icmp sge i64 %inc, %n
233   br i1 %cond, label %exit, label %loop
235 exit:
236   ret void
239 define void @split_loop_bound_inc_with_step_is_not_one(i64 %a, i64* noalias %src, i64* noalias %dst, i64 %n) {
240 ; CHECK-LABEL: @split_loop_bound_inc_with_step_is_not_one(
241 ; CHECK-NEXT:  loop.ph:
242 ; CHECK-NEXT:    br label [[LOOP_PH_SPLIT:%.*]]
243 ; CHECK:       loop.ph.split:
244 ; CHECK-NEXT:    [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[N:%.*]], i64 1)
245 ; CHECK-NEXT:    [[TMP0:%.*]] = lshr i64 [[SMAX]], 1
246 ; CHECK-NEXT:    [[NEW_BOUND:%.*]] = call i64 @llvm.smin.i64(i64 [[A:%.*]], i64 [[TMP0]])
247 ; CHECK-NEXT:    br label [[LOOP:%.*]]
248 ; CHECK:       loop:
249 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[LOOP_PH_SPLIT]] ]
250 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i64 [[IV]], [[A]]
251 ; CHECK-NEXT:    br i1 true, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
252 ; CHECK:       if.then:
253 ; CHECK-NEXT:    [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, i64* [[SRC:%.*]], i64 [[IV]]
254 ; CHECK-NEXT:    [[VAL:%.*]] = load i64, i64* [[SRC_ARRAYIDX]], align 4
255 ; CHECK-NEXT:    [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, i64* [[DST:%.*]], i64 [[IV]]
256 ; CHECK-NEXT:    store i64 [[VAL]], i64* [[DST_ARRAYIDX]], align 4
257 ; CHECK-NEXT:    br label [[FOR_INC]]
258 ; CHECK:       if.else:
259 ; CHECK-NEXT:    br label [[FOR_INC]]
260 ; CHECK:       for.inc:
261 ; CHECK-NEXT:    [[INC]] = add nuw nsw i64 [[IV]], 2
262 ; CHECK-NEXT:    [[COND:%.*]] = icmp sgt i64 [[INC]], [[NEW_BOUND]]
263 ; CHECK-NEXT:    br i1 [[COND]], label [[LOOP_PH_SPLIT_SPLIT:%.*]], label [[LOOP]]
264 ; CHECK:       loop.ph.split.split:
265 ; CHECK-NEXT:    [[INC_LCSSA:%.*]] = phi i64 [ [[INC]], [[FOR_INC]] ]
266 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i64 [[INC_LCSSA]], [[N]]
267 ; CHECK-NEXT:    br i1 [[TMP1]], label [[LOOP_SPLIT_PREHEADER:%.*]], label [[EXIT:%.*]]
268 ; CHECK:       loop.split.preheader:
269 ; CHECK-NEXT:    br label [[LOOP_SPLIT:%.*]]
270 ; CHECK:       loop.split:
271 ; CHECK-NEXT:    [[IV_SPLIT:%.*]] = phi i64 [ [[INC_SPLIT:%.*]], [[FOR_INC_SPLIT:%.*]] ], [ [[NEW_BOUND]], [[LOOP_SPLIT_PREHEADER]] ]
272 ; CHECK-NEXT:    [[CMP_SPLIT:%.*]] = icmp slt i64 [[IV_SPLIT]], [[A]]
273 ; CHECK-NEXT:    br i1 false, label [[IF_THEN_SPLIT:%.*]], label [[IF_ELSE_SPLIT:%.*]]
274 ; CHECK:       if.else.split:
275 ; CHECK-NEXT:    br label [[FOR_INC_SPLIT]]
276 ; CHECK:       if.then.split:
277 ; CHECK-NEXT:    [[SRC_ARRAYIDX_SPLIT:%.*]] = getelementptr inbounds i64, i64* [[SRC]], i64 [[IV_SPLIT]]
278 ; CHECK-NEXT:    [[VAL_SPLIT:%.*]] = load i64, i64* [[SRC_ARRAYIDX_SPLIT]], align 4
279 ; CHECK-NEXT:    [[DST_ARRAYIDX_SPLIT:%.*]] = getelementptr inbounds i64, i64* [[DST]], i64 [[IV_SPLIT]]
280 ; CHECK-NEXT:    store i64 [[VAL_SPLIT]], i64* [[DST_ARRAYIDX_SPLIT]], align 4
281 ; CHECK-NEXT:    br label [[FOR_INC_SPLIT]]
282 ; CHECK:       for.inc.split:
283 ; CHECK-NEXT:    [[INC_SPLIT]] = add nuw nsw i64 [[IV_SPLIT]], 2
284 ; CHECK-NEXT:    [[COND_SPLIT:%.*]] = icmp sgt i64 [[INC_SPLIT]], [[N]]
285 ; CHECK-NEXT:    br i1 [[COND_SPLIT]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP_SPLIT]]
286 ; CHECK:       exit.loopexit:
287 ; CHECK-NEXT:    br label [[EXIT]]
288 ; CHECK:       exit:
289 ; CHECK-NEXT:    ret void
291 loop.ph:
292   br label %loop
294 loop:
295   %iv = phi i64 [ %inc, %for.inc ], [ 0, %loop.ph ]
296   %cmp = icmp slt i64 %iv, %a
297   br i1 %cmp, label %if.then, label %if.else
299 if.then:
300   %src.arrayidx = getelementptr inbounds i64, i64* %src, i64 %iv
301   %val = load i64, i64* %src.arrayidx
302   %dst.arrayidx = getelementptr inbounds i64, i64* %dst, i64 %iv
303   store i64 %val, i64* %dst.arrayidx
304   br label %for.inc
306 if.else:
307   br label %for.inc
309 for.inc:
310   %inc = add nuw nsw i64 %iv, 2
311   %cond = icmp sgt i64 %inc, %n
312   br i1 %cond, label %exit, label %loop
314 exit:
315   ret void
318 define void @split_loop_bound_inc_with_ne(i64 %a, i64* noalias %src, i64* noalias %dst, i64 %n) {
319 ; CHECK-LABEL: @split_loop_bound_inc_with_ne(
320 ; CHECK-NEXT:  loop.ph:
321 ; CHECK-NEXT:    br label [[LOOP:%.*]]
322 ; CHECK:       loop:
323 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[LOOP_PH:%.*]] ]
324 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i64 [[IV]], [[A:%.*]]
325 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[FOR_INC]]
326 ; CHECK:       if.then:
327 ; CHECK-NEXT:    [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, i64* [[SRC:%.*]], i64 [[IV]]
328 ; CHECK-NEXT:    [[VAL:%.*]] = load i64, i64* [[SRC_ARRAYIDX]], align 4
329 ; CHECK-NEXT:    [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, i64* [[DST:%.*]], i64 [[IV]]
330 ; CHECK-NEXT:    store i64 [[VAL]], i64* [[DST_ARRAYIDX]], align 4
331 ; CHECK-NEXT:    br label [[FOR_INC]]
332 ; CHECK:       for.inc:
333 ; CHECK-NEXT:    [[INC]] = add nuw nsw i64 [[IV]], 1
334 ; CHECK-NEXT:    [[COND:%.*]] = icmp ne i64 [[INC]], [[N:%.*]]
335 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[LOOP]]
336 ; CHECK:       exit:
337 ; CHECK-NEXT:    ret void
339 loop.ph:
340   br label %loop
342 loop:
343   %iv = phi i64 [ %inc, %for.inc ], [ 0, %loop.ph ]
344   %cmp = icmp slt i64 %iv, %a
345   br i1 %cmp, label %if.then, label %for.inc
347 if.then:
348   %src.arrayidx = getelementptr inbounds i64, i64* %src, i64 %iv
349   %val = load i64, i64* %src.arrayidx
350   %dst.arrayidx = getelementptr inbounds i64, i64* %dst, i64 %iv
351   store i64 %val, i64* %dst.arrayidx
352   br label %for.inc
354 for.inc:
355   %inc = add nuw nsw i64 %iv, 1
356   %cond = icmp ne i64 %inc, %n
357   br i1 %cond, label %exit, label %loop
359 exit:
360   ret void
363 define void @split_loop_bound_dec_with_slt(i64 %a, i64* noalias %src, i64* noalias %dst, i64 %n) {
364 ; CHECK-LABEL: @split_loop_bound_dec_with_slt(
365 ; CHECK-NEXT:  loop.ph:
366 ; CHECK-NEXT:    br label [[LOOP:%.*]]
367 ; CHECK:       loop:
368 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[DEC:%.*]], [[FOR_DEC:%.*]] ], [ 0, [[LOOP_PH:%.*]] ]
369 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i64 [[IV]], [[A:%.*]]
370 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[FOR_DEC]]
371 ; CHECK:       if.then:
372 ; CHECK-NEXT:    [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, i64* [[SRC:%.*]], i64 [[IV]]
373 ; CHECK-NEXT:    [[VAL:%.*]] = load i64, i64* [[SRC_ARRAYIDX]], align 4
374 ; CHECK-NEXT:    [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, i64* [[DST:%.*]], i64 [[IV]]
375 ; CHECK-NEXT:    store i64 [[VAL]], i64* [[DST_ARRAYIDX]], align 4
376 ; CHECK-NEXT:    br label [[FOR_DEC]]
377 ; CHECK:       for.dec:
378 ; CHECK-NEXT:    [[DEC]] = sub nuw nsw i64 [[IV]], 1
379 ; CHECK-NEXT:    [[COND:%.*]] = icmp slt i64 [[DEC]], [[N:%.*]]
380 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[LOOP]]
381 ; CHECK:       exit:
382 ; CHECK-NEXT:    ret void
384 loop.ph:
385   br label %loop
387 loop:
388   %iv = phi i64 [ %dec, %for.dec ], [ 0, %loop.ph ]
389   %cmp = icmp slt i64 %iv, %a
390   br i1 %cmp, label %if.then, label %for.dec
392 if.then:
393   %src.arrayidx = getelementptr inbounds i64, i64* %src, i64 %iv
394   %val = load i64, i64* %src.arrayidx
395   %dst.arrayidx = getelementptr inbounds i64, i64* %dst, i64 %iv
396   store i64 %val, i64* %dst.arrayidx
397   br label %for.dec
399 for.dec:
400   %dec = sub nuw nsw i64 %iv, 1
401   %cond = icmp slt i64 %dec, %n
402   br i1 %cond, label %exit, label %loop
404 exit:
405   ret void
408 define void @split_loop_bound_dec_with_sle(i64 %a, i64* noalias %src, i64* noalias %dst, i64 %n) {
409 ; CHECK-LABEL: @split_loop_bound_dec_with_sle(
410 ; CHECK-NEXT:  loop.ph:
411 ; CHECK-NEXT:    br label [[LOOP:%.*]]
412 ; CHECK:       loop:
413 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[DEC:%.*]], [[FOR_DEC:%.*]] ], [ 0, [[LOOP_PH:%.*]] ]
414 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i64 [[IV]], [[A:%.*]]
415 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[FOR_DEC]]
416 ; CHECK:       if.then:
417 ; CHECK-NEXT:    [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, i64* [[SRC:%.*]], i64 [[IV]]
418 ; CHECK-NEXT:    [[VAL:%.*]] = load i64, i64* [[SRC_ARRAYIDX]], align 4
419 ; CHECK-NEXT:    [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, i64* [[DST:%.*]], i64 [[IV]]
420 ; CHECK-NEXT:    store i64 [[VAL]], i64* [[DST_ARRAYIDX]], align 4
421 ; CHECK-NEXT:    br label [[FOR_DEC]]
422 ; CHECK:       for.dec:
423 ; CHECK-NEXT:    [[DEC]] = sub nuw nsw i64 [[IV]], 1
424 ; CHECK-NEXT:    [[COND:%.*]] = icmp sle i64 [[DEC]], [[N:%.*]]
425 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[LOOP]]
426 ; CHECK:       exit:
427 ; CHECK-NEXT:    ret void
429 loop.ph:
430   br label %loop
432 loop:
433   %iv = phi i64 [ %dec, %for.dec ], [ 0, %loop.ph ]
434   %cmp = icmp slt i64 %iv, %a
435   br i1 %cmp, label %if.then, label %for.dec
437 if.then:
438   %src.arrayidx = getelementptr inbounds i64, i64* %src, i64 %iv
439   %val = load i64, i64* %src.arrayidx
440   %dst.arrayidx = getelementptr inbounds i64, i64* %dst, i64 %iv
441   store i64 %val, i64* %dst.arrayidx
442   br label %for.dec
444 for.dec:
445   %dec = sub nuw nsw i64 %iv, 1
446   %cond = icmp sle i64 %dec, %n
447   br i1 %cond, label %exit, label %loop
449 exit:
450   ret void
453 ; LoopBoundSplit pass should ignore phi which is not scevable phi.
454 define void @split_loop_bound_inc_with_sgt_and_is_not_scevable_phi(i64 %a, i64* noalias %src, i64* noalias %dst, i64 %n) {
455 ; CHECK-LABEL: @split_loop_bound_inc_with_sgt_and_is_not_scevable_phi(
456 ; CHECK-NEXT:  loop.ph:
457 ; CHECK-NEXT:    br label [[LOOP_PH_SPLIT:%.*]]
458 ; CHECK:       loop.ph.split:
459 ; CHECK-NEXT:    [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[N:%.*]], i64 0)
460 ; CHECK-NEXT:    [[NEW_BOUND:%.*]] = call i64 @llvm.smin.i64(i64 [[A:%.*]], i64 [[SMAX]])
461 ; CHECK-NEXT:    br label [[LOOP:%.*]]
462 ; CHECK:       loop:
463 ; CHECK-NEXT:    [[IS_NOT_SCEVABLE_PHI:%.*]] = phi double [ 1.000000e+00, [[FOR_INC:%.*]] ], [ 2.000000e+00, [[LOOP_PH_SPLIT]] ]
464 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_INC]] ], [ 0, [[LOOP_PH_SPLIT]] ]
465 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i64 [[IV]], [[A]]
466 ; CHECK-NEXT:    br i1 true, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
467 ; CHECK:       if.then:
468 ; CHECK-NEXT:    [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, i64* [[SRC:%.*]], i64 [[IV]]
469 ; CHECK-NEXT:    [[VAL:%.*]] = load i64, i64* [[SRC_ARRAYIDX]], align 4
470 ; CHECK-NEXT:    [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, i64* [[DST:%.*]], i64 [[IV]]
471 ; CHECK-NEXT:    store i64 [[VAL]], i64* [[DST_ARRAYIDX]], align 4
472 ; CHECK-NEXT:    br label [[FOR_INC]]
473 ; CHECK:       if.else:
474 ; CHECK-NEXT:    br label [[FOR_INC]]
475 ; CHECK:       for.inc:
476 ; CHECK-NEXT:    [[INC]] = add nuw nsw i64 [[IV]], 1
477 ; CHECK-NEXT:    [[COND:%.*]] = icmp sgt i64 [[INC]], [[NEW_BOUND]]
478 ; CHECK-NEXT:    br i1 [[COND]], label [[LOOP_PH_SPLIT_SPLIT:%.*]], label [[LOOP]]
479 ; CHECK:       loop.ph.split.split:
480 ; CHECK-NEXT:    [[INC_LCSSA:%.*]] = phi i64 [ [[INC]], [[FOR_INC]] ]
481 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp ne i64 [[INC_LCSSA]], [[N]]
482 ; CHECK-NEXT:    br i1 [[TMP0]], label [[LOOP_SPLIT_PREHEADER:%.*]], label [[EXIT:%.*]]
483 ; CHECK:       loop.split.preheader:
484 ; CHECK-NEXT:    br label [[LOOP_SPLIT:%.*]]
485 ; CHECK:       loop.split:
486 ; CHECK-NEXT:    [[IS_NOT_SCEVABLE_PHI_SPLIT:%.*]] = phi double [ 1.000000e+00, [[FOR_INC_SPLIT:%.*]] ], [ 2.000000e+00, [[LOOP_SPLIT_PREHEADER]] ]
487 ; CHECK-NEXT:    [[IV_SPLIT:%.*]] = phi i64 [ [[INC_SPLIT:%.*]], [[FOR_INC_SPLIT]] ], [ [[NEW_BOUND]], [[LOOP_SPLIT_PREHEADER]] ]
488 ; CHECK-NEXT:    [[CMP_SPLIT:%.*]] = icmp slt i64 [[IV_SPLIT]], [[A]]
489 ; CHECK-NEXT:    br i1 false, label [[IF_THEN_SPLIT:%.*]], label [[IF_ELSE_SPLIT:%.*]]
490 ; CHECK:       if.else.split:
491 ; CHECK-NEXT:    br label [[FOR_INC_SPLIT]]
492 ; CHECK:       if.then.split:
493 ; CHECK-NEXT:    [[SRC_ARRAYIDX_SPLIT:%.*]] = getelementptr inbounds i64, i64* [[SRC]], i64 [[IV_SPLIT]]
494 ; CHECK-NEXT:    [[VAL_SPLIT:%.*]] = load i64, i64* [[SRC_ARRAYIDX_SPLIT]], align 4
495 ; CHECK-NEXT:    [[DST_ARRAYIDX_SPLIT:%.*]] = getelementptr inbounds i64, i64* [[DST]], i64 [[IV_SPLIT]]
496 ; CHECK-NEXT:    store i64 [[VAL_SPLIT]], i64* [[DST_ARRAYIDX_SPLIT]], align 4
497 ; CHECK-NEXT:    br label [[FOR_INC_SPLIT]]
498 ; CHECK:       for.inc.split:
499 ; CHECK-NEXT:    [[INC_SPLIT]] = add nuw nsw i64 [[IV_SPLIT]], 1
500 ; CHECK-NEXT:    [[COND_SPLIT:%.*]] = icmp sgt i64 [[INC_SPLIT]], [[N]]
501 ; CHECK-NEXT:    br i1 [[COND_SPLIT]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP_SPLIT]]
502 ; CHECK:       exit.loopexit:
503 ; CHECK-NEXT:    br label [[EXIT]]
504 ; CHECK:       exit:
505 ; CHECK-NEXT:    ret void
507 loop.ph:
508   br label %loop
510 loop:
511   %is_not_scevable_phi = phi double [ 1.0, %for.inc ], [ 2.0, %loop.ph ]
512   %iv = phi i64 [ %inc, %for.inc ], [ 0, %loop.ph ]
513   %cmp = icmp slt i64 %iv, %a
514   br i1 %cmp, label %if.then, label %if.else
516 if.then:
517   %src.arrayidx = getelementptr inbounds i64, i64* %src, i64 %iv
518   %val = load i64, i64* %src.arrayidx
519   %dst.arrayidx = getelementptr inbounds i64, i64* %dst, i64 %iv
520   store i64 %val, i64* %dst.arrayidx
521   br label %for.inc
523 if.else:
524   br label %for.inc
526 for.inc:
527   %inc = add nuw nsw i64 %iv, 1
528   %cond = icmp sgt i64 %inc, %n
529   br i1 %cond, label %exit, label %loop
531 exit:
532   ret void