xref: /llvm-project/llvm/test/Analysis/LoopAccessAnalysis/stride-access-dependence.ll (revision 5bd210ace6c165d5093220811ba8d5fc300ac1f9)
1; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 4
2; RUN: opt -passes='print<access-info>' -disable-output  < %s 2>&1 | FileCheck %s
3
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
14define void @nodep_Read_Write(ptr nocapture %A) {
15; CHECK-LABEL: 'nodep_Read_Write'
16; CHECK-NEXT:    for.body:
17; CHECK-NEXT:      Memory dependences are safe
18; CHECK-NEXT:      Dependences:
19; CHECK-NEXT:      Run-time memory checks:
20; CHECK-NEXT:      Grouped accesses:
21; CHECK-EMPTY:
22; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
23; CHECK-NEXT:      SCEV assumptions:
24; CHECK-EMPTY:
25; CHECK-NEXT:      Expressions re-written:
26;
27entry:
28  %add.ptr = getelementptr inbounds i32, ptr %A, i64 1
29  br label %for.body
30
31for.cond.cleanup:                                 ; preds = %for.body
32  ret void
33
34for.body:                                         ; preds = %entry, %for.body
35  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
36  %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv
37  %0 = load i32, ptr %arrayidx, align 4
38  %add = add nsw i32 %0, 1
39  %arrayidx2 = getelementptr inbounds i32, ptr %add.ptr, i64 %indvars.iv
40  store i32 %add, ptr %arrayidx2, align 4
41  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 3
42  %cmp = icmp ult i64 %indvars.iv.next, 1024
43  br i1 %cmp, label %for.body, label %for.cond.cleanup
44}
45
46; int nodep_Write_Read(int *A) {
47;   int sum = 0;
48;   for (unsigned i = 0; i < 1024; i+=4) {
49;     A[i] = i;
50;     sum += A[i+3];
51;   }
52;
53;   return sum;
54; }
55
56define i32 @nodep_Write_Read(ptr nocapture %A) {
57; CHECK-LABEL: 'nodep_Write_Read'
58; CHECK-NEXT:    for.body:
59; CHECK-NEXT:      Memory dependences are safe
60; CHECK-NEXT:      Dependences:
61; CHECK-NEXT:      Run-time memory checks:
62; CHECK-NEXT:      Grouped accesses:
63; CHECK-EMPTY:
64; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
65; CHECK-NEXT:      SCEV assumptions:
66; CHECK-EMPTY:
67; CHECK-NEXT:      Expressions re-written:
68;
69entry:
70  br label %for.body
71
72for.cond.cleanup:                                 ; preds = %for.body
73  ret i32 %add3
74
75for.body:                                         ; preds = %entry, %for.body
76  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
77  %sum.013 = phi i32 [ 0, %entry ], [ %add3, %for.body ]
78  %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv
79  %0 = trunc i64 %indvars.iv to i32
80  store i32 %0, ptr %arrayidx, align 4
81  %1 = or disjoint i64 %indvars.iv, 3
82  %arrayidx2 = getelementptr inbounds i32, ptr %A, i64 %1
83  %2 = load i32, ptr %arrayidx2, align 4
84  %add3 = add nsw i32 %2, %sum.013
85  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 4
86  %cmp = icmp ult i64 %indvars.iv.next, 1024
87  br i1 %cmp, label %for.body, label %for.cond.cleanup
88}
89
90; void nodep_Write_Write(int *A) {
91;   for (unsigned i = 0; i < 1024; i+=2) {
92;     A[i] = i;
93;     A[i+1] = i+1;
94;   }
95; }
96
97define void @nodep_Write_Write(ptr nocapture %A) {
98; CHECK-LABEL: 'nodep_Write_Write'
99; CHECK-NEXT:    for.body:
100; CHECK-NEXT:      Memory dependences are safe
101; CHECK-NEXT:      Dependences:
102; CHECK-NEXT:      Run-time memory checks:
103; CHECK-NEXT:      Grouped accesses:
104; CHECK-EMPTY:
105; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
106; CHECK-NEXT:      SCEV assumptions:
107; CHECK-EMPTY:
108; CHECK-NEXT:      Expressions re-written:
109;
110entry:
111  br label %for.body
112
113for.cond.cleanup:                                 ; preds = %for.body
114  ret void
115
116for.body:                                         ; preds = %entry, %for.body
117  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
118  %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv
119  %0 = trunc i64 %indvars.iv to i32
120  store i32 %0, ptr %arrayidx, align 4
121  %1 = or disjoint i64 %indvars.iv, 1
122  %arrayidx3 = getelementptr inbounds i32, ptr %A, i64 %1
123  %2 = trunc i64 %1 to i32
124  store i32 %2, ptr %arrayidx3, align 4
125  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
126  %cmp = icmp ult i64 %indvars.iv.next, 1024
127  br i1 %cmp, label %for.body, label %for.cond.cleanup
128}
129
130; Following cases are unsafe depdences and are not vectorizable.
131
132; void unsafe_Read_Write(int *A) {
133;   for (unsigned i = 0; i < 1024; i+=3)
134;     A[i+3] = A[i] + 1;
135; }
136
137define void @unsafe_Read_Write(ptr nocapture %A) {
138; CHECK-LABEL: 'unsafe_Read_Write'
139; CHECK-NEXT:    for.body:
140; CHECK-NEXT:      Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
141; CHECK-NEXT:  Backward loop carried data dependence.
142; CHECK-NEXT:      Dependences:
143; CHECK-NEXT:        Backward:
144; CHECK-NEXT:            %0 = load i32, ptr %arrayidx, align 4 ->
145; CHECK-NEXT:            store i32 %add, ptr %arrayidx3, align 4
146; CHECK-EMPTY:
147; CHECK-NEXT:      Run-time memory checks:
148; CHECK-NEXT:      Grouped accesses:
149; CHECK-EMPTY:
150; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
151; CHECK-NEXT:      SCEV assumptions:
152; CHECK-EMPTY:
153; CHECK-NEXT:      Expressions re-written:
154;
155entry:
156  br label %for.body
157
158for.cond.cleanup:                                 ; preds = %for.body
159  ret void
160
161for.body:                                         ; preds = %entry, %for.body
162  %i.010 = phi i32 [ 0, %entry ], [ %add1, %for.body ]
163  %idxprom = zext i32 %i.010 to i64
164  %arrayidx = getelementptr inbounds i32, ptr %A, i64 %idxprom
165  %0 = load i32, ptr %arrayidx, align 4
166  %add = add nsw i32 %0, 1
167  %add1 = add i32 %i.010, 3
168  %idxprom2 = zext i32 %add1 to i64
169  %arrayidx3 = getelementptr inbounds i32, ptr %A, i64 %idxprom2
170  store i32 %add, ptr %arrayidx3, align 4
171  %cmp = icmp ult i32 %add1, 1024
172  br i1 %cmp, label %for.body, label %for.cond.cleanup
173}
174
175; int unsafe_Write_Read(int *A) {
176;   int sum = 0;
177;   for (unsigned i = 0; i < 1024; i+=4) {
178;     A[i] = i;
179;     sum += A[i+4];
180;   }
181;
182;   return sum;
183; }
184
185define i32 @unsafe_Write_Read(ptr nocapture %A) {
186; CHECK-LABEL: 'unsafe_Write_Read'
187; CHECK-NEXT:    for.body:
188; CHECK-NEXT:      Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
189; CHECK-NEXT:  Backward loop carried data dependence.
190; CHECK-NEXT:      Dependences:
191; CHECK-NEXT:        Backward:
192; CHECK-NEXT:            store i32 %0, ptr %arrayidx, align 4 ->
193; CHECK-NEXT:            %1 = load i32, ptr %arrayidx2, align 4
194; CHECK-EMPTY:
195; CHECK-NEXT:      Run-time memory checks:
196; CHECK-NEXT:      Grouped accesses:
197; CHECK-EMPTY:
198; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
199; CHECK-NEXT:      SCEV assumptions:
200; CHECK-EMPTY:
201; CHECK-NEXT:      Expressions re-written:
202;
203entry:
204  br label %for.body
205
206for.cond.cleanup:                                 ; preds = %for.body
207  ret i32 %add3
208
209for.body:                                         ; preds = %entry, %for.body
210  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
211  %sum.013 = phi i32 [ 0, %entry ], [ %add3, %for.body ]
212  %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv
213  %0 = trunc i64 %indvars.iv to i32
214  store i32 %0, ptr %arrayidx, align 4
215  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 4
216  %arrayidx2 = getelementptr inbounds i32, ptr %A, i64 %indvars.iv.next
217  %1 = load i32, ptr %arrayidx2, align 4
218  %add3 = add nsw i32 %1, %sum.013
219  %cmp = icmp ult i64 %indvars.iv.next, 1024
220  br i1 %cmp, label %for.body, label %for.cond.cleanup
221}
222
223; void unsafe_Write_Write(int *A) {
224;   for (unsigned i = 0; i < 1024; i+=2) {
225;     A[i] = i;
226;     A[i+2] = i+1;
227;   }
228; }
229
230define void @unsafe_Write_Write(ptr nocapture %A) {
231; CHECK-LABEL: 'unsafe_Write_Write'
232; CHECK-NEXT:    for.body:
233; CHECK-NEXT:      Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
234; CHECK-NEXT:  Backward loop carried data dependence.
235; CHECK-NEXT:      Dependences:
236; CHECK-NEXT:        Backward:
237; CHECK-NEXT:            store i32 %0, ptr %arrayidx, align 4 ->
238; CHECK-NEXT:            store i32 %2, ptr %arrayidx3, align 4
239; CHECK-EMPTY:
240; CHECK-NEXT:      Run-time memory checks:
241; CHECK-NEXT:      Grouped accesses:
242; CHECK-EMPTY:
243; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
244; CHECK-NEXT:      SCEV assumptions:
245; CHECK-EMPTY:
246; CHECK-NEXT:      Expressions re-written:
247;
248entry:
249  br label %for.body
250
251for.cond.cleanup:                                 ; preds = %for.body
252  ret void
253
254for.body:                                         ; preds = %entry, %for.body
255  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
256  %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv
257  %0 = trunc i64 %indvars.iv to i32
258  store i32 %0, ptr %arrayidx, align 4
259  %1 = or disjoint i64 %indvars.iv, 1
260  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
261  %arrayidx3 = getelementptr inbounds i32, ptr %A, i64 %indvars.iv.next
262  %2 = trunc i64 %1 to i32
263  store i32 %2, ptr %arrayidx3, align 4
264  %cmp = icmp ult i64 %indvars.iv.next, 1024
265  br i1 %cmp, label %for.body, label %for.cond.cleanup
266}
267
268; Following cases check that strided accesses can be vectorized.
269
270; void vectorizable_Read_Write(int *A) {
271;   int *B = A + 4;
272;   for (unsigned i = 0; i < 1024; i+=2)
273;     B[i] = A[i] + 1;
274; }
275
276define void @vectorizable_Read_Write(ptr nocapture %A) {
277; CHECK-LABEL: 'vectorizable_Read_Write'
278; CHECK-NEXT:    for.body:
279; CHECK-NEXT:      Memory dependences are safe with a maximum safe vector width of 64 bits
280; CHECK-NEXT:      Dependences:
281; CHECK-NEXT:        BackwardVectorizable:
282; CHECK-NEXT:            %0 = load i32, ptr %arrayidx, align 4 ->
283; CHECK-NEXT:            store i32 %add, ptr %arrayidx2, align 4
284; CHECK-EMPTY:
285; CHECK-NEXT:      Run-time memory checks:
286; CHECK-NEXT:      Grouped accesses:
287; CHECK-EMPTY:
288; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
289; CHECK-NEXT:      SCEV assumptions:
290; CHECK-EMPTY:
291; CHECK-NEXT:      Expressions re-written:
292;
293entry:
294  %add.ptr = getelementptr inbounds i32, ptr %A, i64 4
295  br label %for.body
296
297for.cond.cleanup:                                 ; preds = %for.body
298  ret void
299
300for.body:                                         ; preds = %entry, %for.body
301  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
302  %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv
303  %0 = load i32, ptr %arrayidx, align 4
304  %add = add nsw i32 %0, 1
305  %arrayidx2 = getelementptr inbounds i32, ptr %add.ptr, i64 %indvars.iv
306  store i32 %add, ptr %arrayidx2, align 4
307  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
308  %cmp = icmp ult i64 %indvars.iv.next, 1024
309  br i1 %cmp, label %for.body, label %for.cond.cleanup
310}
311
312; int vectorizable_Write_Read(int *A) {
313;   int *B = A + 4;
314;   int sum = 0;
315;   for (unsigned i = 0; i < 1024; i+=2) {
316;     A[i] = i;
317;     sum += B[i];
318;   }
319;
320;   return sum;
321; }
322
323define i32 @vectorizable_Write_Read(ptr nocapture %A) {
324; CHECK-LABEL: 'vectorizable_Write_Read'
325; CHECK-NEXT:    for.body:
326; CHECK-NEXT:      Memory dependences are safe with a maximum safe vector width of 64 bits
327; CHECK-NEXT:      Dependences:
328; CHECK-NEXT:        BackwardVectorizable:
329; CHECK-NEXT:            store i32 %0, ptr %arrayidx, align 4 ->
330; CHECK-NEXT:            %1 = load i32, ptr %arrayidx2, align 4
331; CHECK-EMPTY:
332; CHECK-NEXT:      Run-time memory checks:
333; CHECK-NEXT:      Grouped accesses:
334; CHECK-EMPTY:
335; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
336; CHECK-NEXT:      SCEV assumptions:
337; CHECK-EMPTY:
338; CHECK-NEXT:      Expressions re-written:
339;
340entry:
341  %add.ptr = getelementptr inbounds i32, ptr %A, i64 4
342  br label %for.body
343
344for.cond.cleanup:                                 ; preds = %for.body
345  ret i32 %add
346
347for.body:                                         ; preds = %entry, %for.body
348  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
349  %sum.013 = phi i32 [ 0, %entry ], [ %add, %for.body ]
350  %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv
351  %0 = trunc i64 %indvars.iv to i32
352  store i32 %0, ptr %arrayidx, align 4
353  %arrayidx2 = getelementptr inbounds i32, ptr %add.ptr, i64 %indvars.iv
354  %1 = load i32, ptr %arrayidx2, align 4
355  %add = add nsw i32 %1, %sum.013
356  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
357  %cmp = icmp ult i64 %indvars.iv.next, 1024
358  br i1 %cmp, label %for.body, label %for.cond.cleanup
359}
360
361; void vectorizable_Write_Write(int *A) {
362;   int *B = A + 4;
363;   for (unsigned i = 0; i < 1024; i+=2) {
364;     A[i] = i;
365;     B[i] = i+1;
366;   }
367; }
368
369define void @vectorizable_Write_Write(ptr nocapture %A) {
370; CHECK-LABEL: 'vectorizable_Write_Write'
371; CHECK-NEXT:    for.body:
372; CHECK-NEXT:      Memory dependences are safe with a maximum safe vector width of 64 bits
373; CHECK-NEXT:      Dependences:
374; CHECK-NEXT:        BackwardVectorizable:
375; CHECK-NEXT:            store i32 %0, ptr %arrayidx, align 4 ->
376; CHECK-NEXT:            store i32 %2, ptr %arrayidx2, align 4
377; CHECK-EMPTY:
378; CHECK-NEXT:      Run-time memory checks:
379; CHECK-NEXT:      Grouped accesses:
380; CHECK-EMPTY:
381; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
382; CHECK-NEXT:      SCEV assumptions:
383; CHECK-EMPTY:
384; CHECK-NEXT:      Expressions re-written:
385;
386entry:
387  %add.ptr = getelementptr inbounds i32, ptr %A, i64 4
388  br label %for.body
389
390for.cond.cleanup:                                 ; preds = %for.body
391  ret void
392
393for.body:                                         ; preds = %entry, %for.body
394  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
395  %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv
396  %0 = trunc i64 %indvars.iv to i32
397  store i32 %0, ptr %arrayidx, align 4
398  %1 = or disjoint i64 %indvars.iv, 1
399  %arrayidx2 = getelementptr inbounds i32, ptr %add.ptr, i64 %indvars.iv
400  %2 = trunc i64 %1 to i32
401  store i32 %2, ptr %arrayidx2, align 4
402  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
403  %cmp = icmp ult i64 %indvars.iv.next, 1024
404  br i1 %cmp, label %for.body, label %for.cond.cleanup
405}
406
407; void vectorizable_unscaled_Read_Write(int *A) {
408;   int *B = (int *)((char *)A + 14);
409;   for (unsigned i = 0; i < 1024; i+=2)
410;     B[i] = A[i] + 1;
411; }
412
413; FIXME: This case looks like previous case @vectorizable_Read_Write. It sould
414; be vectorizable.
415
416define void @vectorizable_unscaled_Read_Write(ptr nocapture %A) {
417; CHECK-LABEL: 'vectorizable_unscaled_Read_Write'
418; CHECK-NEXT:    for.body:
419; CHECK-NEXT:      Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
420; CHECK-NEXT:  Backward loop carried data dependence that prevents store-to-load forwarding.
421; CHECK-NEXT:      Dependences:
422; CHECK-NEXT:        BackwardVectorizableButPreventsForwarding:
423; CHECK-NEXT:            %0 = load i32, ptr %arrayidx, align 4 ->
424; CHECK-NEXT:            store i32 %add, ptr %arrayidx2, align 4
425; CHECK-EMPTY:
426; CHECK-NEXT:      Run-time memory checks:
427; CHECK-NEXT:      Grouped accesses:
428; CHECK-EMPTY:
429; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
430; CHECK-NEXT:      SCEV assumptions:
431; CHECK-EMPTY:
432; CHECK-NEXT:      Expressions re-written:
433;
434entry:
435  %add.ptr = getelementptr inbounds i8, ptr %A, i64 14
436  br label %for.body
437
438for.cond.cleanup:                                 ; preds = %for.body
439  ret void
440
441for.body:                                         ; preds = %entry, %for.body
442  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
443  %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv
444  %0 = load i32, ptr %arrayidx, align 4
445  %add = add nsw i32 %0, 1
446  %arrayidx2 = getelementptr inbounds i32, ptr %add.ptr, i64 %indvars.iv
447  store i32 %add, ptr %arrayidx2, align 4
448  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
449  %cmp = icmp ult i64 %indvars.iv.next, 1024
450  br i1 %cmp, label %for.body, label %for.cond.cleanup
451}
452
453; int vectorizable_unscaled_Write_Read(int *A) {
454;   int *B = (int *)((char *)A + 17);
455;   int sum = 0;
456;   for (unsigned i = 0; i < 1024; i+=2) {
457;     A[i] = i;
458;     sum += B[i];
459;   }
460;
461;   return sum;
462; }
463
464define i32 @vectorizable_unscaled_Write_Read(ptr nocapture %A) {
465; CHECK-LABEL: 'vectorizable_unscaled_Write_Read'
466; CHECK-NEXT:    for.body:
467; CHECK-NEXT:      Memory dependences are safe with a maximum safe vector width of 64 bits
468; CHECK-NEXT:      Dependences:
469; CHECK-NEXT:        BackwardVectorizable:
470; CHECK-NEXT:            store i32 %0, ptr %arrayidx, align 4 ->
471; CHECK-NEXT:            %1 = load i32, ptr %arrayidx2, align 4
472; CHECK-EMPTY:
473; CHECK-NEXT:      Run-time memory checks:
474; CHECK-NEXT:      Grouped accesses:
475; CHECK-EMPTY:
476; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
477; CHECK-NEXT:      SCEV assumptions:
478; CHECK-EMPTY:
479; CHECK-NEXT:      Expressions re-written:
480;
481entry:
482  %add.ptr = getelementptr inbounds i8, ptr %A, i64 17
483  br label %for.body
484
485for.cond.cleanup:                                 ; preds = %for.body
486  ret i32 %add
487
488for.body:                                         ; preds = %entry, %for.body
489  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
490  %sum.013 = phi i32 [ 0, %entry ], [ %add, %for.body ]
491  %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv
492  %0 = trunc i64 %indvars.iv to i32
493  store i32 %0, ptr %arrayidx, align 4
494  %arrayidx2 = getelementptr inbounds i32, ptr %add.ptr, i64 %indvars.iv
495  %1 = load i32, ptr %arrayidx2, align 4
496  %add = add nsw i32 %1, %sum.013
497  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
498  %cmp = icmp ult i64 %indvars.iv.next, 1024
499  br i1 %cmp, label %for.body, label %for.cond.cleanup
500}
501
502; void unsafe_unscaled_Read_Write(int *A) {
503;   int *B = (int *)((char *)A + 11);
504;   for (unsigned i = 0; i < 1024; i+=2)
505;     B[i] = A[i] + 1;
506; }
507
508define void @unsafe_unscaled_Read_Write(ptr nocapture %A) {
509; CHECK-LABEL: 'unsafe_unscaled_Read_Write'
510; CHECK-NEXT:    for.body:
511; CHECK-NEXT:      Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
512; CHECK-NEXT:  Backward loop carried data dependence.
513; CHECK-NEXT:      Dependences:
514; CHECK-NEXT:        Backward:
515; CHECK-NEXT:            %0 = load i32, ptr %arrayidx, align 4 ->
516; CHECK-NEXT:            store i32 %add, ptr %arrayidx2, align 4
517; CHECK-EMPTY:
518; CHECK-NEXT:      Run-time memory checks:
519; CHECK-NEXT:      Grouped accesses:
520; CHECK-EMPTY:
521; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
522; CHECK-NEXT:      SCEV assumptions:
523; CHECK-EMPTY:
524; CHECK-NEXT:      Expressions re-written:
525;
526entry:
527  %add.ptr = getelementptr inbounds i8, ptr %A, i64 11
528  br label %for.body
529
530for.cond.cleanup:                                 ; preds = %for.body
531  ret void
532
533for.body:                                         ; preds = %entry, %for.body
534  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
535  %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv
536  %0 = load i32, ptr %arrayidx, align 4
537  %add = add nsw i32 %0, 1
538  %arrayidx2 = getelementptr inbounds i32, ptr %add.ptr, i64 %indvars.iv
539  store i32 %add, ptr %arrayidx2, align 4
540  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
541  %cmp = icmp ult i64 %indvars.iv.next, 1024
542  br i1 %cmp, label %for.body, label %for.cond.cleanup
543}
544
545; void unsafe_unscaled_Read_Write2(int *A) {
546;   int *B = (int *)((char *)A + 1);
547;   for (unsigned i = 0; i < 1024; i+=2)
548;     B[i] = A[i] + 1;
549; }
550
551define void @unsafe_unscaled_Read_Write2(ptr nocapture %A) {
552; CHECK-LABEL: 'unsafe_unscaled_Read_Write2'
553; CHECK-NEXT:    for.body:
554; CHECK-NEXT:      Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
555; CHECK-NEXT:  Backward loop carried data dependence.
556; CHECK-NEXT:      Dependences:
557; CHECK-NEXT:        Backward:
558; CHECK-NEXT:            %0 = load i32, ptr %arrayidx, align 4 ->
559; CHECK-NEXT:            store i32 %add, ptr %arrayidx2, align 4
560; CHECK-EMPTY:
561; CHECK-NEXT:      Run-time memory checks:
562; CHECK-NEXT:      Grouped accesses:
563; CHECK-EMPTY:
564; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
565; CHECK-NEXT:      SCEV assumptions:
566; CHECK-EMPTY:
567; CHECK-NEXT:      Expressions re-written:
568;
569entry:
570  %add.ptr = getelementptr inbounds i8, ptr %A, i64 1
571  br label %for.body
572
573for.cond.cleanup:                                 ; preds = %for.body
574  ret void
575
576for.body:                                         ; preds = %entry, %for.body
577  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
578  %arrayidx = getelementptr inbounds i32, ptr %A, i64 %indvars.iv
579  %0 = load i32, ptr %arrayidx, align 4
580  %add = add nsw i32 %0, 1
581  %arrayidx2 = getelementptr inbounds i32, ptr %add.ptr, i64 %indvars.iv
582  store i32 %add, ptr %arrayidx2, align 4
583  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
584  %cmp = icmp ult i64 %indvars.iv.next, 1024
585  br i1 %cmp, label %for.body, label %for.cond.cleanup
586}
587
588; Following case checks that interleaved stores have dependences with another
589; store and can not pass dependence check.
590
591; void interleaved_stores(int *A) {
592;   int *B = (int *) ((char *)A + 1);
593;   for(int i = 0; i < 1024; i+=2) {
594;     B[i]   = i;                // (1)
595;     A[i+1] = i + 1;            // (2)
596;     B[i+1] = i + 1;            // (3)
597;   }
598; }
599;
600; The access (2) has overlaps with (1) and (3).
601
602define void @interleaved_stores(ptr nocapture %A) {
603; CHECK-LABEL: 'interleaved_stores'
604; CHECK-NEXT:    for.body:
605; CHECK-NEXT:      Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
606; CHECK-NEXT:  Backward loop carried data dependence.
607; CHECK-NEXT:      Dependences:
608; CHECK-NEXT:        Backward:
609; CHECK-NEXT:            store i32 %2, ptr %arrayidx5, align 4 ->
610; CHECK-NEXT:            store i32 %2, ptr %arrayidx9, align 4
611; CHECK-EMPTY:
612; CHECK-NEXT:        Backward:
613; CHECK-NEXT:            store i32 %0, ptr %arrayidx2, align 4 ->
614; CHECK-NEXT:            store i32 %2, ptr %arrayidx5, align 4
615; CHECK-EMPTY:
616; CHECK-NEXT:      Run-time memory checks:
617; CHECK-NEXT:      Grouped accesses:
618; CHECK-EMPTY:
619; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
620; CHECK-NEXT:      SCEV assumptions:
621; CHECK-EMPTY:
622; CHECK-NEXT:      Expressions re-written:
623;
624entry:
625  %incdec.ptr = getelementptr inbounds i8, ptr %A, i64 1
626  br label %for.body
627
628for.cond.cleanup:                                 ; preds = %for.body
629  ret void
630
631for.body:                                         ; preds = %entry, %for.body
632  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
633  %0 = trunc i64 %indvars.iv to i32
634  %arrayidx2 = getelementptr inbounds i32, ptr %incdec.ptr, i64 %indvars.iv
635  store i32 %0, ptr %arrayidx2, align 4
636  %1 = or disjoint i64 %indvars.iv, 1
637  %arrayidx5 = getelementptr inbounds i32, ptr %A, i64 %1
638  %2 = trunc i64 %1 to i32
639  store i32 %2, ptr %arrayidx5, align 4
640  %arrayidx9 = getelementptr inbounds i32, ptr %incdec.ptr, i64 %1
641  store i32 %2, ptr %arrayidx9, align 4
642  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 2
643  %cmp = icmp slt i64 %indvars.iv.next, 1024
644  br i1 %cmp, label %for.body, label %for.cond.cleanup
645}
646