[LAA] Revert a small part of r239295
[oota-llvm.git] / test / Analysis / LoopAccessAnalysis / stride-access-dependence.ll
1 ; RUN: opt -loop-accesses -analyze < %s | FileCheck %s
2
3 target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"
4
5 ; Following cases are no dependence.
6
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 ; }
12
13 ; CHECK: function 'nodep_Read_Write':
14 ; CHECK-NEXT:   for.body:
15 ; CHECK-NEXT:     Memory dependences are safe
16 ; CHECK-NEXT:     Interesting Dependences:
17 ; CHECK-NEXT:     Run-time memory checks:
18
19 define void @nodep_Read_Write(i32* nocapture %A) {
20 entry:
21   %add.ptr = getelementptr inbounds i32, i32* %A, i64 1
22   br label %for.body
23
24 for.cond.cleanup:                                 ; preds = %for.body
25   ret void
26
27 for.body:                                         ; preds = %entry, %for.body
28   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
29   %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
30   %0 = load i32, i32* %arrayidx, align 4
31   %add = add nsw i32 %0, 1
32   %arrayidx2 = getelementptr inbounds i32, i32* %add.ptr, i64 %indvars.iv
33   store i32 %add, i32* %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
37 }
38
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 ; }
48
49 ; CHECK: function 'nodep_Write_Read':
50 ; CHECK-NEXT:   for.body:
51 ; CHECK-NEXT:     Memory dependences are safe
52 ; CHECK-NEXT:     Interesting Dependences:
53 ; CHECK-NEXT:     Run-time memory checks:
54
55 define i32 @nodep_Write_Read(i32* nocapture %A) {
56 entry:
57   br label %for.body
58
59 for.cond.cleanup:                                 ; preds = %for.body
60   ret i32 %add3
61
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, i32* %A, i64 %indvars.iv
66   %0 = trunc i64 %indvars.iv to i32
67   store i32 %0, i32* %arrayidx, align 4
68   %1 = or i64 %indvars.iv, 3
69   %arrayidx2 = getelementptr inbounds i32, i32* %A, i64 %1
70   %2 = load i32, i32* %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
75 }
76
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 ; }
83
84 ; CHECK: function 'nodep_Write_Write':
85 ; CHECK-NEXT:   for.body:
86 ; CHECK-NEXT:     Memory dependences are safe
87 ; CHECK-NEXT:     Interesting Dependences:
88 ; CHECK-NEXT:     Run-time memory checks:
89
90 define void @nodep_Write_Write(i32* nocapture %A) {
91 entry:
92   br label %for.body
93
94 for.cond.cleanup:                                 ; preds = %for.body
95   ret void
96
97 for.body:                                         ; preds = %entry, %for.body
98   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
99   %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
100   %0 = trunc i64 %indvars.iv to i32
101   store i32 %0, i32* %arrayidx, align 4
102   %1 = or i64 %indvars.iv, 1
103   %arrayidx3 = getelementptr inbounds i32, i32* %A, i64 %1
104   %2 = trunc i64 %1 to i32
105   store i32 %2, i32* %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
109 }
110
111 ; Following cases are unsafe depdences and are not vectorizable.
112
113 ; void unsafe_Read_Write(int *A) {
114 ;   for (unsigned i = 0; i < 1024; i+=3)
115 ;     A[i+3] = A[i] + 1;
116 ; }
117
118 ; CHECK: function 'unsafe_Read_Write':
119 ; CHECK-NEXT:   for.body:
120 ; CHECK-NEXT:     Report: unsafe dependent memory operations in loop
121 ; CHECK-NEXT:     Interesting Dependences:
122 ; CHECK-NEXT:      Backward:
123 ; CHECK-NEXT:           %0 = load i32, i32* %arrayidx, align 4 -> 
124 ; CHECK-NEXT:           store i32 %add, i32* %arrayidx3, align 4
125
126 define void @unsafe_Read_Write(i32* nocapture %A) {
127 entry:
128   br label %for.body
129
130 for.cond.cleanup:                                 ; preds = %for.body
131   ret void
132
133 for.body:                                         ; preds = %entry, %for.body
134   %i.010 = phi i32 [ 0, %entry ], [ %add1, %for.body ]
135   %idxprom = zext i32 %i.010 to i64
136   %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom
137   %0 = load i32, i32* %arrayidx, align 4
138   %add = add nsw i32 %0, 1
139   %add1 = add i32 %i.010, 3
140   %idxprom2 = zext i32 %add1 to i64
141   %arrayidx3 = getelementptr inbounds i32, i32* %A, i64 %idxprom2
142   store i32 %add, i32* %arrayidx3, align 4
143   %cmp = icmp ult i32 %add1, 1024
144   br i1 %cmp, label %for.body, label %for.cond.cleanup
145 }
146
147 ; int unsafe_Write_Read(int *A) {
148 ;   int sum = 0;
149 ;   for (unsigned i = 0; i < 1024; i+=4) {
150 ;     A[i] = i;
151 ;     sum += A[i+4];
152 ;   }
153 ;
154 ;   return sum;
155 ; }
156
157 ; CHECK: function 'unsafe_Write_Read':
158 ; CHECK-NEXT:   for.body:
159 ; CHECK-NEXT:     Report: unsafe dependent memory operations in loop
160 ; CHECK-NEXT:     Interesting Dependences:
161 ; CHECK-NEXT:      Backward:
162 ; CHECK-NEXT:           store i32 %0, i32* %arrayidx, align 4 ->
163 ; CHECK-NEXT:           %1 = load i32, i32* %arrayidx2, align 4
164
165 define i32 @unsafe_Write_Read(i32* nocapture %A) {
166 entry:
167   br label %for.body
168
169 for.cond.cleanup:                                 ; preds = %for.body
170   ret i32 %add3
171
172 for.body:                                         ; preds = %entry, %for.body
173   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
174   %sum.013 = phi i32 [ 0, %entry ], [ %add3, %for.body ]
175   %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
176   %0 = trunc i64 %indvars.iv to i32
177   store i32 %0, i32* %arrayidx, align 4
178   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 4
179   %arrayidx2 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv.next
180   %1 = load i32, i32* %arrayidx2, align 4
181   %add3 = add nsw i32 %1, %sum.013
182   %cmp = icmp ult i64 %indvars.iv.next, 1024
183   br i1 %cmp, label %for.body, label %for.cond.cleanup
184 }
185
186 ; void unsafe_Write_Write(int *A) {
187 ;   for (unsigned i = 0; i < 1024; i+=2) {
188 ;     A[i] = i;
189 ;     A[i+2] = i+1;
190 ;   }
191 ; }
192
193 ; CHECK: function 'unsafe_Write_Write':
194 ; CHECK-NEXT:   for.body:
195 ; CHECK-NEXT:     Report: unsafe dependent memory operations in loop
196 ; CHECK-NEXT:     Interesting Dependences:
197 ; CHECK-NEXT:      Backward:
198 ; CHECK-NEXT:           store i32 %0, i32* %arrayidx, align 4 ->
199 ; CHECK-NEXT:           store i32 %2, i32* %arrayidx3, align 4
200
201 define void @unsafe_Write_Write(i32* nocapture %A) {
202 entry:
203   br label %for.body
204
205 for.cond.cleanup:                                 ; preds = %for.body
206   ret void
207
208 for.body:                                         ; preds = %entry, %for.body
209   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
210   %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
211   %0 = trunc i64 %indvars.iv to i32
212   store i32 %0, i32* %arrayidx, align 4
213   %1 = or i64 %indvars.iv, 1
214   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
215   %arrayidx3 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv.next
216   %2 = trunc i64 %1 to i32
217   store i32 %2, i32* %arrayidx3, align 4
218   %cmp = icmp ult i64 %indvars.iv.next, 1024
219   br i1 %cmp, label %for.body, label %for.cond.cleanup
220 }
221
222 ; Following cases check that strided accesses can be vectorized.
223
224 ; void vectorizable_Read_Write(int *A) {
225 ;   int *B = A + 4;
226 ;   for (unsigned i = 0; i < 1024; i+=2)
227 ;     B[i] = A[i] + 1;
228 ; }
229
230 ; CHECK: function 'vectorizable_Read_Write':
231 ; CHECK-NEXT:   for.body:
232 ; CHECK-NEXT:     Memory dependences are safe
233 ; CHECK-NEXT:     Interesting Dependences:
234 ; CHECK-NEXT:       BackwardVectorizable:
235 ; CHECK-NEXT:           %0 = load i32, i32* %arrayidx, align 4 ->
236 ; CHECK-NEXT:           store i32 %add, i32* %arrayidx2, align 4
237
238 define void @vectorizable_Read_Write(i32* nocapture %A) {
239 entry:
240   %add.ptr = getelementptr inbounds i32, i32* %A, i64 4
241   br label %for.body
242
243 for.cond.cleanup:                                 ; preds = %for.body
244   ret void
245
246 for.body:                                         ; preds = %entry, %for.body
247   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
248   %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
249   %0 = load i32, i32* %arrayidx, align 4
250   %add = add nsw i32 %0, 1
251   %arrayidx2 = getelementptr inbounds i32, i32* %add.ptr, i64 %indvars.iv
252   store i32 %add, i32* %arrayidx2, align 4
253   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
254   %cmp = icmp ult i64 %indvars.iv.next, 1024
255   br i1 %cmp, label %for.body, label %for.cond.cleanup
256 }
257
258 ; int vectorizable_Write_Read(int *A) {
259 ;   int *B = A + 4;
260 ;   int sum = 0;
261 ;   for (unsigned i = 0; i < 1024; i+=2) {
262 ;     A[i] = i;
263 ;     sum += B[i];
264 ;   }
265 ;   
266 ;   return sum;
267 ; }
268
269 ; CHECK: function 'vectorizable_Write_Read':
270 ; CHECK-NEXT:   for.body:
271 ; CHECK-NEXT:     Memory dependences are safe
272 ; CHECK-NEXT:     Interesting Dependences:
273 ; CHECK-NEXT:       BackwardVectorizable:
274 ; CHECK-NEXT:           store i32 %0, i32* %arrayidx, align 4 ->
275 ; CHECK-NEXT:           %1 = load i32, i32* %arrayidx2, align 4
276
277 define i32 @vectorizable_Write_Read(i32* nocapture %A) {
278 entry:
279   %add.ptr = getelementptr inbounds i32, i32* %A, i64 4
280   br label %for.body
281
282 for.cond.cleanup:                                 ; preds = %for.body
283   ret i32 %add
284
285 for.body:                                         ; preds = %entry, %for.body
286   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
287   %sum.013 = phi i32 [ 0, %entry ], [ %add, %for.body ]
288   %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
289   %0 = trunc i64 %indvars.iv to i32
290   store i32 %0, i32* %arrayidx, align 4
291   %arrayidx2 = getelementptr inbounds i32, i32* %add.ptr, i64 %indvars.iv
292   %1 = load i32, i32* %arrayidx2, align 4
293   %add = add nsw i32 %1, %sum.013
294   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
295   %cmp = icmp ult i64 %indvars.iv.next, 1024
296   br i1 %cmp, label %for.body, label %for.cond.cleanup
297 }
298
299 ; void vectorizable_Write_Write(int *A) {
300 ;   int *B = A + 4;
301 ;   for (unsigned i = 0; i < 1024; i+=2) {
302 ;     A[i] = i;
303 ;     B[i] = i+1;
304 ;   }
305 ; }
306
307 ; CHECK: function 'vectorizable_Write_Write':
308 ; CHECK-NEXT:   for.body:
309 ; CHECK-NEXT:     Memory dependences are safe
310 ; CHECK-NEXT:     Interesting Dependences:
311 ; CHECK-NEXT:       BackwardVectorizable:
312 ; CHECK-NEXT:           store i32 %0, i32* %arrayidx, align 4 -> 
313 ; CHECK-NEXT:           store i32 %2, i32* %arrayidx2, align 4
314
315 define void @vectorizable_Write_Write(i32* nocapture %A) {
316 entry:
317   %add.ptr = getelementptr inbounds i32, i32* %A, i64 4
318   br label %for.body
319
320 for.cond.cleanup:                                 ; preds = %for.body
321   ret void
322
323 for.body:                                         ; preds = %entry, %for.body
324   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
325   %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
326   %0 = trunc i64 %indvars.iv to i32
327   store i32 %0, i32* %arrayidx, align 4
328   %1 = or i64 %indvars.iv, 1
329   %arrayidx2 = getelementptr inbounds i32, i32* %add.ptr, i64 %indvars.iv
330   %2 = trunc i64 %1 to i32
331   store i32 %2, i32* %arrayidx2, align 4
332   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
333   %cmp = icmp ult i64 %indvars.iv.next, 1024
334   br i1 %cmp, label %for.body, label %for.cond.cleanup
335 }
336
337 ; void vectorizable_unscaled_Read_Write(int *A) {
338 ;   int *B = (int *)((char *)A + 14);
339 ;   for (unsigned i = 0; i < 1024; i+=2)
340 ;     B[i] = A[i] + 1;
341 ; }
342
343 ; FIXME: This case looks like previous case @vectorizable_Read_Write. It sould
344 ; be vectorizable.
345
346 ; CHECK: function 'vectorizable_unscaled_Read_Write':
347 ; CHECK-NEXT:   for.body:
348 ; CHECK-NEXT:     Report: unsafe dependent memory operations in loop
349 ; CHECK-NEXT:     Interesting Dependences:
350 ; CHECK-NEXT:       BackwardVectorizableButPreventsForwarding:
351 ; CHECK-NEXT:           %2 = load i32, i32* %arrayidx, align 4 ->
352 ; CHECK-NEXT:           store i32 %add, i32* %arrayidx2, align 4
353
354 define void @vectorizable_unscaled_Read_Write(i32* nocapture %A) {
355 entry:
356   %0 = bitcast i32* %A to i8*
357   %add.ptr = getelementptr inbounds i8, i8* %0, i64 14
358   %1 = bitcast i8* %add.ptr to i32*
359   br label %for.body
360
361 for.cond.cleanup:                                 ; preds = %for.body
362   ret void
363
364 for.body:                                         ; preds = %entry, %for.body
365   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
366   %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
367   %2 = load i32, i32* %arrayidx, align 4
368   %add = add nsw i32 %2, 1
369   %arrayidx2 = getelementptr inbounds i32, i32* %1, i64 %indvars.iv
370   store i32 %add, i32* %arrayidx2, align 4
371   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
372   %cmp = icmp ult i64 %indvars.iv.next, 1024
373   br i1 %cmp, label %for.body, label %for.cond.cleanup
374 }
375
376 ; int vectorizable_unscaled_Write_Read(int *A) {
377 ;   int *B = (int *)((char *)A + 17);
378 ;   int sum = 0;
379 ;   for (unsigned i = 0; i < 1024; i+=2) {
380 ;     A[i] = i;
381 ;     sum += B[i];
382 ;   }
383
384 ;   return sum;
385 ; }
386
387 ; CHECK: for function 'vectorizable_unscaled_Write_Read':
388 ; CHECK-NEXT:   for.body:
389 ; CHECK-NEXT:     Memory dependences are safe
390 ; CHECK-NEXT:     Interesting Dependences:
391 ; CHECK-NEXT:       BackwardVectorizable:
392 ; CHECK-NEXT:           store i32 %2, i32* %arrayidx, align 4 -> 
393 ; CHECK-NEXT:           %3 = load i32, i32* %arrayidx2, align 4
394
395 define i32 @vectorizable_unscaled_Write_Read(i32* nocapture %A) {
396 entry:
397   %0 = bitcast i32* %A to i8*
398   %add.ptr = getelementptr inbounds i8, i8* %0, i64 17
399   %1 = bitcast i8* %add.ptr to i32*
400   br label %for.body
401
402 for.cond.cleanup:                                 ; preds = %for.body
403   ret i32 %add
404
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, i32* %A, i64 %indvars.iv
409   %2 = trunc i64 %indvars.iv to i32
410   store i32 %2, i32* %arrayidx, align 4
411   %arrayidx2 = getelementptr inbounds i32, i32* %1, i64 %indvars.iv
412   %3 = load i32, i32* %arrayidx2, align 4
413   %add = add nsw i32 %3, %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
417 }
418
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 ; }
424
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:     Interesting Dependences:
429 ; CHECK-NEXT:       Backward:
430 ; CHECK-NEXT:           %2 = load i32, i32* %arrayidx, align 4 -> 
431 ; CHECK-NEXT:           store i32 %add, i32* %arrayidx2, align 4
432
433 define void @unsafe_unscaled_Read_Write(i32* nocapture %A) {
434 entry:
435   %0 = bitcast i32* %A to i8*
436   %add.ptr = getelementptr inbounds i8, i8* %0, i64 11
437   %1 = bitcast i8* %add.ptr to i32*
438   br label %for.body
439
440 for.cond.cleanup:                                 ; preds = %for.body
441   ret void
442
443 for.body:                                         ; preds = %entry, %for.body
444   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
445   %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
446   %2 = load i32, i32* %arrayidx, align 4
447   %add = add nsw i32 %2, 1
448   %arrayidx2 = getelementptr inbounds i32, i32* %1, i64 %indvars.iv
449   store i32 %add, i32* %arrayidx2, align 4
450   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
451   %cmp = icmp ult i64 %indvars.iv.next, 1024
452   br i1 %cmp, label %for.body, label %for.cond.cleanup
453 }
454
455 ; CHECK: function 'unsafe_unscaled_Read_Write2':
456 ; CHECK-NEXT:   for.body:
457 ; CHECK-NEXT:     Report: unsafe dependent memory operations in loop
458 ; CHECK-NEXT:     Interesting Dependences:
459 ; CHECK-NEXT:       Backward:
460 ; CHECK-NEXT:           %2 = load i32, i32* %arrayidx, align 4 -> 
461 ; CHECK-NEXT:           store i32 %add, i32* %arrayidx2, align 4
462
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 ; }
468
469 define void @unsafe_unscaled_Read_Write2(i32* nocapture %A) {
470 entry:
471   %0 = bitcast i32* %A to i8*
472   %add.ptr = getelementptr inbounds i8, i8* %0, i64 1
473   %1 = bitcast i8* %add.ptr to i32*
474   br label %for.body
475
476 for.cond.cleanup:                                 ; preds = %for.body
477   ret void
478
479 for.body:                                         ; preds = %entry, %for.body
480   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
481   %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
482   %2 = load i32, i32* %arrayidx, align 4
483   %add = add nsw i32 %2, 1
484   %arrayidx2 = getelementptr inbounds i32, i32* %1, i64 %indvars.iv
485   store i32 %add, i32* %arrayidx2, align 4
486   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
487   %cmp = icmp ult i64 %indvars.iv.next, 1024
488   br i1 %cmp, label %for.body, label %for.cond.cleanup
489 }
490
491 ; Following case checks that interleaved stores have dependences with another
492 ; store and can not pass dependence check.
493
494 ; void interleaved_stores(int *A) {
495 ;   int *B = (int *) ((char *)A + 1);
496 ;   for(int i = 0; i < 1024; i+=2) {
497 ;     B[i]   = i;                // (1)
498 ;     A[i+1] = i + 1;            // (2)
499 ;     B[i+1] = i + 1;            // (3)
500 ;   }
501 ; }
502 ;
503 ; The access (2) has overlaps with (1) and (3).
504
505 ; CHECK: function 'interleaved_stores':
506 ; CHECK-NEXT:   for.body:
507 ; CHECK-NEXT:     Report: unsafe dependent memory operations in loop
508 ; CHECK-NEXT:     Interesting Dependences:
509 ; CHECK-NEXT:       Backward:
510 ; CHECK-NEXT:           store i32 %4, i32* %arrayidx5, align 4 -> 
511 ; CHECK-NEXT:           store i32 %4, i32* %arrayidx9, align 4
512 ; CHECK:       Backward:
513 ; CHECK-NEXT:           store i32 %2, i32* %arrayidx2, align 4 -> 
514 ; CHECK-NEXT:           store i32 %4, i32* %arrayidx5, align 4
515
516 define void @interleaved_stores(i32* nocapture %A) {
517 entry:
518   %0 = bitcast i32* %A to i8*
519   %incdec.ptr = getelementptr inbounds i8, i8* %0, i64 1
520   %1 = bitcast i8* %incdec.ptr to i32*
521   br label %for.body
522
523 for.cond.cleanup:                                 ; preds = %for.body
524   ret void
525
526 for.body:                                         ; preds = %entry, %for.body
527   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
528   %2 = trunc i64 %indvars.iv to i32
529   %arrayidx2 = getelementptr inbounds i32, i32* %1, i64 %indvars.iv
530   store i32 %2, i32* %arrayidx2, align 4
531   %3 = or i64 %indvars.iv, 1
532   %arrayidx5 = getelementptr inbounds i32, i32* %A, i64 %3
533   %4 = trunc i64 %3 to i32
534   store i32 %4, i32* %arrayidx5, align 4
535   %arrayidx9 = getelementptr inbounds i32, i32* %1, i64 %3
536   store i32 %4, i32* %arrayidx9, align 4
537   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
538   %cmp = icmp slt i64 %indvars.iv.next, 1024
539   br i1 %cmp, label %for.body, label %for.cond.cleanup
540 }