1 ; RUN: opt < %s -loop-reroll -S | FileCheck %s
2 ; RUN: opt < %s -passes=loop-reroll -S | FileCheck %s
3 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
4 target triple = "x86_64-unknown-linux-gnu"
8 ; for (int i = 0; i < 500; i += 3) {
15 ; Function Attrs: nounwind uwtable
16 define void @bar(i32* nocapture readnone %x) #0 {
20 for.body: ; preds = %for.body, %entry
21 %i.08 = phi i32 [ 0, %entry ], [ %add3, %for.body ]
22 %call = tail call i32 @foo(i32 %i.08) #1
23 %add = add nsw i32 %i.08, 1
24 %call1 = tail call i32 @foo(i32 %add) #1
25 %add2 = add nsw i32 %i.08, 2
26 %call3 = tail call i32 @foo(i32 %add2) #1
27 %add3 = add nsw i32 %i.08, 3
28 %exitcond = icmp sge i32 %add3, 500
29 br i1 %exitcond, label %for.end, label %for.body
34 ; CHECK: %indvar = phi i32 [ %indvar.next, %for.body ], [ 0, %entry ]
35 ; CHECK: %call = tail call i32 @foo(i32 %indvar) #1
36 ; CHECK: %indvar.next = add i32 %indvar, 1
37 ; CHECK: %exitcond1 = icmp eq i32 %indvar, 500
38 ; CHECK: br i1 %exitcond1, label %for.end, label %for.body
42 for.end: ; preds = %for.body
49 ; for (int i = 0; i < 1500; i += 3) {
56 ; Function Attrs: nounwind uwtable
57 define void @hi1(i32* nocapture %x) #0 {
61 for.body: ; preds = %entry, %for.body
62 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
63 %call = tail call i32 @foo(i32 0) #1
64 %arrayidx = getelementptr inbounds i32, i32* %x, i64 %indvars.iv
65 store i32 %call, i32* %arrayidx, align 4
66 %call1 = tail call i32 @foo(i32 0) #1
67 %0 = add nsw i64 %indvars.iv, 1
68 %arrayidx3 = getelementptr inbounds i32, i32* %x, i64 %0
69 store i32 %call1, i32* %arrayidx3, align 4
70 %call4 = tail call i32 @foo(i32 0) #1
71 %1 = add nsw i64 %indvars.iv, 2
72 %arrayidx7 = getelementptr inbounds i32, i32* %x, i64 %1
73 store i32 %call4, i32* %arrayidx7, align 4
74 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 3
75 %2 = trunc i64 %indvars.iv.next to i32
76 %cmp = icmp slt i32 %2, 1500
77 br i1 %cmp, label %for.body, label %for.end
82 ; CHECK: %indvar = phi i64 [ %indvar.next, %for.body ], [ 0, %entry ]
83 ; CHECK: %0 = trunc i64 %indvar to i32
84 ; CHECK: %call = tail call i32 @foo(i32 0) #1
85 ; CHECK: %arrayidx = getelementptr inbounds i32, i32* %x, i64 %indvar
86 ; CHECK: store i32 %call, i32* %arrayidx, align 4
87 ; CHECK: %indvar.next = add i64 %indvar, 1
88 ; CHECK: %exitcond = icmp eq i32 %0, 1499
89 ; CHECK: br i1 %exitcond, label %for.end, label %for.body
93 for.end: ; preds = %for.body
98 ; for (int i = 0; i < 500; ++i) {
105 ; Function Attrs: nounwind uwtable
106 define void @hi2(i32* nocapture %x) #0 {
110 for.body: ; preds = %for.body, %entry
111 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
112 %call = tail call i32 @foo(i32 0) #1
113 %0 = mul nsw i64 %indvars.iv, 3
114 %arrayidx = getelementptr inbounds i32, i32* %x, i64 %0
115 store i32 %call, i32* %arrayidx, align 4
116 %call1 = tail call i32 @foo(i32 0) #1
117 %1 = add nsw i64 %0, 1
118 %arrayidx4 = getelementptr inbounds i32, i32* %x, i64 %1
119 store i32 %call1, i32* %arrayidx4, align 4
120 %call5 = tail call i32 @foo(i32 0) #1
121 %2 = add nsw i64 %0, 2
122 %arrayidx9 = getelementptr inbounds i32, i32* %x, i64 %2
123 store i32 %call5, i32* %arrayidx9, align 4
124 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
125 %exitcond = icmp eq i64 %indvars.iv.next, 500
126 br i1 %exitcond, label %for.end, label %for.body
131 ; CHECK: %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
132 ; CHECK: %call = tail call i32 @foo(i32 0) #1
133 ; CHECK: %arrayidx = getelementptr inbounds i32, i32* %x, i64 %indvars.iv
134 ; CHECK: store i32 %call, i32* %arrayidx, align 4
135 ; CHECK: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
136 ; CHECK: %exitcond1 = icmp eq i64 %indvars.iv, 1499
137 ; CHECK: br i1 %exitcond1, label %for.end, label %for.body
141 for.end: ; preds = %for.body
145 ; void goo(float alpha, float *a, float *b) {
146 ; for (int i = 0; i < 3200; i += 5) {
147 ; a[i] += alpha * b[i];
148 ; a[i + 1] += alpha * b[i + 1];
149 ; a[i + 2] += alpha * b[i + 2];
150 ; a[i + 3] += alpha * b[i + 3];
151 ; a[i + 4] += alpha * b[i + 4];
155 ; Function Attrs: nounwind uwtable
156 define void @goo(float %alpha, float* nocapture %a, float* nocapture readonly %b) #0 {
160 for.body: ; preds = %entry, %for.body
161 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
162 %arrayidx = getelementptr inbounds float, float* %b, i64 %indvars.iv
163 %0 = load float, float* %arrayidx, align 4
164 %mul = fmul float %0, %alpha
165 %arrayidx2 = getelementptr inbounds float, float* %a, i64 %indvars.iv
166 %1 = load float, float* %arrayidx2, align 4
167 %add = fadd float %1, %mul
168 store float %add, float* %arrayidx2, align 4
169 %2 = add nsw i64 %indvars.iv, 1
170 %arrayidx5 = getelementptr inbounds float, float* %b, i64 %2
171 %3 = load float, float* %arrayidx5, align 4
172 %mul6 = fmul float %3, %alpha
173 %arrayidx9 = getelementptr inbounds float, float* %a, i64 %2
174 %4 = load float, float* %arrayidx9, align 4
175 %add10 = fadd float %4, %mul6
176 store float %add10, float* %arrayidx9, align 4
177 %5 = add nsw i64 %indvars.iv, 2
178 %arrayidx13 = getelementptr inbounds float, float* %b, i64 %5
179 %6 = load float, float* %arrayidx13, align 4
180 %mul14 = fmul float %6, %alpha
181 %arrayidx17 = getelementptr inbounds float, float* %a, i64 %5
182 %7 = load float, float* %arrayidx17, align 4
183 %add18 = fadd float %7, %mul14
184 store float %add18, float* %arrayidx17, align 4
185 %8 = add nsw i64 %indvars.iv, 3
186 %arrayidx21 = getelementptr inbounds float, float* %b, i64 %8
187 %9 = load float, float* %arrayidx21, align 4
188 %mul22 = fmul float %9, %alpha
189 %arrayidx25 = getelementptr inbounds float, float* %a, i64 %8
190 %10 = load float, float* %arrayidx25, align 4
191 %add26 = fadd float %10, %mul22
192 store float %add26, float* %arrayidx25, align 4
193 %11 = add nsw i64 %indvars.iv, 4
194 %arrayidx29 = getelementptr inbounds float, float* %b, i64 %11
195 %12 = load float, float* %arrayidx29, align 4
196 %mul30 = fmul float %12, %alpha
197 %arrayidx33 = getelementptr inbounds float, float* %a, i64 %11
198 %13 = load float, float* %arrayidx33, align 4
199 %add34 = fadd float %13, %mul30
200 store float %add34, float* %arrayidx33, align 4
201 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 5
202 %14 = trunc i64 %indvars.iv.next to i32
203 %cmp = icmp slt i32 %14, 3200
204 br i1 %cmp, label %for.body, label %for.end
209 ; CHECK: %indvar = phi i64 [ %indvar.next, %for.body ], [ 0, %entry ]
210 ; CHECK: %0 = trunc i64 %indvar to i32
211 ; CHECK: %arrayidx = getelementptr inbounds float, float* %b, i64 %indvar
212 ; CHECK: %1 = load float, float* %arrayidx, align 4
213 ; CHECK: %mul = fmul float %1, %alpha
214 ; CHECK: %arrayidx2 = getelementptr inbounds float, float* %a, i64 %indvar
215 ; CHECK: %2 = load float, float* %arrayidx2, align 4
216 ; CHECK: %add = fadd float %2, %mul
217 ; CHECK: store float %add, float* %arrayidx2, align 4
218 ; CHECK: %indvar.next = add i64 %indvar, 1
219 ; CHECK: %exitcond = icmp eq i32 %0, 3199
220 ; CHECK: br i1 %exitcond, label %for.end, label %for.body
224 for.end: ; preds = %for.body
228 ; void hoo(float alpha, float *a, float *b, int *ip) {
229 ; for (int i = 0; i < 3200; i += 5) {
230 ; a[i] += alpha * b[ip[i]];
231 ; a[i + 1] += alpha * b[ip[i + 1]];
232 ; a[i + 2] += alpha * b[ip[i + 2]];
233 ; a[i + 3] += alpha * b[ip[i + 3]];
234 ; a[i + 4] += alpha * b[ip[i + 4]];
238 ; Function Attrs: nounwind uwtable
239 define void @hoo(float %alpha, float* nocapture %a, float* nocapture readonly %b, i32* nocapture readonly %ip) #0 {
243 for.body: ; preds = %entry, %for.body
244 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
245 %arrayidx = getelementptr inbounds i32, i32* %ip, i64 %indvars.iv
246 %0 = load i32, i32* %arrayidx, align 4
247 %idxprom1 = sext i32 %0 to i64
248 %arrayidx2 = getelementptr inbounds float, float* %b, i64 %idxprom1
249 %1 = load float, float* %arrayidx2, align 4
250 %mul = fmul float %1, %alpha
251 %arrayidx4 = getelementptr inbounds float, float* %a, i64 %indvars.iv
252 %2 = load float, float* %arrayidx4, align 4
253 %add = fadd float %2, %mul
254 store float %add, float* %arrayidx4, align 4
255 %3 = add nsw i64 %indvars.iv, 1
256 %arrayidx7 = getelementptr inbounds i32, i32* %ip, i64 %3
257 %4 = load i32, i32* %arrayidx7, align 4
258 %idxprom8 = sext i32 %4 to i64
259 %arrayidx9 = getelementptr inbounds float, float* %b, i64 %idxprom8
260 %5 = load float, float* %arrayidx9, align 4
261 %mul10 = fmul float %5, %alpha
262 %arrayidx13 = getelementptr inbounds float, float* %a, i64 %3
263 %6 = load float, float* %arrayidx13, align 4
264 %add14 = fadd float %6, %mul10
265 store float %add14, float* %arrayidx13, align 4
266 %7 = add nsw i64 %indvars.iv, 2
267 %arrayidx17 = getelementptr inbounds i32, i32* %ip, i64 %7
268 %8 = load i32, i32* %arrayidx17, align 4
269 %idxprom18 = sext i32 %8 to i64
270 %arrayidx19 = getelementptr inbounds float, float* %b, i64 %idxprom18
271 %9 = load float, float* %arrayidx19, align 4
272 %mul20 = fmul float %9, %alpha
273 %arrayidx23 = getelementptr inbounds float, float* %a, i64 %7
274 %10 = load float, float* %arrayidx23, align 4
275 %add24 = fadd float %10, %mul20
276 store float %add24, float* %arrayidx23, align 4
277 %11 = add nsw i64 %indvars.iv, 3
278 %arrayidx27 = getelementptr inbounds i32, i32* %ip, i64 %11
279 %12 = load i32, i32* %arrayidx27, align 4
280 %idxprom28 = sext i32 %12 to i64
281 %arrayidx29 = getelementptr inbounds float, float* %b, i64 %idxprom28
282 %13 = load float, float* %arrayidx29, align 4
283 %mul30 = fmul float %13, %alpha
284 %arrayidx33 = getelementptr inbounds float, float* %a, i64 %11
285 %14 = load float, float* %arrayidx33, align 4
286 %add34 = fadd float %14, %mul30
287 store float %add34, float* %arrayidx33, align 4
288 %15 = add nsw i64 %indvars.iv, 4
289 %arrayidx37 = getelementptr inbounds i32, i32* %ip, i64 %15
290 %16 = load i32, i32* %arrayidx37, align 4
291 %idxprom38 = sext i32 %16 to i64
292 %arrayidx39 = getelementptr inbounds float, float* %b, i64 %idxprom38
293 %17 = load float, float* %arrayidx39, align 4
294 %mul40 = fmul float %17, %alpha
295 %arrayidx43 = getelementptr inbounds float, float* %a, i64 %15
296 %18 = load float, float* %arrayidx43, align 4
297 %add44 = fadd float %18, %mul40
298 store float %add44, float* %arrayidx43, align 4
299 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 5
300 %19 = trunc i64 %indvars.iv.next to i32
301 %cmp = icmp slt i32 %19, 3200
302 br i1 %cmp, label %for.body, label %for.end
307 ; CHECK: %indvar = phi i64 [ %indvar.next, %for.body ], [ 0, %entry ]
308 ; CHECK: %0 = trunc i64 %indvar to i32
309 ; CHECK: %arrayidx = getelementptr inbounds i32, i32* %ip, i64 %indvar
310 ; CHECK: %1 = load i32, i32* %arrayidx, align 4
311 ; CHECK: %idxprom1 = sext i32 %1 to i64
312 ; CHECK: %arrayidx2 = getelementptr inbounds float, float* %b, i64 %idxprom1
313 ; CHECK: %2 = load float, float* %arrayidx2, align 4
314 ; CHECK: %mul = fmul float %2, %alpha
315 ; CHECK: %arrayidx4 = getelementptr inbounds float, float* %a, i64 %indvar
316 ; CHECK: %3 = load float, float* %arrayidx4, align 4
317 ; CHECK: %add = fadd float %3, %mul
318 ; CHECK: store float %add, float* %arrayidx4, align 4
319 ; CHECK: %indvar.next = add i64 %indvar, 1
320 ; CHECK: %exitcond = icmp eq i32 %0, 3199
321 ; CHECK: br i1 %exitcond, label %for.end, label %for.body
325 for.end: ; preds = %for.body
329 ; void multi1(int *x) {
331 ; for (int i = 0; i < 500; ++i) {
341 ; Function Attrs: nounwind uwtable
342 define void @multi1(i32* nocapture %x) #0 {
344 %call = tail call i32 @foo(i32 0) #1
347 for.body: ; preds = %for.body, %entry
348 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
349 %0 = mul nsw i64 %indvars.iv, 3
350 %arrayidx = getelementptr inbounds i32, i32* %x, i64 %0
351 store i32 %call, i32* %arrayidx, align 4
352 %1 = add nsw i64 %0, 1
353 %arrayidx4 = getelementptr inbounds i32, i32* %x, i64 %1
354 store i32 %call, i32* %arrayidx4, align 4
355 %2 = add nsw i64 %0, 2
356 %arrayidx9 = getelementptr inbounds i32, i32* %x, i64 %2
357 store i32 %call, i32* %arrayidx9, align 4
358 %3 = add nsw i64 %0, 6
359 %arrayidx6 = getelementptr inbounds i32, i32* %x, i64 %3
360 store i32 %call, i32* %arrayidx6, align 4
361 %4 = add nsw i64 %0, 7
362 %arrayidx7 = getelementptr inbounds i32, i32* %x, i64 %4
363 store i32 %call, i32* %arrayidx7, align 4
364 %5 = add nsw i64 %0, 8
365 %arrayidx8 = getelementptr inbounds i32, i32* %x, i64 %5
366 store i32 %call, i32* %arrayidx8, align 4
367 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
368 %exitcond = icmp eq i64 %indvars.iv.next, 500
369 br i1 %exitcond, label %for.end, label %for.body
371 ; CHECK-LABEL: @multi1
374 ; CHECK: %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
375 ; CHECK: %0 = add i64 %indvars.iv, 6
376 ; CHECK: %arrayidx = getelementptr inbounds i32, i32* %x, i64 %indvars.iv
377 ; CHECK: store i32 %call, i32* %arrayidx, align 4
378 ; CHECK: %arrayidx6 = getelementptr inbounds i32, i32* %x, i64 %0
379 ; CHECK: store i32 %call, i32* %arrayidx6, align 4
380 ; CHECK: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
381 ; CHECK: %exitcond1 = icmp eq i64 %indvars.iv, 1499
382 ; CHECK: br i1 %exitcond1, label %for.end, label %for.body
384 for.end: ; preds = %for.body
388 ; void multi2(int *x) {
390 ; for (int i = 0; i < 500; ++i) {
400 ; Function Attrs: nounwind uwtable
401 define void @multi2(i32* nocapture %x) #0 {
403 %call = tail call i32 @foo(i32 0) #1
406 for.body: ; preds = %for.body, %entry
407 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
408 %0 = mul nsw i64 %indvars.iv, 3
409 %add = add nsw i64 %indvars.iv, 1
410 %newmul = mul nsw i64 %add, 3
411 %arrayidx = getelementptr inbounds i32, i32* %x, i64 %0
412 store i32 %call, i32* %arrayidx, align 4
413 %1 = add nsw i64 %0, 1
414 %arrayidx4 = getelementptr inbounds i32, i32* %x, i64 %1
415 store i32 %call, i32* %arrayidx4, align 4
416 %2 = add nsw i64 %0, 2
417 %arrayidx9 = getelementptr inbounds i32, i32* %x, i64 %2
418 store i32 %call, i32* %arrayidx9, align 4
419 %arrayidx6 = getelementptr inbounds i32, i32* %x, i64 %newmul
420 store i32 %call, i32* %arrayidx6, align 4
421 %3 = add nsw i64 %newmul, 1
422 %arrayidx7 = getelementptr inbounds i32, i32* %x, i64 %3
423 store i32 %call, i32* %arrayidx7, align 4
424 %4 = add nsw i64 %newmul, 2
425 %arrayidx8 = getelementptr inbounds i32, i32* %x, i64 %4
426 store i32 %call, i32* %arrayidx8, align 4
427 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
428 %exitcond = icmp eq i64 %indvars.iv.next, 500
429 br i1 %exitcond, label %for.end, label %for.body
431 ; CHECK-LABEL: @multi2
434 ; CHECK: %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
435 ; CHECK: %0 = add i64 %indvars.iv, 3
436 ; CHECK: %arrayidx = getelementptr inbounds i32, i32* %x, i64 %indvars.iv
437 ; CHECK: store i32 %call, i32* %arrayidx, align 4
438 ; CHECK: %arrayidx6 = getelementptr inbounds i32, i32* %x, i64 %0
439 ; CHECK: store i32 %call, i32* %arrayidx6, align 4
440 ; CHECK: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
441 ; CHECK: %exitcond1 = icmp eq i64 %indvars.iv, 1499
442 ; CHECK: br i1 %exitcond1, label %for.end, label %for.body
444 for.end: ; preds = %for.body
448 ; void multi3(int *x) {
450 ; for (int i = 0; i < 500; ++i) {
451 ; // Note: No zero index
458 ; Function Attrs: nounwind uwtable
459 define void @multi3(i32* nocapture %x) #0 {
461 %call = tail call i32 @foo(i32 0) #1
464 for.body: ; preds = %for.body, %entry
465 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
466 %0 = mul nsw i64 %indvars.iv, 3
467 %x0 = add nsw i64 %0, 3
468 %add = add nsw i64 %indvars.iv, 1
469 %arrayidx = getelementptr inbounds i32, i32* %x, i64 %x0
470 store i32 %call, i32* %arrayidx, align 4
471 %1 = add nsw i64 %0, 4
472 %arrayidx4 = getelementptr inbounds i32, i32* %x, i64 %1
473 store i32 %call, i32* %arrayidx4, align 4
474 %2 = add nsw i64 %0, 5
475 %arrayidx9 = getelementptr inbounds i32, i32* %x, i64 %2
476 store i32 %call, i32* %arrayidx9, align 4
477 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
478 %exitcond = icmp eq i64 %indvars.iv.next, 500
479 br i1 %exitcond, label %for.end, label %for.body
481 ; CHECK-LABEL: @multi3
483 ; CHECK: %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
484 ; CHECK: %0 = add i64 %indvars.iv, 3
485 ; CHECK: %arrayidx = getelementptr inbounds i32, i32* %x, i64 %0
486 ; CHECK: store i32 %call, i32* %arrayidx, align 4
487 ; CHECK: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
488 ; CHECK: %exitcond1 = icmp eq i64 %indvars.iv, 1499
489 ; CHECK: br i1 %exitcond1, label %for.end, label %for.body
491 for.end: ; preds = %for.body
496 ; void bar2(int *x, int y, int z) {
497 ; for (int i = 0; i < 500; i += 3) {
498 ; foo(i+y+i*z); // Slightly reordered instruction order
499 ; foo(i+1+y+(i+1)*z);
500 ; foo(i+2+y+(i+2)*z);
504 ; Function Attrs: nounwind uwtable
505 define void @bar2(i32* nocapture readnone %x, i32 %y, i32 %z) #0 {
509 for.body: ; preds = %for.body, %entry
510 %i.08 = phi i32 [ 0, %entry ], [ %add3, %for.body ]
512 %tmp1 = add i32 %i.08, %y
513 %tmp2 = mul i32 %i.08, %z
514 %tmp3 = add i32 %tmp2, %tmp1
515 %call = tail call i32 @foo(i32 %tmp3) #1
517 %add = add nsw i32 %i.08, 1
518 %tmp2a = mul i32 %add, %z
519 %tmp1a = add i32 %add, %y
520 %tmp3a = add i32 %tmp2a, %tmp1a
521 %calla = tail call i32 @foo(i32 %tmp3a) #1
523 %add2 = add nsw i32 %i.08, 2
524 %tmp2b = mul i32 %add2, %z
525 %tmp1b = add i32 %add2, %y
526 %tmp3b = add i32 %tmp2b, %tmp1b
527 %callb = tail call i32 @foo(i32 %tmp3b) #1
529 %add3 = add nsw i32 %i.08, 3
531 %exitcond = icmp sge i32 %add3, 500
532 br i1 %exitcond, label %for.end, label %for.body
537 ; CHECK: %indvar = phi i32 [ %indvar.next, %for.body ], [ 0, %entry ]
538 ; CHECK: %tmp1 = add i32 %indvar, %y
539 ; CHECK: %tmp2 = mul i32 %indvar, %z
540 ; CHECK: %tmp3 = add i32 %tmp2, %tmp1
541 ; CHECK: %call = tail call i32 @foo(i32 %tmp3) #1
542 ; CHECK: %indvar.next = add i32 %indvar, 1
543 ; CHECK: %exitcond1 = icmp eq i32 %indvar, 500
544 ; CHECK: br i1 %exitcond1, label %for.end, label %for.body
548 for.end: ; preds = %for.body
552 %struct.s = type { i32, i32 }
554 ; Function Attrs: nounwind uwtable
555 define void @gep1(%struct.s* nocapture %x) #0 {
557 %call = tail call i32 @foo(i32 0) #1
560 for.body: ; preds = %for.body, %entry
561 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
562 %0 = mul nsw i64 %indvars.iv, 3
563 %arrayidx = getelementptr inbounds %struct.s, %struct.s* %x, i64 %0, i32 0
564 store i32 %call, i32* %arrayidx, align 4
565 %1 = add nsw i64 %0, 1
566 %arrayidx4 = getelementptr inbounds %struct.s, %struct.s* %x, i64 %1, i32 0
567 store i32 %call, i32* %arrayidx4, align 4
568 %2 = add nsw i64 %0, 2
569 %arrayidx9 = getelementptr inbounds %struct.s, %struct.s* %x, i64 %2, i32 0
570 store i32 %call, i32* %arrayidx9, align 4
571 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
572 %exitcond = icmp eq i64 %indvars.iv.next, 500
573 br i1 %exitcond, label %for.end, label %for.body
576 ; This test is a crash test only.
578 for.end: ; preds = %for.body
582 define void @gep-indexing(i32* nocapture %x) {
584 %call = tail call i32 @foo(i32 0) #1
587 for.body: ; preds = %for.body, %entry
588 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
589 %0 = mul nsw i64 %indvars.iv, 3
590 %arrayidx = getelementptr inbounds i32, i32* %x, i64 %0
591 store i32 %call, i32* %arrayidx, align 4
592 %arrayidx4 = getelementptr inbounds i32, i32* %arrayidx, i64 1
593 store i32 %call, i32* %arrayidx4, align 4
594 %arrayidx9 = getelementptr inbounds i32, i32* %arrayidx, i64 2
595 store i32 %call, i32* %arrayidx9, align 4
596 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
597 %exitcond = icmp eq i64 %indvars.iv.next, 500
598 br i1 %exitcond, label %for.end, label %for.body
600 ; CHECK-LABEL: @gep-indexing
602 ; CHECK-NEXT: %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
603 ; CHECK-NEXT: %scevgep = getelementptr i32, i32* %x, i64 %indvars.iv
604 ; CHECK-NEXT: store i32 %call, i32* %scevgep, align 4
605 ; CHECK-NEXT: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
606 ; CHECK-NEXT: %exitcond1 = icmp eq i64 %indvars.iv, 1499
607 ; CHECK-NEXT: br i1 %exitcond1, label %for.end, label %for.body
609 for.end: ; preds = %for.body
614 define void @unordered_atomic_ops(i32* noalias %buf_0, i32* noalias %buf_1) {
615 ; CHECK-LABEL: @unordered_atomic_ops(
618 ; CHECK-NEXT: %indvar = phi i32 [ %indvar.next, %for.body ], [ 0, %entry ]
619 ; CHECK-NEXT: %buf0_a = getelementptr i32, i32* %buf_0, i32 %indvar
620 ; CHECK-NEXT: %buf1_a = getelementptr i32, i32* %buf_1, i32 %indvar
621 ; CHECK-NEXT: %va = load atomic i32, i32* %buf0_a unordered, align 4
622 ; CHECK-NEXT: store atomic i32 %va, i32* %buf1_a unordered, align 4
623 ; CHECK-NEXT: %indvar.next = add i32 %indvar, 1
624 ; CHECK-NEXT: %exitcond = icmp eq i32 %indvar, 3199
625 ; CHECK-NEXT: br i1 %exitcond, label %for.end, label %for.body
631 %indvars.iv = phi i32 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
632 %indvars.iv.next = add i32 %indvars.iv, 2
633 %indvars.mid = add i32 %indvars.iv, 1
634 %buf0_a = getelementptr i32, i32* %buf_0, i32 %indvars.iv
635 %buf0_b = getelementptr i32, i32* %buf_0, i32 %indvars.mid
636 %buf1_a = getelementptr i32, i32* %buf_1, i32 %indvars.iv
637 %buf1_b = getelementptr i32, i32* %buf_1, i32 %indvars.mid
638 %va = load atomic i32, i32* %buf0_a unordered, align 4
639 %vb = load atomic i32, i32* %buf0_b unordered, align 4
640 store atomic i32 %va, i32* %buf1_a unordered, align 4
641 store atomic i32 %vb, i32* %buf1_b unordered, align 4
642 %cmp = icmp slt i32 %indvars.iv.next, 3200
643 br i1 %cmp, label %for.body, label %for.end
649 define void @unordered_atomic_ops_nomatch(i32* noalias %buf_0, i32* noalias %buf_1) {
652 ; CHECK-LABEL: @unordered_atomic_ops_nomatch(
658 ; CHECK: %indvars.iv.next = add i32 %indvars.iv, 2
659 ; CHECK: %indvars.mid = add i32 %indvars.iv, 1
660 ; CHECK: %cmp = icmp slt i32 %indvars.iv.next, 3200
661 ; CHECK: br i1 %cmp, label %for.body, label %for.end
663 %indvars.iv = phi i32 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
664 %indvars.iv.next = add i32 %indvars.iv, 2
665 %indvars.mid = add i32 %indvars.iv, 1
666 %buf0_a = getelementptr i32, i32* %buf_0, i32 %indvars.iv
667 %buf0_b = getelementptr i32, i32* %buf_0, i32 %indvars.mid
668 %buf1_a = getelementptr i32, i32* %buf_1, i32 %indvars.iv
669 %buf1_b = getelementptr i32, i32* %buf_1, i32 %indvars.mid
670 %va = load atomic i32, i32* %buf0_a unordered, align 4
671 %vb = load atomic i32, i32* %buf0_b unordered, align 4
672 store i32 %va, i32* %buf1_a, align 4 ;; Not atomic
673 store atomic i32 %vb, i32* %buf1_b unordered, align 4
674 %cmp = icmp slt i32 %indvars.iv.next, 3200
675 br i1 %cmp, label %for.body, label %for.end
681 define void @ordered_atomic_ops(i32* noalias %buf_0, i32* noalias %buf_1) {
684 ; CHECK-LABEL: @ordered_atomic_ops(
690 ; CHECK: %indvars.iv.next = add i32 %indvars.iv, 2
691 ; CHECK: %indvars.mid = add i32 %indvars.iv, 1
692 ; CHECK: %cmp = icmp slt i32 %indvars.iv.next, 3200
693 ; CHECK: br i1 %cmp, label %for.body, label %for.end
695 %indvars.iv = phi i32 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
696 %indvars.iv.next = add i32 %indvars.iv, 2
697 %indvars.mid = add i32 %indvars.iv, 1
698 %buf0_a = getelementptr i32, i32* %buf_0, i32 %indvars.iv
699 %buf0_b = getelementptr i32, i32* %buf_0, i32 %indvars.mid
700 %buf1_a = getelementptr i32, i32* %buf_1, i32 %indvars.iv
701 %buf1_b = getelementptr i32, i32* %buf_1, i32 %indvars.mid
702 %va = load atomic i32, i32* %buf0_a acquire, align 4
703 %vb = load atomic i32, i32* %buf0_b acquire, align 4
704 store atomic i32 %va, i32* %buf1_a release, align 4
705 store atomic i32 %vb, i32* %buf1_b release, align 4
706 %cmp = icmp slt i32 %indvars.iv.next, 3200
707 br i1 %cmp, label %for.body, label %for.end
713 define void @unordered_atomic_ops_with_fence(i32* noalias %buf_0, i32* noalias %buf_1) {
714 ; CHECK-LABEL: @unordered_atomic_ops_with_fence(
720 ; CHECK: %va = load atomic i32, i32* %buf0_a unordered, align 4
721 ; CHECK-NEXT: %vb = load atomic i32, i32* %buf0_b unordered, align 4
722 ; CHECK-NEXT: fence seq_cst
723 ; CHECK-NEXT: store atomic i32 %va, i32* %buf1_a unordered, align 4
724 ; CHECK-NEXT: store atomic i32 %vb, i32* %buf1_b unordered, align 4
726 %indvars.iv = phi i32 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
727 %indvars.iv.next = add i32 %indvars.iv, 2
728 %indvars.mid = add i32 %indvars.iv, 1
729 %buf0_a = getelementptr i32, i32* %buf_0, i32 %indvars.iv
730 %buf0_b = getelementptr i32, i32* %buf_0, i32 %indvars.mid
731 %buf1_a = getelementptr i32, i32* %buf_1, i32 %indvars.iv
732 %buf1_b = getelementptr i32, i32* %buf_1, i32 %indvars.mid
733 %va = load atomic i32, i32* %buf0_a unordered, align 4
734 %vb = load atomic i32, i32* %buf0_b unordered, align 4
736 store atomic i32 %va, i32* %buf1_a unordered, align 4
737 store atomic i32 %vb, i32* %buf1_b unordered, align 4
738 %cmp = icmp slt i32 %indvars.iv.next, 3200
739 br i1 %cmp, label %for.body, label %for.end
745 define void @pointer_bitcast_baseinst(i16* %arg, i8* %arg1, i64 %arg2) {
746 ; CHECK-LABEL: @pointer_bitcast_baseinst(
748 ; CHECK-NEXT: %indvar = phi i64 [ %indvar.next, %bb3 ], [ 0, %bb ]
749 ; CHECK-NEXT: %4 = shl nuw i64 %indvar, 3
750 ; CHECK-NEXT: %5 = add i64 %4, 1
751 ; CHECK-NEXT: %tmp5 = shl nuw i64 %5, 1
752 ; CHECK-NEXT: %tmp6 = getelementptr i8, i8* %arg1, i64 %tmp5
753 ; CHECK-NEXT: %tmp7 = bitcast i8* %tmp6 to <8 x i16>*
754 ; CHECK-NEXT: %tmp8 = load <8 x i16>, <8 x i16>* %tmp7, align 2
755 ; CHECK-NEXT: %tmp13 = getelementptr i16, i16* %arg, i64 %5
756 ; CHECK-NEXT: %tmp14 = bitcast i16* %tmp13 to <8 x i16>*
757 ; CHECK-NEXT: store <8 x i16> %tmp8, <8 x i16>* %tmp14, align 2
758 ; CHECK-NEXT: %indvar.next = add i64 %indvar, 1
759 ; CHECK-NEXT: %exitcond = icmp eq i64 %indvar, %3
760 ; CHECK-NEXT: br i1 %exitcond, label %bb19, label %bb3
764 bb3: ; preds = %bb3, %bb
765 %tmp = phi i64 [ 1, %bb ], [ %tmp17, %bb3 ]
766 %tmp4 = add nuw i64 %tmp, 8
767 %tmp5 = shl nuw i64 %tmp, 1
768 %tmp6 = getelementptr i8, i8* %arg1, i64 %tmp5
769 %tmp7 = bitcast i8* %tmp6 to <8 x i16>*
770 %tmp8 = load <8 x i16>, <8 x i16>* %tmp7, align 2
771 %tmp9 = shl i64 %tmp4, 1
772 %tmp10 = getelementptr i8, i8* %arg1, i64 %tmp9
773 %tmp11 = bitcast i8* %tmp10 to <8 x i16>*
774 %tmp12 = load <8 x i16>, <8 x i16>* %tmp11, align 2
775 %tmp13 = getelementptr i16, i16* %arg, i64 %tmp
776 %tmp14 = bitcast i16* %tmp13 to <8 x i16>*
777 store <8 x i16> %tmp8, <8 x i16>* %tmp14, align 2
778 %tmp15 = getelementptr i16, i16* %arg, i64 %tmp4
779 %tmp16 = bitcast i16* %tmp15 to <8 x i16>*
780 store <8 x i16> %tmp12, <8 x i16>* %tmp16, align 2
781 %tmp17 = add nuw nsw i64 %tmp, 16
782 %tmp18 = icmp eq i64 %tmp17, %arg2
783 br i1 %tmp18, label %bb19, label %bb3
789 define void @bad_step(i32* nocapture readnone %x) #0 {
793 for.body: ; preds = %for.body, %entry
794 %i.08 = phi i32 [ 0, %entry ], [ %add3, %for.body ]
795 %call = tail call i32 @foo(i32 %i.08) #1
796 %add = add nsw i32 %i.08, 2
797 %call1 = tail call i32 @foo(i32 %add) #1
798 %add2 = add nsw i32 %i.08, 3
799 %call3 = tail call i32 @foo(i32 %add2) #1
800 %add3 = add nsw i32 %i.08, 6
801 %exitcond = icmp sge i32 %add3, 500
802 br i1 %exitcond, label %for.end, label %for.body
804 ; CHECK-LABEL: @bad_step
805 ; CHECK: %add = add nsw i32 %i.08, 2
806 ; CHECK: %add2 = add nsw i32 %i.08, 3
807 ; CHECK: %add3 = add nsw i32 %i.08, 6
809 for.end: ; preds = %for.body
813 @a = external global [2 x [512 x i64]], align 16
814 @b = external global [512 x [4 x i64]], align 16
816 define void @ptr_step_crash() {
817 ; CHECK-LABEL: @ptr_step_crash(
819 br label %for.body42.3
821 for.body42.3: ; preds = %for.body42.3, %entry
822 %k.2207.3 = phi i32 [ -512, %entry ], [ %inc63.3, %for.body42.3 ]
823 %sub46.3 = add nsw i32 %k.2207.3, 512
824 %idxprom47.3 = zext i32 %sub46.3 to i64
825 %arrayidx48.3 = getelementptr inbounds [2 x [512 x i64]], [2 x [512 x i64]]* @a, i64 0, i64 0, i64 %idxprom47.3
826 %arrayidx55.3 = getelementptr inbounds [512 x [4 x i64]], [512 x [4 x i64]]* @b, i64 0, i64 %idxprom47.3, i64 3
827 %0 = load i64, i64* %arrayidx55.3, align 8
828 %inc63.3 = add nsw i32 %k.2207.3, 1
829 br i1 undef, label %for.inc65.3, label %for.body42.3
831 for.inc65.3: ; preds = %for.body42.3
835 attributes #0 = { nounwind uwtable }
836 attributes #1 = { nounwind }