Skip to content

Commit 972353f

Browse files
committed
[LAA] Add tests where results can be improved using loop guards.
1 parent b5598c3 commit 972353f

File tree

1 file changed

+363
-0
lines changed

1 file changed

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

0 commit comments

Comments
 (0)