fix(gen): list iteration loads the real element type
`for v in list[T]` allocated the loop variable as i8* and loaded each
element through i8*, so integer elements were treated as pointers. A
later reuse of the same name, e.g.
for i in nums: ... # i becomes i8*
for i in range(6): ... # stores/compares 6 in the i8* slot
then materialized a pointer-typed constant 6 and failed the renderer
with `[MLIR-FAIL] unsupported constant operand form (type '!llvm.ptr',
value '6')`.
Resolve the element type from the list specialization
(`_list_elem_type_from_name`: list[int] -> i32, list[str] -> i8*) and use
it for both the loop-variable alloca and the element load; fail fast when
the specialization name cannot be resolved instead of silently loading a
pointer.
Probe: `for v in list[int]` prints 10/20/30 and sums 60; the reporting
project compiles and runs without the MLIR failure; self-host 110/110;
ListTest, GenericTest3, PtrOpProbe and HashLibTest pass.
This commit is contained in:
1 parent
49683fc881
commit
91d300d45f
1 file changed
+14
-3
@@ -2023,11 +2023,22 @@ novirtual class StmtGenCifMixin:
|
||||
if cnt_ptr is None: self.Gen.TypeGenErr.fatal_error(for_node, "list iteration: failed to locate __count__")
|
||||
count_val: mlirlite.Value* = mlirlite.build_load(builder, i64_ty, cnt_ptr)
|
||||
|
||||
# loop-var alloca (element type i8*, matching inline list.get)
|
||||
# loop-var alloca (the real element type: list[int] -> i32, list[str] -> i8*).
|
||||
# A fixed i8* slot made `for i in list[int]` store a pointer-typed element and
|
||||
# poisoned later reuse of the same name (e.g. a following `for i in range(6)`
|
||||
# stored/compared integer 6 against an i8* slot).
|
||||
lst_st: mlirlite.LLVMType* = self.Gen.StructGen.get_struct_type_from_value(list_val)
|
||||
lst_nm: str = None
|
||||
if lst_st is not None: lst_nm = mlirlite.get_struct_name(lst_st)
|
||||
elem_ty: mlirlite.LLVMType* = None
|
||||
if lst_nm is not None: elem_ty = self.Gen.ExprGenName._list_elem_type_from_name(pool, lst_nm)
|
||||
if elem_ty is None:
|
||||
self.Gen.TypeGenErr.fatal_error(for_node, "list iteration: cannot determine the list element type (unresolved list[...] specialization)", "TypeError")
|
||||
return 0
|
||||
var_alloca: mlirlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, var_name)
|
||||
new_vars: int = 0
|
||||
if var_alloca is None:
|
||||
var_alloca = self.Gen.VarGen._alloca_at_entry(builder, i8_ptr_ty)
|
||||
var_alloca = self.Gen.VarGen._alloca_at_entry(builder, elem_ty)
|
||||
if self.Gen.VarGen.define_var(trans.SymTab, var_name, var_alloca) == 0: new_vars = 1
|
||||
|
||||
# implicit index variable (i64, aligned with __count__)
|
||||
@@ -2071,7 +2082,7 @@ novirtual class StmtGenCifMixin:
|
||||
esize: mlirlite.Value* = mlirlite.build_load(builder, i64_ty, epp)
|
||||
offset: mlirlite.Value* = mlirlite.build_mul(builder, cur_idx, esize)
|
||||
elem_addr: mlirlite.Value* = mlirlite.build_gep(builder, i8_ty, data_ptr, offset)
|
||||
cur_elem: mlirlite.Value* = mlirlite.build_load(builder, i8_ptr_ty, elem_addr)
|
||||
cur_elem: mlirlite.Value* = mlirlite.build_load(builder, elem_ty, elem_addr)
|
||||
mlirlite.build_store(builder, cur_elem, var_alloca)
|
||||
|
||||
# save the old loop context and set break/continue targets
|
||||
|
||||
Reference in new issue
Block a user