Skip to content

Commit 904aac7

Browse files
committed
Add bounds check tests with Slab
1 parent e066bb2 commit 904aac7

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+
// RUN: %target-swift-frontend %s -emit-sil -O \
2+
// RUN: -disable-availability-checking \
3+
// RUN: -enable-experimental-feature Slab \
4+
// RUN: -enable-experimental-feature ValueGenerics | %FileCheck %s --check-prefix=CHECK-SIL
5+
6+
// RUN: %target-swift-frontend %s -emit-ir -O \
7+
// RUN: -disable-availability-checking \
8+
// RUN: -enable-experimental-feature Slab \
9+
// RUN: -enable-experimental-feature ValueGenerics | %FileCheck %s --check-prefix=CHECK-IR
10+
11+
// REQUIRES: swift_in_compiler
12+
// REQUIRES: swift_feature_ValueGenerics
13+
// REQUIRES: swift_stdlib_no_asserts, optimized_stdlib
14+
15+
// Bounds check should be eliminated
16+
// SIL removes lower bounds check from the loop
17+
// LLVM removes the upper bounds check from the loop and then vectorizes
18+
// A lower bounds check is left behind in the entry block
19+
20+
// CHECK-SIL-LABEL: sil @$s23slab_bounds_check_tests0A29_sum_iterate_to_count_wo_trapySis4SlabVyxSiGSiRVzlF :
21+
// CHECK-SIL: bb3
22+
// CHECK-SIL: cond_fail {{.*}}, "Index out of bounds"
23+
// CHECK-SIL-NOT: cond_fail {{.*}}, "Index out of bounds"
24+
// CHECK-SIL: cond_br
25+
// CHECK-SIL-LABEL: } // end sil function '$s23slab_bounds_check_tests0A29_sum_iterate_to_count_wo_trapySis4SlabVyxSiGSiRVzlF'
26+
27+
// CHECK-IR: define {{.*}} @"$s23slab_bounds_check_tests0A29_sum_iterate_to_count_wo_trapySis4SlabVyxSiGSiRVzlF"
28+
// CHECK-IR: @llvm.vector.reduce.add
29+
public func slab_sum_iterate_to_count_wo_trap<let N: Int>(_ v: Slab<N, Int>) -> Int {
30+
var sum = 0
31+
for i in 0..<v.count {
32+
sum &+= v[i]
33+
}
34+
return sum
35+
}
36+
37+
// Bounds check should be eliminated
38+
// SIL removes lower bounds check from the loop
39+
// LLVM removes the upper bounds check from the loop
40+
// A lower bounds check is left behind in the entry block
41+
42+
// CHECK-SIL-LABEL: sil @$s23slab_bounds_check_tests0A31_sum_iterate_to_count_with_trapySis4SlabVyxSiGSiRVzlF :
43+
// CHECK-SIL: bb3
44+
// CHECK-SIL: cond_fail {{.*}}, "Index out of bounds"
45+
// CHECK-SIL-NOT: cond_fail {{.*}}, "Index out of bounds"
46+
// CHECK-SIL: cond_br
47+
// CHECK-SIL-LABEL: } // end sil function '$s23slab_bounds_check_tests0A31_sum_iterate_to_count_with_trapySis4SlabVyxSiGSiRVzlF'
48+
49+
public func slab_sum_iterate_to_count_with_trap<let N: Int>(_ v: Slab<N, Int>) -> Int {
50+
var sum = 0
51+
for i in 0..<v.count {
52+
sum += v[i]
53+
}
54+
return sum
55+
}
56+
57+
// Bounds check should be hoisted
58+
// SIL removes lower bounds check from the loop
59+
// LLVM removes the upper bounds check from the loop and then vectorizes
60+
// A lower bounds check is left behind in the entry block
61+
62+
// CHECK-SIL-LABEL: sil @$s23slab_bounds_check_tests0A31_sum_iterate_to_unknown_wo_trapySis4SlabVyxSiG_SitSiRVzlF :
63+
// CHECK-SIL: bb3
64+
// CHECK-SIL: cond_fail {{.*}}, "Index out of bounds"
65+
// CHECK-SIL-NOT: cond_fail {{.*}}, "Index out of bounds"
66+
// CHECK-SIL: cond_br
67+
// CHECK-SIL-LABEL: } // end sil function '$s23slab_bounds_check_tests0A31_sum_iterate_to_unknown_wo_trapySis4SlabVyxSiG_SitSiRVzlF'
68+
69+
// CHECK-IR: define {{.*}} @"$s23slab_bounds_check_tests0A31_sum_iterate_to_unknown_wo_trapySis4SlabVyxSiG_SitSiRVzlF"
70+
// CHECK-IR: @llvm.vector.reduce.add
71+
public func slab_sum_iterate_to_unknown_wo_trap<let N: Int>(_ v: Slab<N, Int>, _ n: Int) -> Int {
72+
var sum = 0
73+
for i in 0...n {
74+
sum &+= v[i]
75+
}
76+
return sum
77+
}
78+
79+
// Bounds check should be hoisted
80+
// SIL removes lower bounds check from the loop
81+
// LLVM removes the upper bounds check from the loop
82+
// A lower bounds check is left behind in the entry block
83+
84+
// CHECK-SIL-LABEL: sil @$s23slab_bounds_check_tests0A33_sum_iterate_to_unknown_with_trapySis4SlabVyxSiG_SitSiRVzlF :
85+
// CHECK-SIL: bb3
86+
// CHECK-SIL: cond_fail {{.*}}, "Index out of bounds"
87+
// CHECK-SIL-NOT: cond_fail {{.*}}, "Index out of bounds"
88+
// CHECK-SIL: cond_br
89+
// CHECK-SIL-LABEL: } // end sil function '$s23slab_bounds_check_tests0A33_sum_iterate_to_unknown_with_trapySis4SlabVyxSiG_SitSiRVzlF'
90+
public func slab_sum_iterate_to_unknown_with_trap<let N: Int>(_ v: Slab<N, Int>, _ n: Int) -> Int {
91+
var sum = 0
92+
for i in 0...n {
93+
sum += v[i]
94+
}
95+
return sum
96+
}
97+
98+
// Bounds check should be eliminated
99+
// SIL removes lower bounds check from the loop
100+
// LLVM removes the upper bounds check from the loop and then vectorizes
101+
102+
// CHECK-SIL-LABEL: sil @$s23slab_bounds_check_tests0A40_sum_iterate_to_deducible_count1_wo_trapySis4SlabVyxSiG_SitSiRVzlF :
103+
// CHECK-SIL: bb3
104+
// CHECK-SIL: cond_fail {{.*}}, "Index out of bounds"
105+
// CHECK-SIL-NOT: cond_fail {{.*}}, "Index out of bounds"
106+
// CHECK-SIL: cond_br
107+
// CHECK-SIL-LABEL: } // end sil function '$s23slab_bounds_check_tests0A40_sum_iterate_to_deducible_count1_wo_trapySis4SlabVyxSiG_SitSiRVzlF'
108+
109+
// CHECK-IR: define {{.*}} @"$s23slab_bounds_check_tests0A40_sum_iterate_to_deducible_count1_wo_trapySis4SlabVyxSiG_SitSiRVzlF"
110+
// CHECK-IR: @llvm.vector.reduce.add
111+
public func slab_sum_iterate_to_deducible_count1_wo_trap<let N: Int>(_ v: Slab<N, Int>, _ n: Int) -> Int {
112+
var sum = 0
113+
precondition(n <= v.count)
114+
for i in 0..<n {
115+
sum &+= v[i]
116+
}
117+
return sum
118+
}
119+
120+
// Bounds check should be eliminated
121+
// SIL removes lower bounds check from the loop
122+
// LLVM does not eliminate redundant bounds check
123+
124+
// CHECK-SIL-LABEL: sil @$s23slab_bounds_check_tests0A42_sum_iterate_to_deducible_count1_with_trapySis4SlabVyxSiG_SitSiRVzlF :
125+
// CHECK-SIL: bb3
126+
// CHECK-SIL: cond_fail {{.*}}, "Index out of bounds"
127+
// CHECK-SIL-NOT: cond_fail {{.*}}, "Index out of bounds"
128+
// CHECK-SIL: cond_br
129+
// CHECK-SIL-LABEL: } // end sil function '$s23slab_bounds_check_tests0A42_sum_iterate_to_deducible_count1_with_trapySis4SlabVyxSiG_SitSiRVzlF'
130+
public func slab_sum_iterate_to_deducible_count1_with_trap<let N: Int>(_ v: Slab<N, Int>, _ n: Int) -> Int {
131+
var sum = 0
132+
precondition(n <= v.count)
133+
for i in 0..<n {
134+
sum += v[i]
135+
}
136+
return sum
137+
}
138+
139+
// Bounds check should be eliminated
140+
// SIL removes lower bounds check from the loop
141+
// LLVM removes upper bounds check and vectorizes the loop
142+
143+
// CHECK-SIL-LABEL: sil @$s23slab_bounds_check_tests0A40_sum_iterate_to_deducible_count2_wo_trapySis4SlabVyxSiG_SitSiRVzlF :
144+
// CHECK-SIL: bb3
145+
// CHECK-SIL: cond_fail {{.*}}, "Index out of bounds"
146+
// CHECK-SIL-NOT: cond_fail {{.*}}, "Index out of bounds"
147+
// CHECK-SIL: cond_br
148+
// CHECK-SIL-LABEL: } // end sil function '$s23slab_bounds_check_tests0A40_sum_iterate_to_deducible_count2_wo_trapySis4SlabVyxSiG_SitSiRVzlF'
149+
150+
// CHECK-IR: define {{.*}} @"$s23slab_bounds_check_tests0A40_sum_iterate_to_deducible_count2_wo_trapySis4SlabVyxSiG_SitSiRVzlF"
151+
// CHECK-IR: @llvm.vector.reduce.add
152+
public func slab_sum_iterate_to_deducible_count2_wo_trap<let N: Int>(_ v: Slab<N, Int>, _ n: Int) -> Int {
153+
var sum = 0
154+
precondition(n <= v.count)
155+
for i in 0...n {
156+
sum &+= v[i]
157+
}
158+
return sum
159+
}
160+
161+
// Bounds check should be eliminated
162+
// SIL removes lower bounds check from the loop
163+
// LLVM does not eliminate redundant bounds check
164+
165+
// CHECK-SIL-LABEL: sil @$s23slab_bounds_check_tests0A42_sum_iterate_to_deducible_count2_with_trapySis4SlabVyxSiG_SitSiRVzlF :
166+
// CHECK-SIL: bb3
167+
// CHECK-SIL: cond_fail {{.*}}, "Index out of bounds"
168+
// CHECK-SIL-NOT: cond_fail {{.*}}, "Index out of bounds"
169+
// CHECK-SIL: cond_br
170+
// CHECK-SIL-LABEL: } // end sil function '$s23slab_bounds_check_tests0A42_sum_iterate_to_deducible_count2_with_trapySis4SlabVyxSiG_SitSiRVzlF'
171+
public func slab_sum_iterate_to_deducible_count2_with_trap<let N: Int>(_ v: Slab<N, Int>, _ n: Int) -> Int {
172+
var sum = 0
173+
precondition(n <= v.count)
174+
for i in 0...n {
175+
sum += v[i]
176+
}
177+
return sum
178+
}
179+
180+
// Bounds check should be eliminated
181+
// SIL removes lower bounds check from the loop
182+
// LLVM removes upper bounds check and vectorizes the loop
183+
184+
// CHECK-SIL-LABEL: sil @$s23slab_bounds_check_tests0A29_iterate_over_indices_wo_trapySis4SlabVyxSiGSiRVzlF :
185+
// CHECK-SIL: bb3
186+
// CHECK-SIL: cond_fail {{.*}}, "Index out of bounds"
187+
// CHECK-SIL-NOT: cond_fail {{.*}}, "Index out of bounds"
188+
// CHECK-SIL: cond_br
189+
// CHECK-SIL-LABEL: } // end sil function '$s23slab_bounds_check_tests0A29_iterate_over_indices_wo_trapySis4SlabVyxSiGSiRVzlF'
190+
191+
// CHECK-IR: define {{.*}} @"$s23slab_bounds_check_tests0A29_iterate_over_indices_wo_trapySis4SlabVyxSiGSiRVzlF"
192+
// CHECK-IR: @llvm.vector.reduce.add
193+
public func slab_iterate_over_indices_wo_trap<let N: Int>(_ v: Slab<N, Int>) -> Int {
194+
var sum = 0
195+
for i in v.indices {
196+
sum &+= v[i]
197+
}
198+
return sum
199+
}
200+
201+
// Bounds check should be eliminated
202+
// SIL removes lower bounds check from the loop
203+
// LLVM does not eliminate redundant bounds check
204+
205+
// CHECK-SIL-LABEL: sil @$s23slab_bounds_check_tests0A31_iterate_over_indices_with_trapySis4SlabVyxSiGSiRVzlF :
206+
// CHECK-SIL: bb3
207+
// CHECK-SIL: cond_fail {{.*}}, "Index out of bounds"
208+
// CHECK-SIL-NOT: cond_fail {{.*}}, "Index out of bounds"
209+
// CHECK-SIL: cond_br
210+
// CHECK-SIL-LABEL: } // end sil function '$s23slab_bounds_check_tests0A31_iterate_over_indices_with_trapySis4SlabVyxSiGSiRVzlF'
211+
public func slab_iterate_over_indices_with_trap<let N: Int>(_ v: Slab<N, Int>) -> Int {
212+
var sum = 0
213+
for i in v.indices {
214+
sum += v[i]
215+
}
216+
return sum
217+
}
218+
219+
// Eliminate duplicate bounds check
220+
221+
// CHECK-SIL-LABEL: sil @$s23slab_bounds_check_tests0A17_element_equalityySbs4SlabVyxSiG_SitSiRVzlF :
222+
// CHECK-SIL: cond_fail {{.*}}, "Index out of bounds"
223+
// CHECK-SIL-NOT: cond_fail {{.*}}, "Index out of bounds"
224+
// CHECK-SIL-LABEL: } // end sil function '$s23slab_bounds_check_tests0A17_element_equalityySbs4SlabVyxSiG_SitSiRVzlF'
225+
226+
public func slab_element_equality<let N: Int>(_ v: Slab<N, Int>, _ i: Int) -> Bool {
227+
return v[i] == v[i]
228+
}
229+
230+
// Eliminate duplicate bounds check
231+
232+
// CHECK-SIL-LABEL: sil @$s23slab_bounds_check_tests0A12_element_sumySis4SlabVyxSiG_SitSiRVzlF :
233+
// CHECK-SIL: cond_fail {{.*}}, "Index out of bounds"
234+
// CHECK-SIL: cond_fail {{.*}}, "Index out of bounds"
235+
// CHECK-SIL-LABEL: } // end sil function '$s23slab_bounds_check_tests0A12_element_sumySis4SlabVyxSiG_SitSiRVzlF'
236+
public func slab_element_sum<let N: Int>(_ v: Slab<N, Int>, _ i: Int) -> Int {
237+
return v[i] &+ v[i]
238+
}
239+
240+
// Bounds check should be eliminated
241+
242+
// CHECK-SIL-LABEL: sil @$s23slab_bounds_check_tests0A7_searchySiSgs4SlabVyq_xG_xtSiRV_SQRzr0_lF :
243+
// CHECK-SIL: bb3:
244+
// CHECK-SIL: cond_fail {{.*}}, "Index out of bounds"
245+
// CHECK-SIL: cond_fail {{.*}}, "Index out of bounds"
246+
// CHECK-SIL: cond_br
247+
// CHECK-SIL-LABEL: } // end sil function '$s23slab_bounds_check_tests0A7_searchySiSgs4SlabVyq_xG_xtSiRV_SQRzr0_lF'
248+
public func slab_search<T : Equatable, let N: Int>(_ v: Slab<N, T>, _ elem: T) -> Int? {
249+
for i in v.indices {
250+
if v[i] == elem {
251+
return i
252+
}
253+
}
254+
return nil
255+
}
256+
257+
// Bounds check should be eliminated
258+
259+
// CHECK-SIL-LABEL: sil @$s23slab_bounds_check_tests0A11_search_splySiSgs4SlabVyxSiG_SitSiRVzlF :
260+
// CHECK-SIL: bb3:
261+
// CHECK-SIL: cond_fail {{.*}}, "Index out of bounds"
262+
// CHECK-SIL: cond_fail {{.*}}, "Index out of bounds"
263+
// CHECK-SIL: cond_br
264+
// CHECK-SIL-LABEL: } // end sil function '$s23slab_bounds_check_tests0A11_search_splySiSgs4SlabVyxSiG_SitSiRVzlF'
265+
public func slab_search_spl<let N: Int>(_ v: Slab<N, Int>, _ elem: Int) -> Int? {
266+
for i in v.indices {
267+
if v[i] == elem {
268+
return i
269+
}
270+
}
271+
return nil
272+
}
273+
274+
// Bounds check should be eliminated
275+
276+
// CHECK-SIL-LABEL: sil @$s23slab_bounds_check_tests0A18_binary_search_splySiSgs4SlabVyxSiG_SitSiRVzlF :
277+
// CHECK-SIL: bb2
278+
// CHECK-SIL: cond_fail {{.*}}, "Index out of bounds"
279+
// CHECK-SIL: cond_br
280+
// CHECK-SIL-LABEL: } // end sil function '$s23slab_bounds_check_tests0A18_binary_search_splySiSgs4SlabVyxSiG_SitSiRVzlF'
281+
public func slab_binary_search_spl<let N: Int>(_ v: Slab<N, Int>, _ elem: Int) -> Int? {
282+
var low = 0, high = v.count - 1
283+
while low <= high {
284+
let mid = low + (high - low) / 2
285+
286+
if v[mid] == elem {
287+
return mid
288+
}
289+
else if v[mid] < elem {
290+
low = mid + 1
291+
} else {
292+
high = mid - 1
293+
}
294+
}
295+
296+
return nil;
297+
}
298+

0 commit comments

Comments
 (0)