Skip to content

Commit 9c535a3

Browse files
committed
[LAA] Add tests for #69744.
Note that both loops in the tests are needed to incorrectly determine that the loops are safe with runtime checks via FoundNonConstantDistanceDependence handling code in LAA.
1 parent 6cea5c3 commit 9c535a3

File tree

1 file changed

+298
-0
lines changed

1 file changed

+298
-0
lines changed
Lines changed: 298 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 3
2+
; RUN: opt -passes='print<access-info>' -disable-output %s 2>&1 | FileCheck %s
3+
4+
target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
5+
6+
; Test cases for https://github.com/llvm/llvm-project/issues/69744.
7+
; Note that both loops in the tests are needed to incorrectly determine that
8+
; the loops are safe with runtime checks via FoundNonConstantDistanceDependence
9+
; handling code in LAA.
10+
11+
; FIXME: Not safe with runtime checks due to the indirect pointers are modified
12+
; in the loop.
13+
define void @test_indirect_read_write_loop_also_modifies_pointer_array(ptr noundef %arr) {
14+
; CHECK-LABEL: 'test_indirect_read_write_loop_also_modifies_pointer_array'
15+
; CHECK-NEXT: loop.1:
16+
; CHECK-NEXT: Report: could not determine number of loop iterations
17+
; CHECK-NEXT: Dependences:
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+
; CHECK-NEXT: loop.2:
26+
; CHECK-NEXT: Memory dependences are safe with run-time checks
27+
; CHECK-NEXT: Dependences:
28+
; CHECK-NEXT: Run-time memory checks:
29+
; CHECK-NEXT: Check 0:
30+
; CHECK-NEXT: Comparing group ([[GRP1:0x[0-9a-f]+]]):
31+
; CHECK-NEXT: %gep.iv.2 = getelementptr inbounds ptr, ptr %arr, i64 %iv.2
32+
; CHECK-NEXT: Against group ([[GRP2:0x[0-9a-f]+]]):
33+
; CHECK-NEXT: %gep.iv.1 = getelementptr inbounds ptr, ptr %arr, i64 %iv.1
34+
; CHECK-NEXT: Grouped accesses:
35+
; CHECK-NEXT: Group [[GRP1]]:
36+
; CHECK-NEXT: (Low: {(64 + %arr),+,64}<%loop.1> High: {(8064 + %arr),+,64}<%loop.1>)
37+
; CHECK-NEXT: Member: {{\{{}}(64 + %arr),+,64}<%loop.1>,+,8}<%loop.2>
38+
; CHECK-NEXT: Group [[GRP2]]:
39+
; CHECK-NEXT: (Low: %arr High: (8000 + %arr))
40+
; CHECK-NEXT: Member: {%arr,+,8}<nuw><%loop.2>
41+
; CHECK-EMPTY:
42+
; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
43+
; CHECK-NEXT: SCEV assumptions:
44+
; CHECK-EMPTY:
45+
; CHECK-NEXT: Expressions re-written:
46+
;
47+
entry:
48+
br label %loop.1
49+
50+
loop.1:
51+
%iv = phi i64 [ %iv.next, %loop.1 ], [ 8, %entry ]
52+
%arr.addr.0.i = phi ptr [ %incdec.ptr.i, %loop.1 ], [ %arr, %entry ]
53+
%incdec.ptr.i = getelementptr inbounds ptr, ptr %arr.addr.0.i, i64 1
54+
%0 = load ptr, ptr %arr.addr.0.i, align 8, !tbaa !6
55+
%tobool.not.i = icmp eq ptr %0, null
56+
%iv.next = add i64 %iv, 8
57+
br i1 %tobool.not.i, label %loop.1.exit, label %loop.1
58+
59+
loop.1.exit:
60+
%iv.lcssa = phi i64 [ %iv, %loop.1 ]
61+
br label %loop.2
62+
63+
loop.2:
64+
%iv.1 = phi i64 [ 0, %loop.1.exit ], [ %iv.1.next, %loop.2 ]
65+
%iv.2 = phi i64 [ %iv.lcssa, %loop.1.exit ], [ %iv.2.next, %loop.2 ]
66+
%gep.iv.1 = getelementptr inbounds ptr, ptr %arr, i64 %iv.1
67+
%l.1 = load ptr, ptr %gep.iv.1, align 8, !tbaa !6
68+
%l.2 = load i64, ptr %l.1, align 8, !tbaa !13
69+
%inc = add i64 %l.2, 1
70+
store i64 %inc, ptr %l.1, align 8, !tbaa !13
71+
%iv.2.next = add nsw i64 %iv.2, 1
72+
%gep.iv.2 = getelementptr inbounds ptr, ptr %arr, i64 %iv.2
73+
store ptr %l.1, ptr %gep.iv.2, align 8, !tbaa !6
74+
%iv.1.next = add nuw nsw i64 %iv.1, 1
75+
%cmp = icmp ult i64 %iv.1.next, 1000
76+
br i1 %cmp, label %loop.2, label %exit
77+
78+
exit:
79+
ret void
80+
}
81+
82+
; FIXME: Not safe with runtime checks due to the indirect pointers are modified
83+
; in the loop.
84+
define void @test_indirect_read_loop_also_modifies_pointer_array(ptr noundef %arr) {
85+
; CHECK-LABEL: 'test_indirect_read_loop_also_modifies_pointer_array'
86+
; CHECK-NEXT: loop.1:
87+
; CHECK-NEXT: Report: could not determine number of loop iterations
88+
; CHECK-NEXT: Dependences:
89+
; CHECK-NEXT: Run-time memory checks:
90+
; CHECK-NEXT: Grouped accesses:
91+
; CHECK-EMPTY:
92+
; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
93+
; CHECK-NEXT: SCEV assumptions:
94+
; CHECK-EMPTY:
95+
; CHECK-NEXT: Expressions re-written:
96+
; CHECK-NEXT: loop.2:
97+
; CHECK-NEXT: Memory dependences are safe with run-time checks
98+
; CHECK-NEXT: Dependences:
99+
; CHECK-NEXT: Run-time memory checks:
100+
; CHECK-NEXT: Check 0:
101+
; CHECK-NEXT: Comparing group ([[GRP3:0x[0-9a-f]+]]):
102+
; CHECK-NEXT: %gep.iv.2 = getelementptr inbounds i64, ptr %arr, i64 %iv.2
103+
; CHECK-NEXT: Against group ([[GRP4:0x[0-9a-f]+]]):
104+
; CHECK-NEXT: %gep.iv.1 = getelementptr inbounds ptr, ptr %arr, i64 %iv.1
105+
; CHECK-NEXT: Grouped accesses:
106+
; CHECK-NEXT: Group [[GRP3]]:
107+
; CHECK-NEXT: (Low: {(64 + %arr),+,64}<%loop.1> High: {(8064 + %arr),+,64}<%loop.1>)
108+
; CHECK-NEXT: Member: {{\{{}}(64 + %arr),+,64}<%loop.1>,+,8}<%loop.2>
109+
; CHECK-NEXT: Group [[GRP4]]:
110+
; CHECK-NEXT: (Low: %arr High: (8000 + %arr))
111+
; CHECK-NEXT: Member: {%arr,+,8}<nuw><%loop.2>
112+
; CHECK-EMPTY:
113+
; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
114+
; CHECK-NEXT: SCEV assumptions:
115+
; CHECK-EMPTY:
116+
; CHECK-NEXT: Expressions re-written:
117+
;
118+
entry:
119+
br label %loop.1
120+
121+
loop.1:
122+
%iv = phi i64 [ %iv.next, %loop.1 ], [ 8, %entry ]
123+
%arr.addr.0.i = phi ptr [ %incdec.ptr.i, %loop.1 ], [ %arr, %entry ]
124+
%incdec.ptr.i = getelementptr inbounds ptr, ptr %arr.addr.0.i, i64 1
125+
%0 = load ptr, ptr %arr.addr.0.i, align 8, !tbaa !6
126+
%tobool.not.i = icmp eq ptr %0, null
127+
%iv.next = add i64 %iv, 8
128+
br i1 %tobool.not.i, label %loop.1.exit, label %loop.1
129+
130+
loop.1.exit:
131+
%iv.lcssa = phi i64 [ %iv, %loop.1 ]
132+
br label %loop.2
133+
134+
loop.2:
135+
%iv.1 = phi i64 [ 0, %loop.1.exit ], [ %iv.1.next, %loop.2 ]
136+
%iv.2 = phi i64 [ %iv.lcssa, %loop.1.exit ], [ %iv.2.next, %loop.2 ]
137+
%gep.iv.1 = getelementptr inbounds ptr, ptr %arr, i64 %iv.1
138+
%l.1 = load ptr, ptr %gep.iv.1, align 8, !tbaa !6
139+
%l.2 = load i64, ptr %l.1, align 8, !tbaa !13
140+
%inc = add i64 %l.2, 1
141+
%iv.2.next = add nsw i64 %iv.2, 1
142+
%gep.iv.2 = getelementptr inbounds i64, ptr %arr, i64 %iv.2
143+
store i64 %l.2, ptr %gep.iv.2, align 8, !tbaa !6
144+
%iv.1.next = add nuw nsw i64 %iv.1, 1
145+
%cmp = icmp ult i64 %iv.1.next, 1000
146+
br i1 %cmp, label %loop.2, label %exit
147+
148+
exit:
149+
ret void
150+
}
151+
152+
; FIXME: Not safe with runtime checks due to the indirect pointers are modified
153+
; in the loop.
154+
define void @test_indirect_write_loop_also_modifies_pointer_array(ptr noundef %arr) {
155+
; CHECK-LABEL: 'test_indirect_write_loop_also_modifies_pointer_array'
156+
; CHECK-NEXT: loop.1:
157+
; CHECK-NEXT: Report: could not determine number of loop iterations
158+
; CHECK-NEXT: Dependences:
159+
; CHECK-NEXT: Run-time memory checks:
160+
; CHECK-NEXT: Grouped accesses:
161+
; CHECK-EMPTY:
162+
; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
163+
; CHECK-NEXT: SCEV assumptions:
164+
; CHECK-EMPTY:
165+
; CHECK-NEXT: Expressions re-written:
166+
; CHECK-NEXT: loop.2:
167+
; CHECK-NEXT: Memory dependences are safe with run-time checks
168+
; CHECK-NEXT: Dependences:
169+
; CHECK-NEXT: Run-time memory checks:
170+
; CHECK-NEXT: Check 0:
171+
; CHECK-NEXT: Comparing group ([[GRP5:0x[0-9a-f]+]]):
172+
; CHECK-NEXT: %gep.iv.2 = getelementptr inbounds ptr, ptr %arr, i64 %iv.2
173+
; CHECK-NEXT: Against group ([[GRP6:0x[0-9a-f]+]]):
174+
; CHECK-NEXT: %gep.iv.1 = getelementptr inbounds ptr, ptr %arr, i64 %iv.1
175+
; CHECK-NEXT: Grouped accesses:
176+
; CHECK-NEXT: Group [[GRP5]]:
177+
; CHECK-NEXT: (Low: {(64 + %arr),+,64}<%loop.1> High: {(8064 + %arr),+,64}<%loop.1>)
178+
; CHECK-NEXT: Member: {{\{{}}(64 + %arr),+,64}<%loop.1>,+,8}<%loop.2>
179+
; CHECK-NEXT: Group [[GRP6]]:
180+
; CHECK-NEXT: (Low: %arr High: (8000 + %arr))
181+
; CHECK-NEXT: Member: {%arr,+,8}<nuw><%loop.2>
182+
; CHECK-EMPTY:
183+
; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
184+
; CHECK-NEXT: SCEV assumptions:
185+
; CHECK-EMPTY:
186+
; CHECK-NEXT: Expressions re-written:
187+
;
188+
entry:
189+
br label %loop.1
190+
191+
loop.1:
192+
%iv = phi i64 [ %iv.next, %loop.1 ], [ 8, %entry ]
193+
%arr.addr.0.i = phi ptr [ %incdec.ptr.i, %loop.1 ], [ %arr, %entry ]
194+
%incdec.ptr.i = getelementptr inbounds ptr, ptr %arr.addr.0.i, i64 1
195+
%0 = load ptr, ptr %arr.addr.0.i, align 8, !tbaa !6
196+
%tobool.not.i = icmp eq ptr %0, null
197+
%iv.next = add i64 %iv, 8
198+
br i1 %tobool.not.i, label %loop.1.exit, label %loop.1
199+
200+
loop.1.exit:
201+
%iv.lcssa = phi i64 [ %iv, %loop.1 ]
202+
br label %loop.2
203+
204+
loop.2:
205+
%iv.1 = phi i64 [ 0, %loop.1.exit ], [ %iv.1.next, %loop.2 ]
206+
%iv.2 = phi i64 [ %iv.lcssa, %loop.1.exit ], [ %iv.2.next, %loop.2 ]
207+
%gep.iv.1 = getelementptr inbounds ptr, ptr %arr, i64 %iv.1
208+
%l.1 = load ptr, ptr %gep.iv.1, align 8, !tbaa !6
209+
%l.2 = load i64, ptr %l.1, align 8, !tbaa !13
210+
%inc = add i64 %l.2, 1
211+
store i64 %inc, ptr %l.1, align 8, !tbaa !13
212+
%iv.2.next = add nsw i64 %iv.2, 1
213+
%gep.iv.2 = getelementptr inbounds ptr, ptr %arr, i64 %iv.2
214+
store ptr %l.1, ptr %gep.iv.2, align 8, !tbaa !6
215+
%iv.1.next = add nuw nsw i64 %iv.1, 1
216+
%cmp = icmp ult i64 %iv.1.next, 1000
217+
br i1 %cmp, label %loop.2, label %exit
218+
219+
exit:
220+
ret void
221+
}
222+
223+
define void @test_indirect_read_write_loop_does_not_modify_pointer_array(ptr noundef %arr) {
224+
; CHECK-LABEL: 'test_indirect_read_write_loop_does_not_modify_pointer_array'
225+
; CHECK-NEXT: loop.1:
226+
; CHECK-NEXT: Report: could not determine number of loop iterations
227+
; CHECK-NEXT: Dependences:
228+
; CHECK-NEXT: Run-time memory checks:
229+
; CHECK-NEXT: Grouped accesses:
230+
; CHECK-EMPTY:
231+
; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
232+
; CHECK-NEXT: SCEV assumptions:
233+
; CHECK-EMPTY:
234+
; CHECK-NEXT: Expressions re-written:
235+
; CHECK-NEXT: loop.2:
236+
; CHECK-NEXT: Memory dependences are safe with run-time checks
237+
; CHECK-NEXT: Dependences:
238+
; CHECK-NEXT: Run-time memory checks:
239+
; CHECK-NEXT: Check 0:
240+
; CHECK-NEXT: Comparing group ([[GRP7:0x[0-9a-f]+]]):
241+
; CHECK-NEXT: %gep.iv.2 = getelementptr inbounds ptr, ptr %arr, i64 %iv.2
242+
; CHECK-NEXT: Against group ([[GRP8:0x[0-9a-f]+]]):
243+
; CHECK-NEXT: %gep.iv.1 = getelementptr inbounds ptr, ptr %arr, i64 %iv.1
244+
; CHECK-NEXT: Grouped accesses:
245+
; CHECK-NEXT: Group [[GRP7]]:
246+
; CHECK-NEXT: (Low: {(64 + %arr),+,64}<%loop.1> High: {(8064 + %arr),+,64}<%loop.1>)
247+
; CHECK-NEXT: Member: {{\{{}}(64 + %arr),+,64}<%loop.1>,+,8}<%loop.2>
248+
; CHECK-NEXT: Group [[GRP8]]:
249+
; CHECK-NEXT: (Low: %arr High: (8000 + %arr))
250+
; CHECK-NEXT: Member: {%arr,+,8}<nuw><%loop.2>
251+
; CHECK-EMPTY:
252+
; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
253+
; CHECK-NEXT: SCEV assumptions:
254+
; CHECK-EMPTY:
255+
; CHECK-NEXT: Expressions re-written:
256+
;
257+
entry:
258+
br label %loop.1
259+
260+
loop.1:
261+
%iv = phi i64 [ %iv.next, %loop.1 ], [ 8, %entry ]
262+
%arr.addr.0.i = phi ptr [ %incdec.ptr.i, %loop.1 ], [ %arr, %entry ]
263+
%incdec.ptr.i = getelementptr inbounds ptr, ptr %arr.addr.0.i, i64 1
264+
%0 = load ptr, ptr %arr.addr.0.i, align 8, !tbaa !6
265+
%tobool.not.i = icmp eq ptr %0, null
266+
%iv.next = add i64 %iv, 8
267+
br i1 %tobool.not.i, label %loop.1.exit, label %loop.1
268+
269+
loop.1.exit:
270+
%iv.lcssa = phi i64 [ %iv, %loop.1 ]
271+
br label %loop.2
272+
273+
loop.2:
274+
%iv.1 = phi i64 [ 0, %loop.1.exit ], [ %iv.1.next, %loop.2 ]
275+
%iv.2 = phi i64 [ %iv.lcssa, %loop.1.exit ], [ %iv.2.next, %loop.2 ]
276+
%gep.iv.1 = getelementptr inbounds ptr, ptr %arr, i64 %iv.1
277+
%l.1 = load ptr, ptr %gep.iv.1, align 8, !tbaa !6
278+
%l.2 = load i64, ptr %l.1, align 8, !tbaa !13
279+
%inc = add i64 %l.2, 1
280+
store i64 %inc, ptr %l.1, align 8, !tbaa !13
281+
%iv.2.next = add nsw i64 %iv.2, 1
282+
%gep.iv.2 = getelementptr inbounds ptr, ptr %arr, i64 %iv.2
283+
store ptr %l.1, ptr %gep.iv.2, align 8, !tbaa !6
284+
%iv.1.next = add nuw nsw i64 %iv.1, 1
285+
%cmp = icmp ult i64 %iv.1.next, 1000
286+
br i1 %cmp, label %loop.2, label %exit
287+
288+
exit:
289+
ret void
290+
}
291+
292+
!6 = !{!7, !7, i64 0}
293+
!7 = !{!"any pointer", !8, i64 0}
294+
!8 = !{!"omnipotent char", !9, i64 0}
295+
!9 = !{!"Simple C/C++ TBAA"}
296+
!13 = !{!14, !15, i64 0}
297+
!14 = !{!"", !15, i64 0}
298+
!15 = !{!"long long", !8, i64 0}

0 commit comments

Comments
 (0)