blob: 4fe6f9f704f7153509bc039ed70e6b7384b27942 [file] [log] [blame]
Hao Liu751004a2015-06-08 04:48:37 +00001; RUN: opt -loop-accesses -analyze < %s | FileCheck %s
Sean Silva284b0322016-07-07 01:01:53 +00002; RUN: opt -passes='require<scalar-evolution>,require<aa>,loop(print-access-info)' -disable-output < %s 2>&1 | FileCheck %s
Hao Liu751004a2015-06-08 04:48:37 +00003
4target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"
5
6; Following cases are no dependence.
7
8; void nodep_Read_Write(int *A) {
9; int *B = A + 1;
10; for (unsigned i = 0; i < 1024; i+=3)
11; B[i] = A[i] + 1;
12; }
13
14; CHECK: function 'nodep_Read_Write':
15; CHECK-NEXT: for.body:
16; CHECK-NEXT: Memory dependences are safe
Adam Nemeta2df7502015-11-03 21:39:52 +000017; CHECK-NEXT: Dependences:
Hao Liu751004a2015-06-08 04:48:37 +000018; CHECK-NEXT: Run-time memory checks:
19
20define void @nodep_Read_Write(i32* nocapture %A) {
21entry:
22 %add.ptr = getelementptr inbounds i32, i32* %A, i64 1
23 br label %for.body
24
25for.cond.cleanup: ; preds = %for.body
26 ret void
27
28for.body: ; preds = %entry, %for.body
29 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
30 %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
31 %0 = load i32, i32* %arrayidx, align 4
32 %add = add nsw i32 %0, 1
33 %arrayidx2 = getelementptr inbounds i32, i32* %add.ptr, i64 %indvars.iv
34 store i32 %add, i32* %arrayidx2, align 4
35 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 3
36 %cmp = icmp ult i64 %indvars.iv.next, 1024
37 br i1 %cmp, label %for.body, label %for.cond.cleanup
38}
39
40; int nodep_Write_Read(int *A) {
41; int sum = 0;
42; for (unsigned i = 0; i < 1024; i+=4) {
43; A[i] = i;
44; sum += A[i+3];
45; }
46;
47; return sum;
48; }
49
50; CHECK: function 'nodep_Write_Read':
51; CHECK-NEXT: for.body:
52; CHECK-NEXT: Memory dependences are safe
Adam Nemeta2df7502015-11-03 21:39:52 +000053; CHECK-NEXT: Dependences:
Hao Liu751004a2015-06-08 04:48:37 +000054; CHECK-NEXT: Run-time memory checks:
55
56define i32 @nodep_Write_Read(i32* nocapture %A) {
57entry:
58 br label %for.body
59
60for.cond.cleanup: ; preds = %for.body
61 ret i32 %add3
62
63for.body: ; preds = %entry, %for.body
64 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
65 %sum.013 = phi i32 [ 0, %entry ], [ %add3, %for.body ]
66 %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
67 %0 = trunc i64 %indvars.iv to i32
68 store i32 %0, i32* %arrayidx, align 4
69 %1 = or i64 %indvars.iv, 3
70 %arrayidx2 = getelementptr inbounds i32, i32* %A, i64 %1
71 %2 = load i32, i32* %arrayidx2, align 4
72 %add3 = add nsw i32 %2, %sum.013
73 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 4
74 %cmp = icmp ult i64 %indvars.iv.next, 1024
75 br i1 %cmp, label %for.body, label %for.cond.cleanup
76}
77
78; void nodep_Write_Write(int *A) {
79; for (unsigned i = 0; i < 1024; i+=2) {
80; A[i] = i;
81; A[i+1] = i+1;
82; }
83; }
84
85; CHECK: function 'nodep_Write_Write':
86; CHECK-NEXT: for.body:
87; CHECK-NEXT: Memory dependences are safe
Adam Nemeta2df7502015-11-03 21:39:52 +000088; CHECK-NEXT: Dependences:
Hao Liu751004a2015-06-08 04:48:37 +000089; CHECK-NEXT: Run-time memory checks:
90
91define void @nodep_Write_Write(i32* nocapture %A) {
92entry:
93 br label %for.body
94
95for.cond.cleanup: ; preds = %for.body
96 ret void
97
98for.body: ; preds = %entry, %for.body
99 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
100 %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
101 %0 = trunc i64 %indvars.iv to i32
102 store i32 %0, i32* %arrayidx, align 4
103 %1 = or i64 %indvars.iv, 1
104 %arrayidx3 = getelementptr inbounds i32, i32* %A, i64 %1
105 %2 = trunc i64 %1 to i32
106 store i32 %2, i32* %arrayidx3, align 4
107 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
108 %cmp = icmp ult i64 %indvars.iv.next, 1024
109 br i1 %cmp, label %for.body, label %for.cond.cleanup
110}
111
112; Following cases are unsafe depdences and are not vectorizable.
113
114; void unsafe_Read_Write(int *A) {
115; for (unsigned i = 0; i < 1024; i+=3)
116; A[i+3] = A[i] + 1;
117; }
118
119; CHECK: function 'unsafe_Read_Write':
120; CHECK-NEXT: for.body:
121; CHECK-NEXT: Report: unsafe dependent memory operations in loop
Adam Nemeta2df7502015-11-03 21:39:52 +0000122; CHECK-NEXT: Dependences:
Hao Liu751004a2015-06-08 04:48:37 +0000123; CHECK-NEXT: Backward:
124; CHECK-NEXT: %0 = load i32, i32* %arrayidx, align 4 ->
125; CHECK-NEXT: store i32 %add, i32* %arrayidx3, align 4
126
127define void @unsafe_Read_Write(i32* nocapture %A) {
128entry:
129 br label %for.body
130
131for.cond.cleanup: ; preds = %for.body
132 ret void
133
134for.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, i32* %A, i64 %idxprom
138 %0 = load i32, i32* %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, i32* %A, i64 %idxprom2
143 store i32 %add, i32* %arrayidx3, align 4
144 %cmp = icmp ult i32 %add1, 1024
145 br i1 %cmp, label %for.body, label %for.cond.cleanup
146}
147
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; }
154;
155; return sum;
156; }
157
158; CHECK: function 'unsafe_Write_Read':
159; CHECK-NEXT: for.body:
160; CHECK-NEXT: Report: unsafe dependent memory operations in loop
Adam Nemeta2df7502015-11-03 21:39:52 +0000161; CHECK-NEXT: Dependences:
Hao Liu751004a2015-06-08 04:48:37 +0000162; CHECK-NEXT: Backward:
163; CHECK-NEXT: store i32 %0, i32* %arrayidx, align 4 ->
164; CHECK-NEXT: %1 = load i32, i32* %arrayidx2, align 4
165
166define i32 @unsafe_Write_Read(i32* nocapture %A) {
167entry:
168 br label %for.body
169
170for.cond.cleanup: ; preds = %for.body
171 ret i32 %add3
172
173for.body: ; preds = %entry, %for.body
174 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
175 %sum.013 = phi i32 [ 0, %entry ], [ %add3, %for.body ]
176 %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
177 %0 = trunc i64 %indvars.iv to i32
178 store i32 %0, i32* %arrayidx, align 4
179 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 4
180 %arrayidx2 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv.next
181 %1 = load i32, i32* %arrayidx2, align 4
182 %add3 = add nsw i32 %1, %sum.013
183 %cmp = icmp ult i64 %indvars.iv.next, 1024
184 br i1 %cmp, label %for.body, label %for.cond.cleanup
185}
186
187; void unsafe_Write_Write(int *A) {
188; for (unsigned i = 0; i < 1024; i+=2) {
189; A[i] = i;
190; A[i+2] = i+1;
191; }
192; }
193
194; CHECK: function 'unsafe_Write_Write':
195; CHECK-NEXT: for.body:
196; CHECK-NEXT: Report: unsafe dependent memory operations in loop
Adam Nemeta2df7502015-11-03 21:39:52 +0000197; CHECK-NEXT: Dependences:
Hao Liu751004a2015-06-08 04:48:37 +0000198; CHECK-NEXT: Backward:
199; CHECK-NEXT: store i32 %0, i32* %arrayidx, align 4 ->
200; CHECK-NEXT: store i32 %2, i32* %arrayidx3, align 4
201
202define void @unsafe_Write_Write(i32* nocapture %A) {
203entry:
204 br label %for.body
205
206for.cond.cleanup: ; preds = %for.body
207 ret void
208
209for.body: ; preds = %entry, %for.body
210 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
211 %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
212 %0 = trunc i64 %indvars.iv to i32
213 store i32 %0, i32* %arrayidx, align 4
214 %1 = or i64 %indvars.iv, 1
215 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
216 %arrayidx3 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv.next
217 %2 = trunc i64 %1 to i32
218 store i32 %2, i32* %arrayidx3, align 4
219 %cmp = icmp ult i64 %indvars.iv.next, 1024
220 br i1 %cmp, label %for.body, label %for.cond.cleanup
221}
222
223; Following cases check that strided accesses can be vectorized.
224
225; void vectorizable_Read_Write(int *A) {
226; int *B = A + 4;
227; for (unsigned i = 0; i < 1024; i+=2)
228; B[i] = A[i] + 1;
229; }
230
231; CHECK: function 'vectorizable_Read_Write':
232; CHECK-NEXT: for.body:
233; CHECK-NEXT: Memory dependences are safe
Adam Nemeta2df7502015-11-03 21:39:52 +0000234; CHECK-NEXT: Dependences:
Hao Liu751004a2015-06-08 04:48:37 +0000235; CHECK-NEXT: BackwardVectorizable:
236; CHECK-NEXT: %0 = load i32, i32* %arrayidx, align 4 ->
237; CHECK-NEXT: store i32 %add, i32* %arrayidx2, align 4
238
239define void @vectorizable_Read_Write(i32* nocapture %A) {
240entry:
241 %add.ptr = getelementptr inbounds i32, i32* %A, i64 4
242 br label %for.body
243
244for.cond.cleanup: ; preds = %for.body
245 ret void
246
247for.body: ; preds = %entry, %for.body
248 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
249 %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
250 %0 = load i32, i32* %arrayidx, align 4
251 %add = add nsw i32 %0, 1
252 %arrayidx2 = getelementptr inbounds i32, i32* %add.ptr, i64 %indvars.iv
253 store i32 %add, i32* %arrayidx2, align 4
254 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
255 %cmp = icmp ult i64 %indvars.iv.next, 1024
256 br i1 %cmp, label %for.body, label %for.cond.cleanup
257}
258
259; int vectorizable_Write_Read(int *A) {
260; int *B = A + 4;
261; int sum = 0;
262; for (unsigned i = 0; i < 1024; i+=2) {
263; A[i] = i;
264; sum += B[i];
265; }
266;
267; return sum;
268; }
269
270; CHECK: function 'vectorizable_Write_Read':
271; CHECK-NEXT: for.body:
272; CHECK-NEXT: Memory dependences are safe
Adam Nemeta2df7502015-11-03 21:39:52 +0000273; CHECK-NEXT: Dependences:
Hao Liu751004a2015-06-08 04:48:37 +0000274; CHECK-NEXT: BackwardVectorizable:
275; CHECK-NEXT: store i32 %0, i32* %arrayidx, align 4 ->
276; CHECK-NEXT: %1 = load i32, i32* %arrayidx2, align 4
277
278define i32 @vectorizable_Write_Read(i32* nocapture %A) {
279entry:
280 %add.ptr = getelementptr inbounds i32, i32* %A, i64 4
281 br label %for.body
282
283for.cond.cleanup: ; preds = %for.body
284 ret i32 %add
285
286for.body: ; preds = %entry, %for.body
287 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
288 %sum.013 = phi i32 [ 0, %entry ], [ %add, %for.body ]
289 %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
290 %0 = trunc i64 %indvars.iv to i32
291 store i32 %0, i32* %arrayidx, align 4
292 %arrayidx2 = getelementptr inbounds i32, i32* %add.ptr, i64 %indvars.iv
293 %1 = load i32, i32* %arrayidx2, align 4
294 %add = add nsw i32 %1, %sum.013
295 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
296 %cmp = icmp ult i64 %indvars.iv.next, 1024
297 br i1 %cmp, label %for.body, label %for.cond.cleanup
298}
299
300; void vectorizable_Write_Write(int *A) {
301; int *B = A + 4;
302; for (unsigned i = 0; i < 1024; i+=2) {
303; A[i] = i;
304; B[i] = i+1;
305; }
306; }
307
308; CHECK: function 'vectorizable_Write_Write':
309; CHECK-NEXT: for.body:
310; CHECK-NEXT: Memory dependences are safe
Adam Nemeta2df7502015-11-03 21:39:52 +0000311; CHECK-NEXT: Dependences:
Hao Liu751004a2015-06-08 04:48:37 +0000312; CHECK-NEXT: BackwardVectorizable:
313; CHECK-NEXT: store i32 %0, i32* %arrayidx, align 4 ->
314; CHECK-NEXT: store i32 %2, i32* %arrayidx2, align 4
315
316define void @vectorizable_Write_Write(i32* nocapture %A) {
317entry:
318 %add.ptr = getelementptr inbounds i32, i32* %A, i64 4
319 br label %for.body
320
321for.cond.cleanup: ; preds = %for.body
322 ret void
323
324for.body: ; preds = %entry, %for.body
325 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
326 %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
327 %0 = trunc i64 %indvars.iv to i32
328 store i32 %0, i32* %arrayidx, align 4
329 %1 = or i64 %indvars.iv, 1
330 %arrayidx2 = getelementptr inbounds i32, i32* %add.ptr, i64 %indvars.iv
331 %2 = trunc i64 %1 to i32
332 store i32 %2, i32* %arrayidx2, align 4
333 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
334 %cmp = icmp ult i64 %indvars.iv.next, 1024
335 br i1 %cmp, label %for.body, label %for.cond.cleanup
336}
337
338; void vectorizable_unscaled_Read_Write(int *A) {
339; int *B = (int *)((char *)A + 14);
340; for (unsigned i = 0; i < 1024; i+=2)
341; B[i] = A[i] + 1;
342; }
343
344; FIXME: This case looks like previous case @vectorizable_Read_Write. It sould
345; be vectorizable.
346
347; CHECK: function 'vectorizable_unscaled_Read_Write':
348; CHECK-NEXT: for.body:
349; CHECK-NEXT: Report: unsafe dependent memory operations in loop
Adam Nemeta2df7502015-11-03 21:39:52 +0000350; CHECK-NEXT: Dependences:
Hao Liu751004a2015-06-08 04:48:37 +0000351; CHECK-NEXT: BackwardVectorizableButPreventsForwarding:
352; CHECK-NEXT: %2 = load i32, i32* %arrayidx, align 4 ->
353; CHECK-NEXT: store i32 %add, i32* %arrayidx2, align 4
354
355define void @vectorizable_unscaled_Read_Write(i32* nocapture %A) {
356entry:
357 %0 = bitcast i32* %A to i8*
358 %add.ptr = getelementptr inbounds i8, i8* %0, i64 14
359 %1 = bitcast i8* %add.ptr to i32*
360 br label %for.body
361
362for.cond.cleanup: ; preds = %for.body
363 ret void
364
365for.body: ; preds = %entry, %for.body
366 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
367 %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
368 %2 = load i32, i32* %arrayidx, align 4
369 %add = add nsw i32 %2, 1
370 %arrayidx2 = getelementptr inbounds i32, i32* %1, i64 %indvars.iv
371 store i32 %add, i32* %arrayidx2, align 4
372 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
373 %cmp = icmp ult i64 %indvars.iv.next, 1024
374 br i1 %cmp, label %for.body, label %for.cond.cleanup
375}
376
377; int vectorizable_unscaled_Write_Read(int *A) {
378; int *B = (int *)((char *)A + 17);
379; int sum = 0;
380; for (unsigned i = 0; i < 1024; i+=2) {
381; A[i] = i;
382; sum += B[i];
383; }
384;
385; return sum;
386; }
387
Xinliang David Li8a021312016-07-02 21:18:40 +0000388; CHECK: function 'vectorizable_unscaled_Write_Read':
Hao Liu751004a2015-06-08 04:48:37 +0000389; CHECK-NEXT: for.body:
390; CHECK-NEXT: Memory dependences are safe
Adam Nemeta2df7502015-11-03 21:39:52 +0000391; CHECK-NEXT: Dependences:
Hao Liu751004a2015-06-08 04:48:37 +0000392; CHECK-NEXT: BackwardVectorizable:
393; CHECK-NEXT: store i32 %2, i32* %arrayidx, align 4 ->
394; CHECK-NEXT: %3 = load i32, i32* %arrayidx2, align 4
395
396define i32 @vectorizable_unscaled_Write_Read(i32* nocapture %A) {
397entry:
398 %0 = bitcast i32* %A to i8*
399 %add.ptr = getelementptr inbounds i8, i8* %0, i64 17
400 %1 = bitcast i8* %add.ptr to i32*
401 br label %for.body
402
403for.cond.cleanup: ; preds = %for.body
404 ret i32 %add
405
406for.body: ; preds = %entry, %for.body
407 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
408 %sum.013 = phi i32 [ 0, %entry ], [ %add, %for.body ]
409 %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
410 %2 = trunc i64 %indvars.iv to i32
411 store i32 %2, i32* %arrayidx, align 4
412 %arrayidx2 = getelementptr inbounds i32, i32* %1, i64 %indvars.iv
413 %3 = load i32, i32* %arrayidx2, align 4
414 %add = add nsw i32 %3, %sum.013
415 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
416 %cmp = icmp ult i64 %indvars.iv.next, 1024
417 br i1 %cmp, label %for.body, label %for.cond.cleanup
418}
419
420; void unsafe_unscaled_Read_Write(int *A) {
421; int *B = (int *)((char *)A + 11);
422; for (unsigned i = 0; i < 1024; i+=2)
423; B[i] = A[i] + 1;
424; }
425
426; CHECK: function 'unsafe_unscaled_Read_Write':
427; CHECK-NEXT: for.body:
428; CHECK-NEXT: Report: unsafe dependent memory operations in loop
Adam Nemeta2df7502015-11-03 21:39:52 +0000429; CHECK-NEXT: Dependences:
Hao Liu751004a2015-06-08 04:48:37 +0000430; CHECK-NEXT: Backward:
431; CHECK-NEXT: %2 = load i32, i32* %arrayidx, align 4 ->
432; CHECK-NEXT: store i32 %add, i32* %arrayidx2, align 4
433
434define void @unsafe_unscaled_Read_Write(i32* nocapture %A) {
435entry:
436 %0 = bitcast i32* %A to i8*
437 %add.ptr = getelementptr inbounds i8, i8* %0, i64 11
438 %1 = bitcast i8* %add.ptr to i32*
439 br label %for.body
440
441for.cond.cleanup: ; preds = %for.body
442 ret void
443
444for.body: ; preds = %entry, %for.body
445 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
446 %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
447 %2 = load i32, i32* %arrayidx, align 4
448 %add = add nsw i32 %2, 1
449 %arrayidx2 = getelementptr inbounds i32, i32* %1, i64 %indvars.iv
450 store i32 %add, i32* %arrayidx2, align 4
451 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
452 %cmp = icmp ult i64 %indvars.iv.next, 1024
453 br i1 %cmp, label %for.body, label %for.cond.cleanup
454}
455
456; CHECK: function 'unsafe_unscaled_Read_Write2':
457; CHECK-NEXT: for.body:
458; CHECK-NEXT: Report: unsafe dependent memory operations in loop
Adam Nemeta2df7502015-11-03 21:39:52 +0000459; CHECK-NEXT: Dependences:
Hao Liu751004a2015-06-08 04:48:37 +0000460; CHECK-NEXT: Backward:
461; CHECK-NEXT: %2 = load i32, i32* %arrayidx, align 4 ->
462; CHECK-NEXT: store i32 %add, i32* %arrayidx2, align 4
463
464; void unsafe_unscaled_Read_Write2(int *A) {
465; int *B = (int *)((char *)A + 1);
466; for (unsigned i = 0; i < 1024; i+=2)
467; B[i] = A[i] + 1;
468; }
469
470define void @unsafe_unscaled_Read_Write2(i32* nocapture %A) {
471entry:
472 %0 = bitcast i32* %A to i8*
473 %add.ptr = getelementptr inbounds i8, i8* %0, i64 1
474 %1 = bitcast i8* %add.ptr to i32*
475 br label %for.body
476
477for.cond.cleanup: ; preds = %for.body
478 ret void
479
480for.body: ; preds = %entry, %for.body
481 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
482 %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
483 %2 = load i32, i32* %arrayidx, align 4
484 %add = add nsw i32 %2, 1
485 %arrayidx2 = getelementptr inbounds i32, i32* %1, i64 %indvars.iv
486 store i32 %add, i32* %arrayidx2, align 4
487 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
488 %cmp = icmp ult i64 %indvars.iv.next, 1024
489 br i1 %cmp, label %for.body, label %for.cond.cleanup
490}
491
492; Following case checks that interleaved stores have dependences with another
493; store and can not pass dependence check.
494
495; void interleaved_stores(int *A) {
496; int *B = (int *) ((char *)A + 1);
497; for(int i = 0; i < 1024; i+=2) {
498; B[i] = i; // (1)
499; A[i+1] = i + 1; // (2)
500; B[i+1] = i + 1; // (3)
501; }
502; }
503;
504; The access (2) has overlaps with (1) and (3).
505
506; CHECK: function 'interleaved_stores':
507; CHECK-NEXT: for.body:
508; CHECK-NEXT: Report: unsafe dependent memory operations in loop
Adam Nemeta2df7502015-11-03 21:39:52 +0000509; CHECK-NEXT: Dependences:
Hao Liu751004a2015-06-08 04:48:37 +0000510; CHECK-NEXT: Backward:
511; CHECK-NEXT: store i32 %4, i32* %arrayidx5, align 4 ->
512; CHECK-NEXT: store i32 %4, i32* %arrayidx9, align 4
513; CHECK: Backward:
514; CHECK-NEXT: store i32 %2, i32* %arrayidx2, align 4 ->
515; CHECK-NEXT: store i32 %4, i32* %arrayidx5, align 4
516
517define void @interleaved_stores(i32* nocapture %A) {
518entry:
519 %0 = bitcast i32* %A to i8*
520 %incdec.ptr = getelementptr inbounds i8, i8* %0, i64 1
521 %1 = bitcast i8* %incdec.ptr to i32*
522 br label %for.body
523
524for.cond.cleanup: ; preds = %for.body
525 ret void
526
527for.body: ; preds = %entry, %for.body
528 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
529 %2 = trunc i64 %indvars.iv to i32
530 %arrayidx2 = getelementptr inbounds i32, i32* %1, i64 %indvars.iv
531 store i32 %2, i32* %arrayidx2, align 4
532 %3 = or i64 %indvars.iv, 1
533 %arrayidx5 = getelementptr inbounds i32, i32* %A, i64 %3
534 %4 = trunc i64 %3 to i32
535 store i32 %4, i32* %arrayidx5, align 4
536 %arrayidx9 = getelementptr inbounds i32, i32* %1, i64 %3
537 store i32 %4, i32* %arrayidx9, align 4
538 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
539 %cmp = icmp slt i64 %indvars.iv.next, 1024
540 br i1 %cmp, label %for.body, label %for.cond.cleanup
541}