xref: /llvm-project/llvm/test/Analysis/LoopAccessAnalysis/no-dep-via-loop-guards.ll (revision dec4cfdb09596f34f17a653ad405ab2551b09039)
1; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 5
2; RUN: opt -passes='print<access-info>' -disable-output < %s  2>&1 | FileCheck %s
3
4; Loop guard for %off guarantees the accesses in the loop do not overlap.
5define void @access_after_via_loop_guard(ptr %a, i64 %off) {
6; CHECK-LABEL: 'access_after_via_loop_guard'
7; CHECK-NEXT:    loop:
8; CHECK-NEXT:      Memory dependences are safe
9; CHECK-NEXT:      Dependences:
10; CHECK-NEXT:      Run-time memory checks:
11; CHECK-NEXT:      Grouped accesses:
12; CHECK-EMPTY:
13; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
14; CHECK-NEXT:      SCEV assumptions:
15; CHECK-EMPTY:
16; CHECK-NEXT:      Expressions re-written:
17;
18  %c = icmp eq i64 %off, 100
19  br i1 %c, label %ph, label %exit
20
21ph:
22  %gep.after = getelementptr inbounds nuw i32, ptr %a, i64 %off
23  br label %loop
24
25loop:
26  %iv = phi i64 [ 0, %ph ], [ %iv.next, %loop ]
27  %l = load i32 , ptr %gep.after, align 4
28  %add = add i32 %l, %l
29  %gep = getelementptr inbounds i32, ptr %a, i64 %iv
30  store i32 %add, ptr %gep, align 4
31  %iv.next = add nsw nuw i64 %iv, 1
32  %ec = icmp eq i64 %iv.next, 100
33  br i1 %ec, label %exit, label %loop
34
35exit:
36  ret void
37}
38
39; Loop guard for %off guarantees the accesses in the loop do not overlap.
40; TODO: currently missed by LAA
41define void @access_after_via_loop_guard_sge(ptr %a, i64 %off) {
42; CHECK-LABEL: 'access_after_via_loop_guard_sge'
43; CHECK-NEXT:    loop:
44; 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
45; CHECK-NEXT:  Unknown data dependence.
46; CHECK-NEXT:      Dependences:
47; CHECK-NEXT:        Unknown:
48; CHECK-NEXT:            %l = load i32, ptr %gep.after, align 4 ->
49; CHECK-NEXT:            store i32 %add, ptr %gep, align 4
50; CHECK-EMPTY:
51; CHECK-NEXT:      Run-time memory checks:
52; CHECK-NEXT:      Grouped accesses:
53; CHECK-EMPTY:
54; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
55; CHECK-NEXT:      SCEV assumptions:
56; CHECK-EMPTY:
57; CHECK-NEXT:      Expressions re-written:
58;
59  %c = icmp sge i64 %off, 100
60  br i1 %c, label %ph, label %exit
61
62ph:
63  %gep.after = getelementptr inbounds nuw i32, ptr %a, i64 %off
64  br label %loop
65
66loop:
67  %iv = phi i64 [ 0, %ph ], [ %iv.next, %loop ]
68  %l = load i32 , ptr %gep.after, align 4
69  %add = add i32 %l, %l
70  %gep = getelementptr inbounds i32, ptr %a, i64 %iv
71  store i32 %add, ptr %gep, align 4
72  %iv.next = add nsw nuw i64 %iv, 1
73  %ec = icmp eq i64 %iv.next, 100
74  br i1 %ec, label %exit, label %loop
75
76exit:
77  ret void
78}
79
80define void @access_after_via_loop_guard_99(ptr %a, i64 %off) {
81; CHECK-LABEL: 'access_after_via_loop_guard_99'
82; CHECK-NEXT:    loop:
83; 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
84; CHECK-NEXT:  Unknown data dependence.
85; CHECK-NEXT:      Dependences:
86; CHECK-NEXT:        Unknown:
87; CHECK-NEXT:            %l = load i32, ptr %gep.after, align 4 ->
88; CHECK-NEXT:            store i32 %add, ptr %gep, align 4
89; CHECK-EMPTY:
90; CHECK-NEXT:      Run-time memory checks:
91; CHECK-NEXT:      Grouped accesses:
92; CHECK-EMPTY:
93; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
94; CHECK-NEXT:      SCEV assumptions:
95; CHECK-EMPTY:
96; CHECK-NEXT:      Expressions re-written:
97;
98  %c = icmp eq i64 %off, 99
99  br i1 %c, label %ph, label %exit
100
101ph:
102  %gep.after = getelementptr inbounds nuw i32, ptr %a, i64 %off
103  br label %loop
104
105loop:
106  %iv = phi i64 [ 0, %ph ], [ %iv.next, %loop ]
107  %l = load i32 , ptr %gep.after, align 4
108  %add = add i32 %l, %l
109  %gep = getelementptr inbounds i32, ptr %a, i64 %iv
110  store i32 %add, ptr %gep, align 4
111  %iv.next = add nsw nuw i64 %iv, 1
112  %ec = icmp eq i64 %iv.next, 100
113  br i1 %ec, label %exit, label %loop
114
115exit:
116  ret void
117}
118
119; Loop guard for %off guarantees the accesses in the loop do not overlap.
120; TODO: currently missed by LAA
121define void @access_after_via_loop_guard_sge_99(ptr %a, i64 %off) {
122; CHECK-LABEL: 'access_after_via_loop_guard_sge_99'
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.after, align 4 ->
129; CHECK-NEXT:            store i32 %add, ptr %gep, 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;
139  %c = icmp sge i64 %off, 99
140  br i1 %c, label %ph, label %exit
141
142ph:
143  %gep.after = getelementptr inbounds nuw i32, ptr %a, i64 %off
144  br label %loop
145
146loop:
147  %iv = phi i64 [ 0, %ph ], [ %iv.next, %loop ]
148  %l = load i32 , ptr %gep.after, align 4
149  %add = add i32 %l, %l
150  %gep = getelementptr inbounds i32, ptr %a, i64 %iv
151  store i32 %add, ptr %gep, align 4
152  %iv.next = add nsw nuw i64 %iv, 1
153  %ec = icmp eq i64 %iv.next, 100
154  br i1 %ec, label %exit, label %loop
155
156exit:
157  ret void
158}
159
160define void @access_after_via_loop_guard_uge(ptr %a, i64 %off) {
161; CHECK-LABEL: 'access_after_via_loop_guard_uge'
162; CHECK-NEXT:    loop:
163; 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
164; CHECK-NEXT:  Unknown data dependence.
165; CHECK-NEXT:      Dependences:
166; CHECK-NEXT:        Unknown:
167; CHECK-NEXT:            %l = load i32, ptr %gep.after, align 4 ->
168; CHECK-NEXT:            store i32 %add, ptr %gep, align 4
169; CHECK-EMPTY:
170; CHECK-NEXT:      Run-time memory checks:
171; CHECK-NEXT:      Grouped accesses:
172; CHECK-EMPTY:
173; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
174; CHECK-NEXT:      SCEV assumptions:
175; CHECK-EMPTY:
176; CHECK-NEXT:      Expressions re-written:
177;
178  %c = icmp uge i64 %off, 100
179  br i1 %c, label %ph, label %exit
180
181ph:
182  %gep.after = getelementptr inbounds nuw i32, ptr %a, i64 %off
183  br label %loop
184
185loop:
186  %iv = phi i64 [ 0, %ph ], [ %iv.next, %loop ]
187  %l = load i32 , ptr %gep.after, align 4
188  %add = add i32 %l, %l
189  %gep = getelementptr inbounds i32, ptr %a, i64 %iv
190  store i32 %add, ptr %gep, align 4
191  %iv.next = add nsw nuw i64 %iv, 1
192  %ec = icmp eq i64 %iv.next, 100
193  br i1 %ec, label %exit, label %loop
194
195exit:
196  ret void
197}
198
199; Loop guard for %off guarantees the accesses in the loop do not overlap.
200define void @access_after_via_loop_guard_eq_loop_cond(ptr %a, i64 %off) {
201; CHECK-LABEL: 'access_after_via_loop_guard_eq_loop_cond'
202; CHECK-NEXT:    loop:
203; CHECK-NEXT:      Memory dependences are safe
204; CHECK-NEXT:      Dependences:
205; CHECK-NEXT:      Run-time memory checks:
206; CHECK-NEXT:      Grouped accesses:
207; CHECK-EMPTY:
208; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
209; CHECK-NEXT:      SCEV assumptions:
210; CHECK-EMPTY:
211; CHECK-NEXT:      Expressions re-written:
212;
213  %c = icmp eq i64 %off, 100
214  br i1 %c, label %ph, label %exit
215
216ph:
217  %gep.after = getelementptr inbounds nuw i32, ptr %a, i64 100
218  br label %loop
219
220loop:
221  %iv = phi i64 [ 0, %ph ], [ %iv.next, %loop ]
222  %l = load i32 , ptr %gep.after, align 4
223  %add = add i32 %l, %l
224  %gep = getelementptr inbounds i32, ptr %a, i64 %iv
225  store i32 %add, ptr %gep, align 4
226  %iv.next = add nsw nuw i64 %iv, 1
227  %ec = icmp eq i64 %iv.next, %off
228  br i1 %ec, label %exit, label %loop
229
230exit:
231  ret void
232}
233
234define void @access_after_via_loop_guard_eq_loop_cond_100(ptr %a, i64 %off) {
235; CHECK-LABEL: 'access_after_via_loop_guard_eq_loop_cond_100'
236; CHECK-NEXT:    loop:
237; 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
238; CHECK-NEXT:  Unknown data dependence.
239; CHECK-NEXT:      Dependences:
240; CHECK-NEXT:        Unknown:
241; CHECK-NEXT:            %l = load i32, ptr %gep.after, align 4 ->
242; CHECK-NEXT:            store i32 %add, ptr %gep, align 4
243; CHECK-EMPTY:
244; CHECK-NEXT:      Run-time memory checks:
245; CHECK-NEXT:      Grouped accesses:
246; CHECK-EMPTY:
247; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
248; CHECK-NEXT:      SCEV assumptions:
249; CHECK-EMPTY:
250; CHECK-NEXT:      Expressions re-written:
251;
252  %c = icmp eq i64 %off, 101
253  br i1 %c, label %ph, label %exit
254
255ph:
256  %gep.after = getelementptr inbounds nuw i32, ptr %a, i64 100
257  br label %loop
258
259loop:
260  %iv = phi i64 [ 0, %ph ], [ %iv.next, %loop ]
261  %l = load i32 , ptr %gep.after, align 4
262  %add = add i32 %l, %l
263  %gep = getelementptr inbounds i32, ptr %a, i64 %iv
264  store i32 %add, ptr %gep, align 4
265  %iv.next = add nsw nuw i64 %iv, 1
266  %ec = icmp eq i64 %iv.next, %off
267  br i1 %ec, label %exit, label %loop
268
269exit:
270  ret void
271}
272
273; Loop guard for %off guarantees the accesses in the loop do not overlap.
274; TODO: currently missed by LAA
275define void @access_after_via_loop_guard_sge_loop_cond(ptr %a, i64 %off) {
276; CHECK-LABEL: 'access_after_via_loop_guard_sge_loop_cond'
277; CHECK-NEXT:    loop:
278; 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
279; CHECK-NEXT:  Unknown data dependence.
280; CHECK-NEXT:      Dependences:
281; CHECK-NEXT:        Unknown:
282; CHECK-NEXT:            %l = load i32, ptr %gep.after, align 4 ->
283; CHECK-NEXT:            store i32 %add, ptr %gep, 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;
293  %c = icmp sge i64 %off, 100
294  br i1 %c, label %ph, label %exit
295
296ph:
297  %gep.after = getelementptr inbounds nuw i32, ptr %a, i64 100
298  br label %loop
299
300loop:
301  %iv = phi i64 [ 0, %ph ], [ %iv.next, %loop ]
302  %l = load i32 , ptr %gep.after, align 4
303  %add = add i32 %l, %l
304  %gep = getelementptr inbounds i32, ptr %a, i64 %iv
305  store i32 %add, ptr %gep, align 4
306  %iv.next = add nsw nuw i64 %iv, 1
307  %ec = icmp eq i64 %iv.next, %off
308  br i1 %ec, label %exit, label %loop
309
310exit:
311  ret void
312}
313
314define void @access_after_via_loop_guard_sge_loop_cond_101(ptr %a, i64 %off) {
315; CHECK-LABEL: 'access_after_via_loop_guard_sge_loop_cond_101'
316; CHECK-NEXT:    loop:
317; 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
318; CHECK-NEXT:  Unknown data dependence.
319; CHECK-NEXT:      Dependences:
320; CHECK-NEXT:        Unknown:
321; CHECK-NEXT:            %l = load i32, ptr %gep.after, align 4 ->
322; CHECK-NEXT:            store i32 %add, ptr %gep, align 4
323; CHECK-EMPTY:
324; CHECK-NEXT:      Run-time memory checks:
325; CHECK-NEXT:      Grouped accesses:
326; CHECK-EMPTY:
327; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
328; CHECK-NEXT:      SCEV assumptions:
329; CHECK-EMPTY:
330; CHECK-NEXT:      Expressions re-written:
331;
332  %c = icmp sge i64 %off, 101
333  br i1 %c, label %ph, label %exit
334
335ph:
336  %gep.after = getelementptr inbounds nuw i32, ptr %a, i64 100
337  br label %loop
338
339loop:
340  %iv = phi i64 [ 0, %ph ], [ %iv.next, %loop ]
341  %l = load i32 , ptr %gep.after, align 4
342  %add = add i32 %l, %l
343  %gep = getelementptr inbounds i32, ptr %a, i64 %iv
344  store i32 %add, ptr %gep, align 4
345  %iv.next = add nsw nuw i64 %iv, 1
346  %ec = icmp eq i64 %iv.next, %off
347  br i1 %ec, label %exit, label %loop
348
349exit:
350  ret void
351}
352