From ea2af739ddc91a2f26c7038f9b640343bc0e2527 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Mon, 12 Oct 2026 20:57:12 +0800 Subject: [PATCH] =?UTF-8?q?feat(gen):=20range=20=E8=BE=B9=E7=95=8C?= =?UTF-8?q?=E4=B8=8E=E5=BE=AA=E7=8E=AF=E5=8F=98=E9=87=8F=E7=BB=9F=E4=B8=80?= =?UTF-8?q?=E6=8F=90=E5=8D=87=E5=88=B0=E8=87=B3=E5=B0=91=20i32=EF=BC=88?= =?UTF-8?q?=E5=8F=96=E6=B6=88=20u8/u16=20=E5=BE=AA=E7=8E=AF=E5=8F=98?= =?UTF-8?q?=E9=87=8F=E6=A1=A3=EF=BC=89=EF=BC=8Cu64=20=E8=BE=B9=E7=95=8C?= =?UTF-8?q?=E4=BF=9D=E6=8C=81=20i64?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- App/lib/core/Gen/Stmt/StmtGenCifMixin.vp | 26 ++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/App/lib/core/Gen/Stmt/StmtGenCifMixin.vp b/App/lib/core/Gen/Stmt/StmtGenCifMixin.vp index 7e76834..c9d2e78 100644 --- a/App/lib/core/Gen/Stmt/StmtGenCifMixin.vp +++ b/App/lib/core/Gen/Stmt/StmtGenCifMixin.vp @@ -1115,8 +1115,28 @@ novirtual class StmtGenCifMixin: skc_r: ast.Constant* = ast.Constant*(step_arg_node) if skc_r.int_val < 0: step_neg_const = 1 - # 3.5 loop-var storage width follows range arg type (u64→i64 / u16→i16 / u8→i8 / else i32); - # a fixed i32 alloca truncates uint64 bounds. Applies only to undeclared loop vars. + # 3.4 range 边界统一提升到**至少 i32**(仿 C 整数提升):i8/i16 边界不再以窄位宽参与比较 + # 与自增。拓宽方向由 coerce_to_type → should_zext_widen 决定:非负 define 常量是**无符号 + # 位模式**(Debugger/define-constants.md §7.2),必须 zext(define N = 50000 → 16 位 0xC350 + # → 50000,而非 sext 成 -15536)。u64 边界保持 i64(不动,避免截断)。 + if stop_val is not None and stop_val.Ty is not None: + sb_p4: int = self.Gen.ExprGenBase.get_llvm_type_bits(stop_val.Ty) + if sb_p4 != 0 and sb_p4 < 32: + nd_s4: ast.AST* = args.get(0) + if arg_count >= 2: nd_s4 = args.get(1) + stop_val = self.Gen.ExprGenBase.coerce_to_type(builder, stop_val, i32_ty, nd_s4, trans) + if start_val is not None and start_val.Ty is not None: + sa_p4: int = self.Gen.ExprGenBase.get_llvm_type_bits(start_val.Ty) + if sa_p4 != 0 and sa_p4 < 32: + start_val = self.Gen.ExprGenBase.coerce_to_type(builder, start_val, i32_ty, args.get(0), trans) + if step_val is not None and step_val.Ty is not None: + sp_p4: int = self.Gen.ExprGenBase.get_llvm_type_bits(step_val.Ty) + if sp_p4 != 0 and sp_p4 < 32: + step_val = self.Gen.ExprGenBase.coerce_to_type(builder, step_val, i32_ty, args.get(2), trans) + + # 3.5 loop-var storage width: 边界已提升到 ≥i32,所以只有 i64 边界需要 i64 循环变量, + # 其余一律 i32(不再有 u16→i16 / u8→i8 档:窄位宽循环变量会把边界截断)。 + # Applies only to undeclared loop vars. loop_store_ty: mlirlite.LLVMType* = i32_ty range_arg_bits: int = 0 if arg_count == 1: @@ -1128,8 +1148,6 @@ novirtual class StmtGenCifMixin: if stop_val is not None and stop_val.Ty is not None: stop_bits_rt = self.Gen.ExprGenBase.get_llvm_type_bits(stop_val.Ty) range_arg_bits = start_bits_rt if start_bits_rt > stop_bits_rt else stop_bits_rt if range_arg_bits == 64: loop_store_ty = mlirlite.Int64(pool) - elif range_arg_bits == 16: loop_store_ty = mlirlite.Int16(pool) - elif range_arg_bits == 8: loop_store_ty = mlirlite.Int8(pool) # 3.6 loop unsignedness: an unsigned loop-var annotation or any unsigned range bound uses # icmp ult/ugt instead of slt/sgt (via ExprGenOps._node_type_unsigned).