xref: /llvm-project/llvm/test/Analysis/LoopAccessAnalysis/non-constant-strides-backward.ll (revision 234cc40adc610a55d1a5a2fe798a9dd07b993f0c)
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:o-i64:64-i128:128-n32:64-S128"
5
6declare void @llvm.assume(i1)
7
8define void @different_non_constant_strides_known_backward(ptr %A) {
9; CHECK-LABEL: 'different_non_constant_strides_known_backward'
10; CHECK-NEXT:    loop:
11; 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
12; CHECK-NEXT:  Unknown data dependence.
13; CHECK-NEXT:      Dependences:
14; CHECK-NEXT:        Unknown:
15; CHECK-NEXT:            %l = load i32, ptr %gep, align 4 ->
16; CHECK-NEXT:            store i32 %add, ptr %gep.mul.2, align 4
17; CHECK-EMPTY:
18; CHECK-NEXT:      Run-time memory checks:
19; CHECK-NEXT:      Grouped accesses:
20; CHECK-EMPTY:
21; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
22; CHECK-NEXT:      SCEV assumptions:
23; CHECK-EMPTY:
24; CHECK-NEXT:      Expressions re-written:
25;
26entry:
27  br label %loop
28
29loop:
30  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
31  %gep = getelementptr inbounds i32, ptr %A, i64 %iv
32  %l = load i32, ptr %gep, align 4
33  %add = add nsw i32 %l, 5
34  %iv.mul.2 = shl nuw nsw i64 %iv, 1
35  %gep.mul.2 = getelementptr inbounds i32, ptr %A, i64 %iv.mul.2
36  store i32 %add, ptr %gep.mul.2, align 4
37  %iv.next = add nuw nsw i64 %iv, 1
38  %exitcond.not = icmp eq i64 %iv.next, 256
39  br i1 %exitcond.not, label %exit, label %loop
40
41exit:
42  ret void
43}
44
45define void @different_non_constant_strides_known_backward_distance_larger_than_trip_count(ptr %A) {
46; CHECK-LABEL: 'different_non_constant_strides_known_backward_distance_larger_than_trip_count'
47; CHECK-NEXT:    loop:
48; 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
49; CHECK-NEXT:  Unknown data dependence.
50; CHECK-NEXT:      Dependences:
51; CHECK-NEXT:        Unknown:
52; CHECK-NEXT:            %l = load i32, ptr %gep, align 4 ->
53; CHECK-NEXT:            store i32 %add, ptr %gep.mul.2, align 4
54; CHECK-EMPTY:
55; CHECK-NEXT:      Run-time memory checks:
56; CHECK-NEXT:      Grouped accesses:
57; CHECK-EMPTY:
58; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
59; CHECK-NEXT:      SCEV assumptions:
60; CHECK-EMPTY:
61; CHECK-NEXT:      Expressions re-written:
62;
63entry:
64  %A.1024 = getelementptr inbounds i8, ptr %A, i64 1024
65  br label %loop
66
67loop:
68  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
69  %gep = getelementptr inbounds i32, ptr %A, i64 %iv
70  %l = load i32, ptr %gep, align 4
71  %add = add nsw i32 %l, 5
72  %iv.mul.2 = shl nuw nsw i64 %iv, 1
73  %gep.mul.2 = getelementptr inbounds i32, ptr %A.1024, i64 %iv.mul.2
74  store i32 %add, ptr %gep.mul.2, align 4
75  %iv.next = add nuw nsw i64 %iv, 1
76  %exitcond.not = icmp eq i64 %iv.next, 256
77  br i1 %exitcond.not, label %exit, label %loop
78
79exit:
80  ret void
81}
82
83define void @different_non_constant_strides_known_backward_min_distance_16(ptr %A) {
84; CHECK-LABEL: 'different_non_constant_strides_known_backward_min_distance_16'
85; CHECK-NEXT:    loop:
86; 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
87; CHECK-NEXT:  Unknown data dependence.
88; CHECK-NEXT:      Dependences:
89; CHECK-NEXT:        Unknown:
90; CHECK-NEXT:            %l = load i32, ptr %gep, align 4 ->
91; CHECK-NEXT:            store i32 %add, ptr %gep.mul.2, align 4
92; CHECK-EMPTY:
93; CHECK-NEXT:      Run-time memory checks:
94; CHECK-NEXT:      Grouped accesses:
95; CHECK-EMPTY:
96; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
97; CHECK-NEXT:      SCEV assumptions:
98; CHECK-EMPTY:
99; CHECK-NEXT:      Expressions re-written:
100;
101entry:
102  %A.16 = getelementptr inbounds i8, ptr %A, i64 16
103  br label %loop
104
105loop:
106  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
107  %gep = getelementptr inbounds i32, ptr %A, i64 %iv
108  %l = load i32, ptr %gep, align 4
109  %add = add nsw i32 %l, 5
110  %iv.mul.2 = shl nuw nsw i64 %iv, 1
111  %gep.mul.2 = getelementptr inbounds i32, ptr %A.16, i64 %iv.mul.2
112  store i32 %add, ptr %gep.mul.2, align 4
113  %iv.next = add nuw nsw i64 %iv, 1
114  %exitcond.not = icmp eq i64 %iv.next, 256
115  br i1 %exitcond.not, label %exit, label %loop
116
117exit:
118  ret void
119}
120
121define void @different_non_constant_strides_known_backward_min_distance_15(ptr %A) {
122; CHECK-LABEL: 'different_non_constant_strides_known_backward_min_distance_15'
123; CHECK-NEXT:    loop:
124; 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
125; CHECK-NEXT:  Unknown data dependence.
126; CHECK-NEXT:      Dependences:
127; CHECK-NEXT:        Unknown:
128; CHECK-NEXT:            %l = load i32, ptr %gep, align 4 ->
129; CHECK-NEXT:            store i32 %add, ptr %gep.mul.2, align 4
130; CHECK-EMPTY:
131; CHECK-NEXT:      Run-time memory checks:
132; CHECK-NEXT:      Grouped accesses:
133; CHECK-EMPTY:
134; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
135; CHECK-NEXT:      SCEV assumptions:
136; CHECK-EMPTY:
137; CHECK-NEXT:      Expressions re-written:
138;
139entry:
140  %A.15 = getelementptr inbounds i8, ptr %A, i64 15
141  br label %loop
142
143loop:
144  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
145  %gep = getelementptr inbounds i32, ptr %A, i64 %iv
146  %l = load i32, ptr %gep, align 4
147  %add = add nsw i32 %l, 5
148  %iv.mul.2 = shl nuw nsw i64 %iv, 1
149  %gep.mul.2 = getelementptr inbounds i32, ptr %A.15, i64 %iv.mul.2
150  store i32 %add, ptr %gep.mul.2, align 4
151  %iv.next = add nuw nsw i64 %iv, 1
152  %exitcond.not = icmp eq i64 %iv.next, 256
153  br i1 %exitcond.not, label %exit, label %loop
154
155exit:
156  ret void
157}
158
159define void @different_non_constant_strides_known_backward_min_distance_8(ptr %A) {
160; CHECK-LABEL: 'different_non_constant_strides_known_backward_min_distance_8'
161; CHECK-NEXT:    loop:
162; 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
163; CHECK-NEXT:  Unknown data dependence.
164; CHECK-NEXT:      Dependences:
165; CHECK-NEXT:        Unknown:
166; CHECK-NEXT:            %l = load i32, ptr %gep, align 4 ->
167; CHECK-NEXT:            store i32 %add, ptr %gep.mul.2, align 4
168; CHECK-EMPTY:
169; CHECK-NEXT:      Run-time memory checks:
170; CHECK-NEXT:      Grouped accesses:
171; CHECK-EMPTY:
172; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
173; CHECK-NEXT:      SCEV assumptions:
174; CHECK-EMPTY:
175; CHECK-NEXT:      Expressions re-written:
176;
177entry:
178  %A.8 = getelementptr inbounds i8, ptr %A, i64 8
179  br label %loop
180
181loop:
182  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
183  %gep = getelementptr inbounds i32, ptr %A, i64 %iv
184  %l = load i32, ptr %gep, align 4
185  %add = add nsw i32 %l, 5
186  %iv.mul.2 = shl nuw nsw i64 %iv, 1
187  %gep.mul.2 = getelementptr inbounds i32, ptr %A.8, i64 %iv.mul.2
188  store i32 %add, ptr %gep.mul.2, align 4
189  %iv.next = add nuw nsw i64 %iv, 1
190  %exitcond.not = icmp eq i64 %iv.next, 256
191  br i1 %exitcond.not, label %exit, label %loop
192
193exit:
194  ret void
195}
196
197define void @different_non_constant_strides_known_backward_min_distance_3(ptr %A) {
198; CHECK-LABEL: 'different_non_constant_strides_known_backward_min_distance_3'
199; CHECK-NEXT:    loop:
200; 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
201; CHECK-NEXT:  Unknown data dependence.
202; CHECK-NEXT:      Dependences:
203; CHECK-NEXT:        Unknown:
204; CHECK-NEXT:            %l = load i32, ptr %gep, align 4 ->
205; CHECK-NEXT:            store i32 %add, ptr %gep.mul.2, align 4
206; CHECK-EMPTY:
207; CHECK-NEXT:      Run-time memory checks:
208; CHECK-NEXT:      Grouped accesses:
209; CHECK-EMPTY:
210; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
211; CHECK-NEXT:      SCEV assumptions:
212; CHECK-EMPTY:
213; CHECK-NEXT:      Expressions re-written:
214;
215entry:
216  %A.3 = getelementptr inbounds i8, ptr %A, i64 3
217  br label %loop
218
219loop:
220  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
221  %gep = getelementptr inbounds i32, ptr %A, i64 %iv
222  %l = load i32, ptr %gep, align 4
223  %add = add nsw i32 %l, 5
224  %iv.mul.2 = shl nuw nsw i64 %iv, 1
225  %gep.mul.2 = getelementptr inbounds i32, ptr %A.3, i64 %iv.mul.2
226  store i32 %add, ptr %gep.mul.2, align 4
227  %iv.next = add nuw nsw i64 %iv, 1
228  %exitcond.not = icmp eq i64 %iv.next, 256
229  br i1 %exitcond.not, label %exit, label %loop
230
231exit:
232  ret void
233}
234
235define void @different_non_constant_strides_known_backward_via_assume(ptr %A, i64 %scale) {
236; CHECK-LABEL: 'different_non_constant_strides_known_backward_via_assume'
237; CHECK-NEXT:    loop:
238; CHECK-NEXT:      Report: cannot identify array bounds
239; CHECK-NEXT:      Dependences:
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  %c = icmp sgt i64 %scale, 0
250  call void @llvm.assume(i1 %c)
251  br label %loop
252
253loop:
254  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
255  %gep = getelementptr inbounds i32, ptr %A, i64 %iv
256  %l = load i32, ptr %gep, align 4
257  %add = add nsw i32 %l, 5
258  %iv.mul.2 = shl nuw nsw i64 %iv, %scale
259  %gep.mul.2 = getelementptr inbounds i32, ptr %A, i64 %iv.mul.2
260  store i32 %add, ptr %gep.mul.2, align 4
261  %iv.next = add nuw nsw i64 %iv, 1
262  %exitcond.not = icmp eq i64 %iv.next, 256
263  br i1 %exitcond.not, label %exit, label %loop
264
265exit:
266  ret void
267}
268
269define void @different_non_constant_strides_known_backward_via_assume_distance_larger_than_trip_count(ptr %A, i64 %scale) {
270; CHECK-LABEL: 'different_non_constant_strides_known_backward_via_assume_distance_larger_than_trip_count'
271; CHECK-NEXT:    loop:
272; CHECK-NEXT:      Report: cannot identify array bounds
273; CHECK-NEXT:      Dependences:
274; CHECK-NEXT:      Run-time memory checks:
275; CHECK-NEXT:      Grouped accesses:
276; CHECK-EMPTY:
277; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
278; CHECK-NEXT:      SCEV assumptions:
279; CHECK-EMPTY:
280; CHECK-NEXT:      Expressions re-written:
281;
282entry:
283  %A.1024 = getelementptr inbounds i8, ptr %A, i64 1024
284  %c = icmp sgt i64 %scale, 0
285  call void @llvm.assume(i1 %c)
286  br label %loop
287
288loop:
289  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
290  %gep = getelementptr inbounds i32, ptr %A, i64 %iv
291  %l = load i32, ptr %gep, align 4
292  %add = add nsw i32 %l, 5
293  %iv.mul.2 = shl nuw nsw i64 %iv, %scale
294  %gep.mul.2 = getelementptr inbounds i32, ptr %A.1024, i64 %iv.mul.2
295  store i32 %add, ptr %gep.mul.2, align 4
296  %iv.next = add nuw nsw i64 %iv, 1
297  %exitcond.not = icmp eq i64 %iv.next, 256
298  br i1 %exitcond.not, label %exit, label %loop
299
300exit:
301  ret void
302}
303
304define void @different_non_constant_strides_known_backward_via_assume_min_distance_3(ptr %A, i64 %scale) {
305; CHECK-LABEL: 'different_non_constant_strides_known_backward_via_assume_min_distance_3'
306; CHECK-NEXT:    loop:
307; CHECK-NEXT:      Report: cannot identify array bounds
308; CHECK-NEXT:      Dependences:
309; CHECK-NEXT:      Run-time memory checks:
310; CHECK-NEXT:      Grouped accesses:
311; CHECK-EMPTY:
312; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
313; CHECK-NEXT:      SCEV assumptions:
314; CHECK-EMPTY:
315; CHECK-NEXT:      Expressions re-written:
316;
317entry:
318  %A.3 = getelementptr inbounds i8, ptr %A, i64 3
319  %c = icmp sgt i64 %scale, 0
320  call void @llvm.assume(i1 %c)
321  br label %loop
322
323loop:
324  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
325  %gep = getelementptr inbounds i32, ptr %A, i64 %iv
326  %l = load i32, ptr %gep, align 4
327  %add = add nsw i32 %l, 5
328  %iv.mul.2 = shl nuw nsw i64 %iv, %scale
329  %gep.mul.2 = getelementptr inbounds i32, ptr %A.3, i64 %iv.mul.2
330  store i32 %add, ptr %gep.mul.2, align 4
331  %iv.next = add nuw nsw i64 %iv, 1
332  %exitcond.not = icmp eq i64 %iv.next, 256
333  br i1 %exitcond.not, label %exit, label %loop
334
335exit:
336  ret void
337}
338
339define void @different_non_constant_strides_not_known_backward(ptr %A, i64 %scale) {
340; CHECK-LABEL: 'different_non_constant_strides_not_known_backward'
341; CHECK-NEXT:    loop:
342; CHECK-NEXT:      Report: cannot identify array bounds
343; CHECK-NEXT:      Dependences:
344; CHECK-NEXT:      Run-time memory checks:
345; CHECK-NEXT:      Grouped accesses:
346; CHECK-EMPTY:
347; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
348; CHECK-NEXT:      SCEV assumptions:
349; CHECK-EMPTY:
350; CHECK-NEXT:      Expressions re-written:
351;
352entry:
353  br label %loop
354
355loop:
356  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
357  %gep = getelementptr inbounds i32, ptr %A, i64 %iv
358  %l = load i32, ptr %gep, align 4
359  %add = add nsw i32 %l, 5
360  %iv.mul.2 = shl nuw nsw i64 %iv, %scale
361  %gep.mul.2 = getelementptr inbounds i32, ptr %A, i64 %iv.mul.2
362  store i32 %add, ptr %gep.mul.2, align 4
363  %iv.next = add nuw nsw i64 %iv, 1
364  %exitcond.not = icmp eq i64 %iv.next, 256
365  br i1 %exitcond.not, label %exit, label %loop
366
367exit:
368  ret void
369}
370