Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / Analysis / LoopAccessAnalysis / stride-access-dependence.ll
blobbfdd15f170d062900a5143a61e732a3541569a9b
1 ; RUN: opt -passes='print<access-info>' -disable-output  < %s 2>&1 | FileCheck %s
3 target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"
5 ; Following cases are no dependence.
7 ; void nodep_Read_Write(int *A) {
8 ;   int *B = A + 1;
9 ;   for (unsigned i = 0; i < 1024; i+=3)
10 ;     B[i] = A[i] + 1;
11 ; }
13 ; CHECK: function 'nodep_Read_Write':
14 ; CHECK-NEXT:   for.body:
15 ; CHECK-NEXT:     Memory dependences are safe
16 ; CHECK-NEXT:     Dependences:
17 ; CHECK-NEXT:     Run-time memory checks:
19 define void @nodep_Read_Write(ptr nocapture %A) {
20 entry:
21   %add.ptr = getelementptr inbounds i32, ptr %A, i64 1
22   br label %for.body
24 for.cond.cleanup:                                 ; preds = %for.body
25   ret void
27 for.body:                                         ; preds = %entry, %for.body
28   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
29   %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv
30   %0 = load i32, ptr %arrayidx, align 4
31   %add = add nsw i32 %0, 1
32   %arrayidx2 = getelementptr inbounds i32, ptr %add.ptr, i64 %indvars.iv
33   store i32 %add, ptr %arrayidx2, align 4
34   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 3
35   %cmp = icmp ult i64 %indvars.iv.next, 1024
36   br i1 %cmp, label %for.body, label %for.cond.cleanup
39 ; int nodep_Write_Read(int *A) {
40 ;   int sum = 0;
41 ;   for (unsigned i = 0; i < 1024; i+=4) {
42 ;     A[i] = i;
43 ;     sum += A[i+3];
44 ;   }
45 ;   
46 ;   return sum;
47 ; }
49 ; CHECK: function 'nodep_Write_Read':
50 ; CHECK-NEXT:   for.body:
51 ; CHECK-NEXT:     Memory dependences are safe
52 ; CHECK-NEXT:     Dependences:
53 ; CHECK-NEXT:     Run-time memory checks:
55 define i32 @nodep_Write_Read(ptr nocapture %A) {
56 entry:
57   br label %for.body
59 for.cond.cleanup:                                 ; preds = %for.body
60   ret i32 %add3
62 for.body:                                         ; preds = %entry, %for.body
63   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
64   %sum.013 = phi i32 [ 0, %entry ], [ %add3, %for.body ]
65   %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv
66   %0 = trunc i64 %indvars.iv to i32
67   store i32 %0, ptr %arrayidx, align 4
68   %1 = or disjoint i64 %indvars.iv, 3
69   %arrayidx2 = getelementptr inbounds i32, ptr %A, i64 %1
70   %2 = load i32, ptr %arrayidx2, align 4
71   %add3 = add nsw i32 %2, %sum.013
72   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 4
73   %cmp = icmp ult i64 %indvars.iv.next, 1024
74   br i1 %cmp, label %for.body, label %for.cond.cleanup
77 ; void nodep_Write_Write(int *A) {
78 ;   for (unsigned i = 0; i < 1024; i+=2) {
79 ;     A[i] = i;
80 ;     A[i+1] = i+1;
81 ;   }
82 ; }
84 ; CHECK: function 'nodep_Write_Write':
85 ; CHECK-NEXT:   for.body:
86 ; CHECK-NEXT:     Memory dependences are safe
87 ; CHECK-NEXT:     Dependences:
88 ; CHECK-NEXT:     Run-time memory checks:
90 define void @nodep_Write_Write(ptr nocapture %A) {
91 entry:
92   br label %for.body
94 for.cond.cleanup:                                 ; preds = %for.body
95   ret void
97 for.body:                                         ; preds = %entry, %for.body
98   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
99   %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv
100   %0 = trunc i64 %indvars.iv to i32
101   store i32 %0, ptr %arrayidx, align 4
102   %1 = or disjoint i64 %indvars.iv, 1
103   %arrayidx3 = getelementptr inbounds i32, ptr %A, i64 %1
104   %2 = trunc i64 %1 to i32
105   store i32 %2, ptr %arrayidx3, align 4
106   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
107   %cmp = icmp ult i64 %indvars.iv.next, 1024
108   br i1 %cmp, label %for.body, label %for.cond.cleanup
111 ; Following cases are unsafe depdences and are not vectorizable.
113 ; void unsafe_Read_Write(int *A) {
114 ;   for (unsigned i = 0; i < 1024; i+=3)
115 ;     A[i+3] = A[i] + 1;
116 ; }
118 ; CHECK: function 'unsafe_Read_Write':
119 ; CHECK-NEXT:   for.body:
120 ; CHECK-NEXT:     Report: unsafe dependent memory operations in loop
121 ; CHECK-NEXT:     Backward loop carried data dependence.
122 ; CHECK-NEXT:     Dependences:
123 ; CHECK-NEXT:      Backward:
124 ; CHECK-NEXT:           %0 = load i32, ptr %arrayidx, align 4 -> 
125 ; CHECK-NEXT:           store i32 %add, ptr %arrayidx3, align 4
127 define void @unsafe_Read_Write(ptr nocapture %A) {
128 entry:
129   br label %for.body
131 for.cond.cleanup:                                 ; preds = %for.body
132   ret void
134 for.body:                                         ; preds = %entry, %for.body
135   %i.010 = phi i32 [ 0, %entry ], [ %add1, %for.body ]
136   %idxprom = zext i32 %i.010 to i64
137   %arrayidx = getelementptr inbounds i32, ptr %A, i64 %idxprom
138   %0 = load i32, ptr %arrayidx, align 4
139   %add = add nsw i32 %0, 1
140   %add1 = add i32 %i.010, 3
141   %idxprom2 = zext i32 %add1 to i64
142   %arrayidx3 = getelementptr inbounds i32, ptr %A, i64 %idxprom2
143   store i32 %add, ptr %arrayidx3, align 4
144   %cmp = icmp ult i32 %add1, 1024
145   br i1 %cmp, label %for.body, label %for.cond.cleanup
148 ; int unsafe_Write_Read(int *A) {
149 ;   int sum = 0;
150 ;   for (unsigned i = 0; i < 1024; i+=4) {
151 ;     A[i] = i;
152 ;     sum += A[i+4];
153 ;   }
155 ;   return sum;
156 ; }
158 ; CHECK: function 'unsafe_Write_Read':
159 ; CHECK-NEXT:   for.body:
160 ; CHECK-NEXT:     Report: unsafe dependent memory operations in loop
161 ; CHECK-NEXT:     Backward loop carried data dependence.
162 ; CHECK-NEXT:     Dependences:
163 ; CHECK-NEXT:      Backward:
164 ; CHECK-NEXT:           store i32 %0, ptr %arrayidx, align 4 ->
165 ; CHECK-NEXT:           %1 = load i32, ptr %arrayidx2, align 4
167 define i32 @unsafe_Write_Read(ptr nocapture %A) {
168 entry:
169   br label %for.body
171 for.cond.cleanup:                                 ; preds = %for.body
172   ret i32 %add3
174 for.body:                                         ; preds = %entry, %for.body
175   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
176   %sum.013 = phi i32 [ 0, %entry ], [ %add3, %for.body ]
177   %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv
178   %0 = trunc i64 %indvars.iv to i32
179   store i32 %0, ptr %arrayidx, align 4
180   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 4
181   %arrayidx2 = getelementptr inbounds i32, ptr %A, i64 %indvars.iv.next
182   %1 = load i32, ptr %arrayidx2, align 4
183   %add3 = add nsw i32 %1, %sum.013
184   %cmp = icmp ult i64 %indvars.iv.next, 1024
185   br i1 %cmp, label %for.body, label %for.cond.cleanup
188 ; void unsafe_Write_Write(int *A) {
189 ;   for (unsigned i = 0; i < 1024; i+=2) {
190 ;     A[i] = i;
191 ;     A[i+2] = i+1;
192 ;   }
193 ; }
195 ; CHECK: function 'unsafe_Write_Write':
196 ; CHECK-NEXT:   for.body:
197 ; CHECK-NEXT:     Report: unsafe dependent memory operations in loop
198 ; CHECK-NEXT:     Backward loop carried data dependence.
199 ; CHECK-NEXT:     Dependences:
200 ; CHECK-NEXT:      Backward:
201 ; CHECK-NEXT:           store i32 %0, ptr %arrayidx, align 4 ->
202 ; CHECK-NEXT:           store i32 %2, ptr %arrayidx3, align 4
204 define void @unsafe_Write_Write(ptr nocapture %A) {
205 entry:
206   br label %for.body
208 for.cond.cleanup:                                 ; preds = %for.body
209   ret void
211 for.body:                                         ; preds = %entry, %for.body
212   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
213   %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv
214   %0 = trunc i64 %indvars.iv to i32
215   store i32 %0, ptr %arrayidx, align 4
216   %1 = or disjoint i64 %indvars.iv, 1
217   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
218   %arrayidx3 = getelementptr inbounds i32, ptr %A, i64 %indvars.iv.next
219   %2 = trunc i64 %1 to i32
220   store i32 %2, ptr %arrayidx3, align 4
221   %cmp = icmp ult i64 %indvars.iv.next, 1024
222   br i1 %cmp, label %for.body, label %for.cond.cleanup
225 ; Following cases check that strided accesses can be vectorized.
227 ; void vectorizable_Read_Write(int *A) {
228 ;   int *B = A + 4;
229 ;   for (unsigned i = 0; i < 1024; i+=2)
230 ;     B[i] = A[i] + 1;
231 ; }
233 ; CHECK: function 'vectorizable_Read_Write':
234 ; CHECK-NEXT:   for.body:
235 ; CHECK-NEXT:     Memory dependences are safe
236 ; CHECK-NEXT:     Dependences:
237 ; CHECK-NEXT:       BackwardVectorizable:
238 ; CHECK-NEXT:           %0 = load i32, ptr %arrayidx, align 4 ->
239 ; CHECK-NEXT:           store i32 %add, ptr %arrayidx2, align 4
241 define void @vectorizable_Read_Write(ptr nocapture %A) {
242 entry:
243   %add.ptr = getelementptr inbounds i32, ptr %A, i64 4
244   br label %for.body
246 for.cond.cleanup:                                 ; preds = %for.body
247   ret void
249 for.body:                                         ; preds = %entry, %for.body
250   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
251   %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv
252   %0 = load i32, ptr %arrayidx, align 4
253   %add = add nsw i32 %0, 1
254   %arrayidx2 = getelementptr inbounds i32, ptr %add.ptr, i64 %indvars.iv
255   store i32 %add, ptr %arrayidx2, align 4
256   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
257   %cmp = icmp ult i64 %indvars.iv.next, 1024
258   br i1 %cmp, label %for.body, label %for.cond.cleanup
261 ; int vectorizable_Write_Read(int *A) {
262 ;   int *B = A + 4;
263 ;   int sum = 0;
264 ;   for (unsigned i = 0; i < 1024; i+=2) {
265 ;     A[i] = i;
266 ;     sum += B[i];
267 ;   }
268 ;   
269 ;   return sum;
270 ; }
272 ; CHECK: function 'vectorizable_Write_Read':
273 ; CHECK-NEXT:   for.body:
274 ; CHECK-NEXT:     Memory dependences are safe
275 ; CHECK-NEXT:     Dependences:
276 ; CHECK-NEXT:       BackwardVectorizable:
277 ; CHECK-NEXT:           store i32 %0, ptr %arrayidx, align 4 ->
278 ; CHECK-NEXT:           %1 = load i32, ptr %arrayidx2, align 4
280 define i32 @vectorizable_Write_Read(ptr nocapture %A) {
281 entry:
282   %add.ptr = getelementptr inbounds i32, ptr %A, i64 4
283   br label %for.body
285 for.cond.cleanup:                                 ; preds = %for.body
286   ret i32 %add
288 for.body:                                         ; preds = %entry, %for.body
289   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
290   %sum.013 = phi i32 [ 0, %entry ], [ %add, %for.body ]
291   %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv
292   %0 = trunc i64 %indvars.iv to i32
293   store i32 %0, ptr %arrayidx, align 4
294   %arrayidx2 = getelementptr inbounds i32, ptr %add.ptr, i64 %indvars.iv
295   %1 = load i32, ptr %arrayidx2, align 4
296   %add = add nsw i32 %1, %sum.013
297   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
298   %cmp = icmp ult i64 %indvars.iv.next, 1024
299   br i1 %cmp, label %for.body, label %for.cond.cleanup
302 ; void vectorizable_Write_Write(int *A) {
303 ;   int *B = A + 4;
304 ;   for (unsigned i = 0; i < 1024; i+=2) {
305 ;     A[i] = i;
306 ;     B[i] = i+1;
307 ;   }
308 ; }
310 ; CHECK: function 'vectorizable_Write_Write':
311 ; CHECK-NEXT:   for.body:
312 ; CHECK-NEXT:     Memory dependences are safe
313 ; CHECK-NEXT:     Dependences:
314 ; CHECK-NEXT:       BackwardVectorizable:
315 ; CHECK-NEXT:           store i32 %0, ptr %arrayidx, align 4 -> 
316 ; CHECK-NEXT:           store i32 %2, ptr %arrayidx2, align 4
318 define void @vectorizable_Write_Write(ptr nocapture %A) {
319 entry:
320   %add.ptr = getelementptr inbounds i32, ptr %A, i64 4
321   br label %for.body
323 for.cond.cleanup:                                 ; preds = %for.body
324   ret void
326 for.body:                                         ; preds = %entry, %for.body
327   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
328   %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv
329   %0 = trunc i64 %indvars.iv to i32
330   store i32 %0, ptr %arrayidx, align 4
331   %1 = or disjoint i64 %indvars.iv, 1
332   %arrayidx2 = getelementptr inbounds i32, ptr %add.ptr, i64 %indvars.iv
333   %2 = trunc i64 %1 to i32
334   store i32 %2, ptr %arrayidx2, align 4
335   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
336   %cmp = icmp ult i64 %indvars.iv.next, 1024
337   br i1 %cmp, label %for.body, label %for.cond.cleanup
340 ; void vectorizable_unscaled_Read_Write(int *A) {
341 ;   int *B = (int *)((char *)A + 14);
342 ;   for (unsigned i = 0; i < 1024; i+=2)
343 ;     B[i] = A[i] + 1;
344 ; }
346 ; FIXME: This case looks like previous case @vectorizable_Read_Write. It sould
347 ; be vectorizable.
349 ; CHECK: function 'vectorizable_unscaled_Read_Write':
350 ; CHECK-NEXT:   for.body:
351 ; CHECK-NEXT:     Report: unsafe dependent memory operations in loop
352 ; CHECK-NEXT:     Backward loop carried data dependence that prevents store-to-load forwarding.
353 ; CHECK-NEXT:     Dependences:
354 ; CHECK-NEXT:       BackwardVectorizableButPreventsForwarding:
355 ; CHECK-NEXT:           %0 = load i32, ptr %arrayidx, align 4 ->
356 ; CHECK-NEXT:           store i32 %add, ptr %arrayidx2, align 4
358 define void @vectorizable_unscaled_Read_Write(ptr nocapture %A) {
359 entry:
360   %add.ptr = getelementptr inbounds i8, ptr %A, i64 14
361   br label %for.body
363 for.cond.cleanup:                                 ; preds = %for.body
364   ret void
366 for.body:                                         ; preds = %entry, %for.body
367   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
368   %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv
369   %0 = load i32, ptr %arrayidx, align 4
370   %add = add nsw i32 %0, 1
371   %arrayidx2 = getelementptr inbounds i32, ptr %add.ptr, i64 %indvars.iv
372   store i32 %add, ptr %arrayidx2, align 4
373   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
374   %cmp = icmp ult i64 %indvars.iv.next, 1024
375   br i1 %cmp, label %for.body, label %for.cond.cleanup
378 ; int vectorizable_unscaled_Write_Read(int *A) {
379 ;   int *B = (int *)((char *)A + 17);
380 ;   int sum = 0;
381 ;   for (unsigned i = 0; i < 1024; i+=2) {
382 ;     A[i] = i;
383 ;     sum += B[i];
384 ;   }
386 ;   return sum;
387 ; }
389 ; CHECK: function 'vectorizable_unscaled_Write_Read':
390 ; CHECK-NEXT:   for.body:
391 ; CHECK-NEXT:     Memory dependences are safe
392 ; CHECK-NEXT:     Dependences:
393 ; CHECK-NEXT:       BackwardVectorizable:
394 ; CHECK-NEXT:           store i32 %0, ptr %arrayidx, align 4 -> 
395 ; CHECK-NEXT:           %1 = load i32, ptr %arrayidx2, align 4
397 define i32 @vectorizable_unscaled_Write_Read(ptr nocapture %A) {
398 entry:
399   %add.ptr = getelementptr inbounds i8, ptr %A, i64 17
400   br label %for.body
402 for.cond.cleanup:                                 ; preds = %for.body
403   ret i32 %add
405 for.body:                                         ; preds = %entry, %for.body
406   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
407   %sum.013 = phi i32 [ 0, %entry ], [ %add, %for.body ]
408   %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv
409   %0 = trunc i64 %indvars.iv to i32
410   store i32 %0, ptr %arrayidx, align 4
411   %arrayidx2 = getelementptr inbounds i32, ptr %add.ptr, i64 %indvars.iv
412   %1 = load i32, ptr %arrayidx2, align 4
413   %add = add nsw i32 %1, %sum.013
414   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
415   %cmp = icmp ult i64 %indvars.iv.next, 1024
416   br i1 %cmp, label %for.body, label %for.cond.cleanup
419 ; void unsafe_unscaled_Read_Write(int *A) {
420 ;   int *B = (int *)((char *)A + 11);
421 ;   for (unsigned i = 0; i < 1024; i+=2)
422 ;     B[i] = A[i] + 1;
423 ; }
425 ; CHECK: function 'unsafe_unscaled_Read_Write':
426 ; CHECK-NEXT:   for.body:
427 ; CHECK-NEXT:     Report: unsafe dependent memory operations in loop
428 ; CHECK-NEXT:     Backward loop carried data dependence.
429 ; CHECK-NEXT:     Dependences:
430 ; CHECK-NEXT:       Backward:
431 ; CHECK-NEXT:           %0 = load i32, ptr %arrayidx, align 4 -> 
432 ; CHECK-NEXT:           store i32 %add, ptr %arrayidx2, align 4
434 define void @unsafe_unscaled_Read_Write(ptr nocapture %A) {
435 entry:
436   %add.ptr = getelementptr inbounds i8, ptr %A, i64 11
437   br label %for.body
439 for.cond.cleanup:                                 ; preds = %for.body
440   ret void
442 for.body:                                         ; preds = %entry, %for.body
443   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
444   %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv
445   %0 = load i32, ptr %arrayidx, align 4
446   %add = add nsw i32 %0, 1
447   %arrayidx2 = getelementptr inbounds i32, ptr %add.ptr, i64 %indvars.iv
448   store i32 %add, ptr %arrayidx2, align 4
449   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
450   %cmp = icmp ult i64 %indvars.iv.next, 1024
451   br i1 %cmp, label %for.body, label %for.cond.cleanup
454 ; CHECK: function 'unsafe_unscaled_Read_Write2':
455 ; CHECK-NEXT:   for.body:
456 ; CHECK-NEXT:     Report: unsafe dependent memory operations in loop
457 ; CHECK-NEXT:     Backward loop carried data dependence.
458 ; CHECK-NEXT:     Dependences:
459 ; CHECK-NEXT:       Backward:
460 ; CHECK-NEXT:           %0 = load i32, ptr %arrayidx, align 4 -> 
461 ; CHECK-NEXT:           store i32 %add, ptr %arrayidx2, align 4
463 ; void unsafe_unscaled_Read_Write2(int *A) {
464 ;   int *B = (int *)((char *)A + 1);
465 ;   for (unsigned i = 0; i < 1024; i+=2)
466 ;     B[i] = A[i] + 1;
467 ; }
469 define void @unsafe_unscaled_Read_Write2(ptr nocapture %A) {
470 entry:
471   %add.ptr = getelementptr inbounds i8, ptr %A, i64 1
472   br label %for.body
474 for.cond.cleanup:                                 ; preds = %for.body
475   ret void
477 for.body:                                         ; preds = %entry, %for.body
478   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
479   %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv
480   %0 = load i32, ptr %arrayidx, align 4
481   %add = add nsw i32 %0, 1
482   %arrayidx2 = getelementptr inbounds i32, ptr %add.ptr, i64 %indvars.iv
483   store i32 %add, ptr %arrayidx2, align 4
484   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
485   %cmp = icmp ult i64 %indvars.iv.next, 1024
486   br i1 %cmp, label %for.body, label %for.cond.cleanup
489 ; Following case checks that interleaved stores have dependences with another
490 ; store and can not pass dependence check.
492 ; void interleaved_stores(int *A) {
493 ;   int *B = (int *) ((char *)A + 1);
494 ;   for(int i = 0; i < 1024; i+=2) {
495 ;     B[i]   = i;                // (1)
496 ;     A[i+1] = i + 1;            // (2)
497 ;     B[i+1] = i + 1;            // (3)
498 ;   }
499 ; }
501 ; The access (2) has overlaps with (1) and (3).
503 ; CHECK: function 'interleaved_stores':
504 ; CHECK-NEXT:   for.body:
505 ; CHECK-NEXT:     Report: unsafe dependent memory operations in loop
506 ; CHECK-NEXT:     Backward loop carried data dependence.
507 ; CHECK-NEXT:     Dependences:
508 ; CHECK-NEXT:       Backward:
509 ; CHECK-NEXT:           store i32 %2, ptr %arrayidx5, align 4 -> 
510 ; CHECK-NEXT:           store i32 %2, ptr %arrayidx9, align 4
511 ; CHECK:       Backward:
512 ; CHECK-NEXT:           store i32 %0, ptr %arrayidx2, align 4 -> 
513 ; CHECK-NEXT:           store i32 %2, ptr %arrayidx5, align 4
515 define void @interleaved_stores(ptr nocapture %A) {
516 entry:
517   %incdec.ptr = getelementptr inbounds i8, ptr %A, i64 1
518   br label %for.body
520 for.cond.cleanup:                                 ; preds = %for.body
521   ret void
523 for.body:                                         ; preds = %entry, %for.body
524   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
525   %0 = trunc i64 %indvars.iv to i32
526   %arrayidx2 = getelementptr inbounds i32, ptr %incdec.ptr, i64 %indvars.iv
527   store i32 %0, ptr %arrayidx2, align 4
528   %1 = or disjoint i64 %indvars.iv, 1
529   %arrayidx5 = getelementptr inbounds i32, ptr %A, i64 %1
530   %2 = trunc i64 %1 to i32
531   store i32 %2, ptr %arrayidx5, align 4
532   %arrayidx9 = getelementptr inbounds i32, ptr %incdec.ptr, i64 %1
533   store i32 %2, ptr %arrayidx9, align 4
534   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
535   %cmp = icmp slt i64 %indvars.iv.next, 1024
536   br i1 %cmp, label %for.body, label %for.cond.cleanup