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'
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
17 ; CHECK-NEXT: Run-time memory checks:
18 ; CHECK-NEXT: Grouped accesses:
20 ; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
21 ; CHECK-NEXT: SCEV assumptions:
23 ; CHECK-NEXT: Expressions re-written:
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
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'
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
53 ; CHECK-NEXT: Run-time memory checks:
54 ; CHECK-NEXT: Grouped accesses:
56 ; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
57 ; CHECK-NEXT: SCEV assumptions:
59 ; CHECK-NEXT: Expressions re-written:
62 %A.3 = getelementptr inbounds i8, ptr %A, i64 3
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
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'
84 ; CHECK-NEXT: Report: cannot identify array bounds
85 ; CHECK-NEXT: Dependences:
86 ; CHECK-NEXT: Run-time memory checks:
87 ; CHECK-NEXT: Grouped accesses:
89 ; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
90 ; CHECK-NEXT: SCEV assumptions:
92 ; CHECK-NEXT: Expressions re-written:
95 %c = icmp sgt i64 %scale, 0
96 call void @llvm.assume(i1 %c)
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
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'
118 ; CHECK-NEXT: Report: cannot identify array bounds
119 ; CHECK-NEXT: Dependences:
120 ; CHECK-NEXT: Run-time memory checks:
121 ; CHECK-NEXT: Grouped accesses:
123 ; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
124 ; CHECK-NEXT: SCEV assumptions:
126 ; CHECK-NEXT: Expressions re-written:
129 %A.3 = getelementptr inbounds i8, ptr %A, i64 3
130 %c = icmp sgt i64 %scale, 0
131 call void @llvm.assume(i1 %c)
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
150 define void @different_non_constant_strides_not_known_forward(ptr %A, i64 %scale) {
151 ; CHECK-LABEL: 'different_non_constant_strides_not_known_forward'
153 ; CHECK-NEXT: Report: cannot identify array bounds
154 ; CHECK-NEXT: Dependences:
155 ; CHECK-NEXT: Run-time memory checks:
156 ; CHECK-NEXT: Grouped accesses:
158 ; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
159 ; CHECK-NEXT: SCEV assumptions:
161 ; CHECK-NEXT: Expressions re-written:
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
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'
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
193 ; CHECK-NEXT: Run-time memory checks:
194 ; CHECK-NEXT: Grouped accesses:
196 ; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
197 ; CHECK-NEXT: SCEV assumptions:
199 ; CHECK-NEXT: Expressions re-written:
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
221 define void @strides_with_different_directions_2(ptr %A) {
222 ; CHECK-LABEL: 'strides_with_different_directions_2'
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
231 ; CHECK-NEXT: Run-time memory checks:
232 ; CHECK-NEXT: Grouped accesses:
234 ; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
235 ; CHECK-NEXT: SCEV assumptions:
237 ; CHECK-NEXT: Expressions re-written:
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
259 define void @strides_with_different_directions_3(ptr %A) {
260 ; CHECK-LABEL: 'strides_with_different_directions_3'
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
269 ; CHECK-NEXT: Run-time memory checks:
270 ; CHECK-NEXT: Grouped accesses:
272 ; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
273 ; CHECK-NEXT: SCEV assumptions:
275 ; CHECK-NEXT: Expressions re-written:
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
297 define void @strides_with_different_directions_4(ptr %A) {
298 ; CHECK-LABEL: 'strides_with_different_directions_4'
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
307 ; CHECK-NEXT: Run-time memory checks:
308 ; CHECK-NEXT: Grouped accesses:
310 ; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
311 ; CHECK-NEXT: SCEV assumptions:
313 ; CHECK-NEXT: Expressions re-written:
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
335 define void @non_constant_strides_with_different_directions_1(ptr %A) {
336 ; CHECK-LABEL: 'non_constant_strides_with_different_directions_1'
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
345 ; CHECK-NEXT: Run-time memory checks:
346 ; CHECK-NEXT: Grouped accesses:
348 ; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
349 ; CHECK-NEXT: SCEV assumptions:
351 ; CHECK-NEXT: Expressions re-written:
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
374 define void @non_constant_strides_with_different_directions_2(ptr %A) {
375 ; CHECK-LABEL: 'non_constant_strides_with_different_directions_2'
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
384 ; CHECK-NEXT: Run-time memory checks:
385 ; CHECK-NEXT: Grouped accesses:
387 ; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
388 ; CHECK-NEXT: SCEV assumptions:
390 ; CHECK-NEXT: Expressions re-written:
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