Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Analysis / LoopAccessAnalysis / non-constant-strides-forward.ll
blob5f4c732dc19df088e8beb7e942048d7f5c921698
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
4 target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
6 declare void @llvm.assume(i1)
8 define void @different_non_constant_strides_known_forward(ptr %A) {
9 ; CHECK-LABEL: 'different_non_constant_strides_known_forward'
10 ; CHECK-NEXT:    loop:
11 ; CHECK-NEXT:      Memory dependences are safe
12 ; CHECK-NEXT:      Dependences:
13 ; CHECK-NEXT:        Forward:
14 ; CHECK-NEXT:            %l = load i32, ptr %gep.mul.2, align 4 ->
15 ; CHECK-NEXT:            store i32 %add, ptr %gep, align 4
16 ; CHECK-EMPTY:
17 ; CHECK-NEXT:      Run-time memory checks:
18 ; CHECK-NEXT:      Grouped accesses:
19 ; CHECK-EMPTY:
20 ; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
21 ; CHECK-NEXT:      SCEV assumptions:
22 ; CHECK-EMPTY:
23 ; CHECK-NEXT:      Expressions re-written:
25 entry:
26   br label %loop
28 loop:
29   %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
30   %iv.mul.2 = shl nuw nsw i64 %iv, 1
31   %gep.mul.2 = getelementptr inbounds i32, ptr %A, i64 %iv.mul.2
32   %l = load i32, ptr %gep.mul.2, align 4
33   %add = add nsw i32 %l, 5
34   %gep = getelementptr inbounds i32, ptr %A, i64 %iv
35   store i32 %add, ptr %gep, align 4
36   %iv.next = add nuw nsw i64 %iv, 1
37   %exitcond.not = icmp eq i64 %iv.next, 256
38   br i1 %exitcond.not, label %exit, label %loop
40 exit:
41   ret void
44 define void @different_non_constant_strides_known_forward_min_distance_3(ptr %A) {
45 ; CHECK-LABEL: 'different_non_constant_strides_known_forward_min_distance_3'
46 ; CHECK-NEXT:    loop:
47 ; CHECK-NEXT:      Memory dependences are safe
48 ; CHECK-NEXT:      Dependences:
49 ; CHECK-NEXT:        Forward:
50 ; CHECK-NEXT:            %l = load i32, ptr %gep.mul.2, align 4 ->
51 ; CHECK-NEXT:            store i32 %add, ptr %gep, align 4
52 ; CHECK-EMPTY:
53 ; CHECK-NEXT:      Run-time memory checks:
54 ; CHECK-NEXT:      Grouped accesses:
55 ; CHECK-EMPTY:
56 ; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
57 ; CHECK-NEXT:      SCEV assumptions:
58 ; CHECK-EMPTY:
59 ; CHECK-NEXT:      Expressions re-written:
61 entry:
62   %A.3 = getelementptr inbounds i8, ptr %A, i64 3
63   br label %loop
65 loop:
66   %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
67   %iv.mul.2 = shl nuw nsw i64 %iv, 1
68   %gep.mul.2 = getelementptr inbounds i32, ptr %A.3, i64 %iv.mul.2
69   %l = load i32, ptr %gep.mul.2, align 4
70   %add = add nsw i32 %l, 5
71   %gep = getelementptr inbounds i32, ptr %A, i64 %iv
72   store i32 %add, ptr %gep, align 4
73   %iv.next = add nuw nsw i64 %iv, 1
74   %exitcond.not = icmp eq i64 %iv.next, 256
75   br i1 %exitcond.not, label %exit, label %loop
77 exit:
78   ret void
81 define void @different_non_constant_strides_known_forward_via_assume(ptr %A, i64 %scale) {
82 ; CHECK-LABEL: 'different_non_constant_strides_known_forward_via_assume'
83 ; CHECK-NEXT:    loop:
84 ; CHECK-NEXT:      Report: cannot identify array bounds
85 ; CHECK-NEXT:      Dependences:
86 ; CHECK-NEXT:      Run-time memory checks:
87 ; CHECK-NEXT:      Grouped accesses:
88 ; CHECK-EMPTY:
89 ; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
90 ; CHECK-NEXT:      SCEV assumptions:
91 ; CHECK-EMPTY:
92 ; CHECK-NEXT:      Expressions re-written:
94 entry:
95   %c = icmp sgt i64 %scale, 0
96   call void @llvm.assume(i1 %c)
97   br label %loop
99 loop:
100   %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
101   %iv.mul.2 = shl nuw nsw i64 %iv, %scale
102   %gep.mul.2 = getelementptr inbounds i32, ptr %A, i64 %iv.mul.2
103   %l = load i32, ptr %gep.mul.2, align 4
104   %add = add nsw i32 %l, 5
105   %gep = getelementptr inbounds i32, ptr %A, i64 %iv
106   store i32 %add, ptr %gep, align 4
107   %iv.next = add nuw nsw i64 %iv, 1
108   %exitcond.not = icmp eq i64 %iv.next, 256
109   br i1 %exitcond.not, label %exit, label %loop
111 exit:
112   ret void
115 define void @different_non_constant_strides_known_forward_via_assume_min_distance_3(ptr %A, i64 %scale) {
116 ; CHECK-LABEL: 'different_non_constant_strides_known_forward_via_assume_min_distance_3'
117 ; CHECK-NEXT:    loop:
118 ; CHECK-NEXT:      Report: cannot identify array bounds
119 ; CHECK-NEXT:      Dependences:
120 ; CHECK-NEXT:      Run-time memory checks:
121 ; CHECK-NEXT:      Grouped accesses:
122 ; CHECK-EMPTY:
123 ; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
124 ; CHECK-NEXT:      SCEV assumptions:
125 ; CHECK-EMPTY:
126 ; CHECK-NEXT:      Expressions re-written:
128 entry:
129   %A.3 = getelementptr inbounds i8, ptr %A, i64 3
130   %c = icmp sgt i64 %scale, 0
131   call void @llvm.assume(i1 %c)
132   br label %loop
134 loop:
135   %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
136   %iv.mul.2 = shl nuw nsw i64 %iv, %scale
137   %gep.mul.2 = getelementptr inbounds i32, ptr %A.3, i64 %iv.mul.2
138   %l = load i32, ptr %gep.mul.2, align 4
139   %add = add nsw i32 %l, 5
140   %gep = getelementptr inbounds i32, ptr %A, i64 %iv
141   store i32 %add, ptr %gep, align 4
142   %iv.next = add nuw nsw i64 %iv, 1
143   %exitcond.not = icmp eq i64 %iv.next, 256
144   br i1 %exitcond.not, label %exit, label %loop
146 exit:
147   ret void
150 define void @different_non_constant_strides_not_known_forward(ptr %A, i64 %scale) {
151 ; CHECK-LABEL: 'different_non_constant_strides_not_known_forward'
152 ; CHECK-NEXT:    loop:
153 ; CHECK-NEXT:      Report: cannot identify array bounds
154 ; CHECK-NEXT:      Dependences:
155 ; CHECK-NEXT:      Run-time memory checks:
156 ; CHECK-NEXT:      Grouped accesses:
157 ; CHECK-EMPTY:
158 ; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
159 ; CHECK-NEXT:      SCEV assumptions:
160 ; CHECK-EMPTY:
161 ; CHECK-NEXT:      Expressions re-written:
163 entry:
164   br label %loop
166 loop:
167   %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
168   %iv.mul.2 = shl nuw nsw i64 %iv, %scale
169   %gep.mul.2 = getelementptr inbounds i32, ptr %A, i64 %iv.mul.2
170   %l = load i32, ptr %gep.mul.2, align 4
171   %add = add nsw i32 %l, 5
172   %gep = getelementptr inbounds i32, ptr %A, i64 %iv
173   store i32 %add, ptr %gep, align 4
174   %iv.next = add nuw nsw i64 %iv, 1
175   %exitcond.not = icmp eq i64 %iv.next, 256
176   br i1 %exitcond.not, label %exit, label %loop
178 exit:
179   ret void
182 ; Tests with accesses with strides with different signs.
183 define void @strides_with_different_directions_1(ptr %A) {
184 ; CHECK-LABEL: 'strides_with_different_directions_1'
185 ; CHECK-NEXT:    loop:
186 ; 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
187 ; CHECK-NEXT:  Unknown data dependence.
188 ; CHECK-NEXT:      Dependences:
189 ; CHECK-NEXT:        Unknown:
190 ; CHECK-NEXT:            %l = load i32, ptr %gep.mul.2, align 4 ->
191 ; CHECK-NEXT:            store i32 %add, ptr %gep, align 4
192 ; CHECK-EMPTY:
193 ; CHECK-NEXT:      Run-time memory checks:
194 ; CHECK-NEXT:      Grouped accesses:
195 ; CHECK-EMPTY:
196 ; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
197 ; CHECK-NEXT:      SCEV assumptions:
198 ; CHECK-EMPTY:
199 ; CHECK-NEXT:      Expressions re-written:
201 entry:
202   br label %loop
204 loop:
205   %iv.1 = phi i64 [ 0, %entry ], [ %iv.1.next, %loop ]
206   %iv.2 = phi i64 [ 300, %entry ], [ %iv.2.next, %loop ]
207   %gep.mul.2 = getelementptr inbounds i32, ptr %A, i64 %iv.1
208   %l = load i32, ptr %gep.mul.2, align 4
209   %add = add nsw i32 %l, 5
210   %gep = getelementptr inbounds i32, ptr %A, i64 %iv.2
211   store i32 %add, ptr %gep, align 4
212   %iv.1.next = add nuw nsw i64 %iv.1, 1
213   %iv.2.next = add nsw i64 %iv.2, -1
214   %exitcond.not = icmp eq i64 %iv.1.next, 256
215   br i1 %exitcond.not, label %exit, label %loop
217 exit:
218   ret void
221 define void @strides_with_different_directions_2(ptr %A) {
222 ; CHECK-LABEL: 'strides_with_different_directions_2'
223 ; CHECK-NEXT:    loop:
224 ; 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
225 ; CHECK-NEXT:  Unknown data dependence.
226 ; CHECK-NEXT:      Dependences:
227 ; CHECK-NEXT:        Unknown:
228 ; CHECK-NEXT:            %l = load i32, ptr %gep.mul.2, align 4 ->
229 ; CHECK-NEXT:            store i32 %add, ptr %gep, align 4
230 ; CHECK-EMPTY:
231 ; CHECK-NEXT:      Run-time memory checks:
232 ; CHECK-NEXT:      Grouped accesses:
233 ; CHECK-EMPTY:
234 ; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
235 ; CHECK-NEXT:      SCEV assumptions:
236 ; CHECK-EMPTY:
237 ; CHECK-NEXT:      Expressions re-written:
239 entry:
240   br label %loop
242 loop:
243   %iv.1 = phi i64 [ 0, %entry ], [ %iv.1.next, %loop ]
244   %iv.2 = phi i64 [ 300, %entry ], [ %iv.2.next, %loop ]
245   %gep.mul.2 = getelementptr inbounds i32, ptr %A, i64 %iv.2
246   %l = load i32, ptr %gep.mul.2, align 4
247   %add = add nsw i32 %l, 5
248   %gep = getelementptr inbounds i32, ptr %A, i64 %iv.1
249   store i32 %add, ptr %gep, align 4
250   %iv.1.next = add nuw nsw i64 %iv.1, 1
251   %iv.2.next = add nsw i64 %iv.2, -1
252   %exitcond.not = icmp eq i64 %iv.1.next, 256
253   br i1 %exitcond.not, label %exit, label %loop
255 exit:
256   ret void
259 define void @strides_with_different_directions_3(ptr %A) {
260 ; CHECK-LABEL: 'strides_with_different_directions_3'
261 ; CHECK-NEXT:    loop:
262 ; 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
263 ; CHECK-NEXT:  Unknown data dependence.
264 ; CHECK-NEXT:      Dependences:
265 ; CHECK-NEXT:        Unknown:
266 ; CHECK-NEXT:            %l = load i32, ptr %gep.mul.2, align 4 ->
267 ; CHECK-NEXT:            store i32 %add, ptr %gep, align 4
268 ; CHECK-EMPTY:
269 ; CHECK-NEXT:      Run-time memory checks:
270 ; CHECK-NEXT:      Grouped accesses:
271 ; CHECK-EMPTY:
272 ; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
273 ; CHECK-NEXT:      SCEV assumptions:
274 ; CHECK-EMPTY:
275 ; CHECK-NEXT:      Expressions re-written:
277 entry:
278   br label %loop
280 loop:
281   %iv.1 = phi i64 [ 0, %entry ], [ %iv.1.next, %loop ]
282   %iv.2 = phi i64 [ 600, %entry ], [ %iv.2.next, %loop ]
283   %gep.mul.2 = getelementptr inbounds i32, ptr %A, i64 %iv.1
284   %l = load i32, ptr %gep.mul.2, align 4
285   %add = add nsw i32 %l, 5
286   %gep = getelementptr inbounds i32, ptr %A, i64 %iv.2
287   store i32 %add, ptr %gep, align 4
288   %iv.1.next = add nuw nsw i64 %iv.1, 1
289   %iv.2.next = add nsw i64 %iv.2, -2
290   %exitcond.not = icmp eq i64 %iv.1.next, 256
291   br i1 %exitcond.not, label %exit, label %loop
293 exit:
294   ret void
297 define void @strides_with_different_directions_4(ptr %A) {
298 ; CHECK-LABEL: 'strides_with_different_directions_4'
299 ; CHECK-NEXT:    loop:
300 ; 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
301 ; CHECK-NEXT:  Unknown data dependence.
302 ; CHECK-NEXT:      Dependences:
303 ; CHECK-NEXT:        Unknown:
304 ; CHECK-NEXT:            %l = load i32, ptr %gep.mul.2, align 4 ->
305 ; CHECK-NEXT:            store i32 %add, ptr %gep, align 4
306 ; CHECK-EMPTY:
307 ; CHECK-NEXT:      Run-time memory checks:
308 ; CHECK-NEXT:      Grouped accesses:
309 ; CHECK-EMPTY:
310 ; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
311 ; CHECK-NEXT:      SCEV assumptions:
312 ; CHECK-EMPTY:
313 ; CHECK-NEXT:      Expressions re-written:
315 entry:
316   br label %loop
318 loop:
319   %iv.1 = phi i64 [ 0, %entry ], [ %iv.1.next, %loop ]
320   %iv.2 = phi i64 [ 600, %entry ], [ %iv.2.next, %loop ]
321   %gep.mul.2 = getelementptr inbounds i32, ptr %A, i64 %iv.2
322   %l = load i32, ptr %gep.mul.2, align 4
323   %add = add nsw i32 %l, 5
324   %gep = getelementptr inbounds i32, ptr %A, i64 %iv.1
325   store i32 %add, ptr %gep, align 4
326   %iv.1.next = add nuw nsw i64 %iv.1, 1
327   %iv.2.next = add nsw i64 %iv.2, -2
328   %exitcond.not = icmp eq i64 %iv.1.next, 256
329   br i1 %exitcond.not, label %exit, label %loop
331 exit:
332   ret void
335 define void @non_constant_strides_with_different_directions_1(ptr %A) {
336 ; CHECK-LABEL: 'non_constant_strides_with_different_directions_1'
337 ; CHECK-NEXT:    loop:
338 ; 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
339 ; CHECK-NEXT:  Unknown data dependence.
340 ; CHECK-NEXT:      Dependences:
341 ; CHECK-NEXT:        Unknown:
342 ; CHECK-NEXT:            %l = load i32, ptr %gep.mul.2, align 4 ->
343 ; CHECK-NEXT:            store i32 %add, ptr %gep, align 4
344 ; CHECK-EMPTY:
345 ; CHECK-NEXT:      Run-time memory checks:
346 ; CHECK-NEXT:      Grouped accesses:
347 ; CHECK-EMPTY:
348 ; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
349 ; CHECK-NEXT:      SCEV assumptions:
350 ; CHECK-EMPTY:
351 ; CHECK-NEXT:      Expressions re-written:
353 entry:
354   br label %loop
356 loop:
357   %iv.1 = phi i64 [ 0, %entry ], [ %iv.1.next, %loop ]
358   %iv.2 = phi i64 [ 300, %entry ], [ %iv.2.next, %loop ]
359   %iv.mul.2 = shl nuw nsw i64 %iv.1, 1
360   %gep.mul.2 = getelementptr inbounds i32, ptr %A, i64 %iv.mul.2
361   %l = load i32, ptr %gep.mul.2, align 4
362   %add = add nsw i32 %l, 5
363   %gep = getelementptr inbounds i32, ptr %A, i64 %iv.2
364   store i32 %add, ptr %gep, align 4
365   %iv.1.next = add nuw nsw i64 %iv.1, 1
366   %iv.2.next = add nsw i64 %iv.2, -1
367   %exitcond.not = icmp eq i64 %iv.1.next, 256
368   br i1 %exitcond.not, label %exit, label %loop
370 exit:
371   ret void
374 define void @non_constant_strides_with_different_directions_2(ptr %A) {
375 ; CHECK-LABEL: 'non_constant_strides_with_different_directions_2'
376 ; CHECK-NEXT:    loop:
377 ; 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
378 ; CHECK-NEXT:  Unknown data dependence.
379 ; CHECK-NEXT:      Dependences:
380 ; CHECK-NEXT:        Unknown:
381 ; CHECK-NEXT:            %l = load i32, ptr %gep.mul.2, align 4 ->
382 ; CHECK-NEXT:            store i32 %add, ptr %gep, align 4
383 ; CHECK-EMPTY:
384 ; CHECK-NEXT:      Run-time memory checks:
385 ; CHECK-NEXT:      Grouped accesses:
386 ; CHECK-EMPTY:
387 ; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
388 ; CHECK-NEXT:      SCEV assumptions:
389 ; CHECK-EMPTY:
390 ; CHECK-NEXT:      Expressions re-written:
392 entry:
393   br label %loop
395 loop:
396   %iv.1 = phi i64 [ 0, %entry ], [ %iv.1.next, %loop ]
397   %iv.2 = phi i64 [ 300, %entry ], [ %iv.2.next, %loop ]
398   %iv.mul.2 = shl nuw nsw i64 %iv.2, 1
399   %gep.mul.2 = getelementptr inbounds i32, ptr %A, i64 %iv.mul.2
400   %l = load i32, ptr %gep.mul.2, align 4
401   %add = add nsw i32 %l, 5
402   %gep = getelementptr inbounds i32, ptr %A, i64 %iv.1
403   store i32 %add, ptr %gep, align 4
404   %iv.1.next = add nuw nsw i64 %iv.1, 1
405   %iv.2.next = add nsw i64 %iv.2, -1
406   %exitcond.not = icmp eq i64 %iv.1.next, 256
407   br i1 %exitcond.not, label %exit, label %loop
409 exit:
410   ret void