Skip to content

Commit ab5fe7f

Browse files
authored
[mypyc] Add additional vec irbuild tests and fix keep alive issue (#20732)
Follow-up to #20724. This wasn't included in the original PR to keep it smaller. This includes irbuild tests for item types other than `i64`. Related issue: mypyc/mypyc#840
1 parent 9da6043 commit ab5fe7f

File tree

7 files changed

+1456
-3
lines changed

7 files changed

+1456
-3
lines changed

mypyc/irbuild/vec.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ def vec_get_item_unsafe(
298298
vtype = base.type
299299
item_addr = vec_item_ptr(builder, base, index)
300300
result = builder.load_mem(item_addr, vtype.item_type, borrow=can_borrow)
301-
builder.keep_alive([base], line)
301+
builder.keep_alives.append(base)
302302
return result
303303

304304

mypyc/test-data/irbuild-vec-i64.test

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -435,8 +435,8 @@ L2:
435435
r7 = r2 * 8
436436
r8 = r6 + r7
437437
r9 = load_mem r8 :: i64*
438-
keep_alive v
439438
x = r9
439+
keep_alive v
440440
r10 = x + 1
441441
r11 = r1.buf
442442
r12 = get_element_ptr r11 items :: VecI64BufObject
@@ -522,8 +522,8 @@ L2:
522522
r5 = r0 * 8
523523
r6 = r4 + r5
524524
r7 = load_mem r6 :: i64*
525-
keep_alive v
526525
x = r7
526+
keep_alive v
527527
r8 = t + 1
528528
t = r8
529529
L3:
Lines changed: 346 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,346 @@
1+
-- Test cases for packed/specialized vec item types other than i64, such as
2+
-- vec[i32] and vec[float]. Since many of the code paths are the same as for
3+
-- vec[i64], only test a subset of functionality.
4+
--
5+
-- vec[i64] test cases are in irbuild-vec-i64.test.
6+
7+
[case testVecMiscCreateEmpty]
8+
from librt.vecs import vec
9+
10+
from mypy_extensions import i32, i16, u8
11+
12+
def create_float() -> vec[float]:
13+
return vec[float]()
14+
15+
def create_i32() -> vec[i32]:
16+
return vec[i32]()
17+
18+
def create_i16() -> vec[i16]:
19+
return vec[i16]()
20+
21+
def create_u8() -> vec[u8]:
22+
return vec[u8]()
23+
24+
def create_bool() -> vec[bool]:
25+
return vec[bool]()
26+
[out]
27+
def create_float():
28+
r0 :: vec[float]
29+
L0:
30+
r0 = VecFloatApi.alloc(0, 0)
31+
return r0
32+
def create_i32():
33+
r0 :: vec[i32]
34+
L0:
35+
r0 = VecI32Api.alloc(0, 0)
36+
return r0
37+
def create_i16():
38+
r0 :: vec[i16]
39+
L0:
40+
r0 = VecI16Api.alloc(0, 0)
41+
return r0
42+
def create_u8():
43+
r0 :: vec[u8]
44+
L0:
45+
r0 = VecU8Api.alloc(0, 0)
46+
return r0
47+
def create_bool():
48+
r0 :: vec[bool]
49+
L0:
50+
r0 = VecBoolApi.alloc(0, 0)
51+
return r0
52+
53+
[case testVecMiscCreateFromList]
54+
from librt.vecs import vec
55+
56+
from mypy_extensions import i64, i32
57+
58+
def create_i32() -> vec[i32]:
59+
return vec[i32]([1, -5])
60+
[out]
61+
def create_i32():
62+
r0 :: vec[i32]
63+
r1 :: object
64+
r2, r3, r4 :: ptr
65+
L0:
66+
r0 = VecI32Api.alloc(2, 2)
67+
r1 = r0.buf
68+
r2 = get_element_ptr r1 items :: VecI32BufObject
69+
set_mem r2, 1 :: i32*
70+
r3 = r2 + 4
71+
set_mem r3, -5 :: i32*
72+
r4 = r3 + 4
73+
keep_alive r0
74+
return r0
75+
76+
[case testVecMiscLen_64bit]
77+
from librt.vecs import vec
78+
79+
from mypy_extensions import i64, i32
80+
81+
def len_i32(v: vec[i32]) -> i64:
82+
return len(v)
83+
[out]
84+
def len_i32(v):
85+
v :: vec[i32]
86+
r0 :: native_int
87+
L0:
88+
r0 = v.len
89+
return r0
90+
91+
[case testVecMiscAppend]
92+
from librt.vecs import vec, append
93+
94+
from mypy_extensions import i32
95+
96+
def append_float(v: vec[float]) -> vec[float]:
97+
return append(v, 1.5)
98+
99+
def append_i32(v: vec[i32]) -> vec[i32]:
100+
return append(v, 123)
101+
[out]
102+
def append_float(v):
103+
v, r0 :: vec[float]
104+
L0:
105+
r0 = VecFloatApi.append(v, 1.5)
106+
return r0
107+
def append_i32(v):
108+
v, r0 :: vec[i32]
109+
L0:
110+
r0 = VecI32Api.append(v, 123)
111+
return r0
112+
113+
[case testVecMiscGetItem_64bit]
114+
from librt.vecs import vec
115+
116+
from mypy_extensions import i64
117+
118+
def get_item_bool(v: vec[bool], i: i64) -> bool:
119+
return v[i]
120+
[out]
121+
def get_item_bool(v, i):
122+
v :: vec[bool]
123+
i :: i64
124+
r0 :: native_int
125+
r1 :: bit
126+
r2 :: i64
127+
r3 :: bit
128+
r4 :: bool
129+
r5 :: i64
130+
r6 :: object
131+
r7 :: ptr
132+
r8 :: i64
133+
r9 :: ptr
134+
r10 :: bool
135+
L0:
136+
r0 = v.len
137+
r1 = i < r0 :: unsigned
138+
if r1 goto L4 else goto L1 :: bool
139+
L1:
140+
r2 = i + r0
141+
r3 = r2 < r0 :: unsigned
142+
if r3 goto L3 else goto L2 :: bool
143+
L2:
144+
r4 = raise IndexError
145+
unreachable
146+
L3:
147+
r5 = r2
148+
goto L5
149+
L4:
150+
r5 = i
151+
L5:
152+
r6 = v.buf
153+
r7 = get_element_ptr r6 items :: VecBoolBufObject
154+
r8 = r5 * 1
155+
r9 = r7 + r8
156+
r10 = load_mem r9 :: builtins.bool*
157+
keep_alive v
158+
return r10
159+
160+
[case testVecMiscPop]
161+
from librt.vecs import vec, pop
162+
163+
from mypy_extensions import i64
164+
165+
def pop_float(v: vec[float], i: i64) -> float:
166+
v, x = pop(v)
167+
return x
168+
[out]
169+
def pop_float(v, i):
170+
v :: vec[float]
171+
i :: i64
172+
r0 :: tuple[vec[float], float]
173+
r1 :: vec[float]
174+
r2 :: float
175+
r3 :: vec[float]
176+
r4, x :: float
177+
L0:
178+
r0 = VecFloatApi.pop(v, -1)
179+
r1 = borrow r0[0]
180+
r2 = borrow r0[1]
181+
keep_alive steal r0
182+
r3 = unborrow r1
183+
v = r3
184+
r4 = unborrow r2
185+
x = r4
186+
return x
187+
188+
[case testVecMiscRemove]
189+
from librt.vecs import vec, remove
190+
191+
def remove_float(v: vec[float]) -> vec[float]:
192+
return remove(v, 1.5)
193+
[out]
194+
def remove_float(v):
195+
v, r0 :: vec[float]
196+
L0:
197+
r0 = VecFloatApi.remove(v, 1.5)
198+
return r0
199+
200+
[case testVecMiscSlice]
201+
from librt.vecs import vec, remove
202+
203+
from mypy_extensions import i64
204+
205+
def remove_float(v: vec[float], x: i64, y: i64) -> vec[float]:
206+
return v[x:y]
207+
[out]
208+
def remove_float(v, x, y):
209+
v :: vec[float]
210+
x, y :: i64
211+
r0 :: vec[float]
212+
L0:
213+
r0 = VecFloatApi.slice(v, x, y)
214+
return r0
215+
216+
[case testVecMiscForLoop]
217+
from librt.vecs import vec, remove
218+
219+
from mypy_extensions import i64, i16
220+
221+
def for_bool(v: vec[i16]) -> i16:
222+
s: i16 = 0
223+
for x in v:
224+
s += x
225+
return s
226+
[out]
227+
def for_bool(v):
228+
v :: vec[i16]
229+
s :: i16
230+
r0, r1 :: native_int
231+
r2 :: bit
232+
r3 :: object
233+
r4 :: ptr
234+
r5 :: native_int
235+
r6 :: ptr
236+
r7, x, r8 :: i16
237+
r9 :: native_int
238+
L0:
239+
s = 0
240+
r0 = 0
241+
L1:
242+
r1 = v.len
243+
r2 = r0 < r1 :: signed
244+
if r2 goto L2 else goto L4 :: bool
245+
L2:
246+
r3 = v.buf
247+
r4 = get_element_ptr r3 items :: VecI16BufObject
248+
r5 = r0 * 2
249+
r6 = r4 + r5
250+
r7 = load_mem r6 :: i16*
251+
x = r7
252+
keep_alive v
253+
r8 = s + x
254+
s = r8
255+
L3:
256+
r9 = r0 + 1
257+
r0 = r9
258+
goto L1
259+
L4:
260+
return s
261+
262+
[case testVecMiscNestedGetItem_64bit]
263+
from librt.vecs import vec
264+
265+
from mypy_extensions import i64, i32
266+
267+
def get_item_nested(v: vec[vec[i32]], i: i64) -> vec[i32]:
268+
return v[i]
269+
[out]
270+
def get_item_nested(v, i):
271+
v :: vec[vec[i32]]
272+
i :: i64
273+
r0 :: native_int
274+
r1 :: bit
275+
r2 :: i64
276+
r3 :: bit
277+
r4 :: bool
278+
r5 :: i64
279+
r6 :: object
280+
r7 :: ptr
281+
r8 :: i64
282+
r9 :: ptr
283+
r10 :: vec[i32]
284+
L0:
285+
r0 = v.len
286+
r1 = i < r0 :: unsigned
287+
if r1 goto L4 else goto L1 :: bool
288+
L1:
289+
r2 = i + r0
290+
r3 = r2 < r0 :: unsigned
291+
if r3 goto L3 else goto L2 :: bool
292+
L2:
293+
r4 = raise IndexError
294+
unreachable
295+
L3:
296+
r5 = r2
297+
goto L5
298+
L4:
299+
r5 = i
300+
L5:
301+
r6 = v.buf
302+
r7 = get_element_ptr r6 items :: VecNestedBufObject
303+
r8 = r5 * 16
304+
r9 = r7 + r8
305+
r10 = load_mem r9 :: vec[i32]*
306+
keep_alive v
307+
return r10
308+
309+
[case testVecMiscNestedPop_64bit]
310+
from librt.vecs import vec, pop
311+
312+
from mypy_extensions import i64, i32
313+
314+
def get_item_nested(v: vec[vec[i32]], i: i64) -> vec[i32]:
315+
v, x = pop(v, i)
316+
return x
317+
[out]
318+
def get_item_nested(v, i):
319+
v :: vec[vec[i32]]
320+
i :: i64
321+
r0 :: tuple[vec[vec[i32]], VecNestedBufItem{len:native_int, buf:object_nrc}]
322+
r1, r2 :: vec[vec[i32]]
323+
r3, r4 :: VecNestedBufItem{len:native_int, buf:object_nrc}
324+
r5 :: vec[i32]
325+
r6 :: tuple[vec[vec[i32]], vec[i32]]
326+
r7 :: vec[vec[i32]]
327+
r8 :: vec[i32]
328+
r9 :: vec[vec[i32]]
329+
r10, x :: vec[i32]
330+
L0:
331+
r0 = VecNestedApi.pop(v, i)
332+
r1 = borrow r0[0]
333+
r2 = unborrow r1
334+
r3 = borrow r0[1]
335+
r4 = unborrow r3
336+
r5 = VecI32Api.convert_from_nested(r4)
337+
r6 = (r2, r5)
338+
keep_alive steal r0
339+
r7 = borrow r6[0]
340+
r8 = borrow r6[1]
341+
keep_alive steal r6
342+
r9 = unborrow r7
343+
v = r9
344+
r10 = unborrow r8
345+
x = r10
346+
return x

0 commit comments

Comments
 (0)