diff --git a/App/lib/core/Gen/Expr/ExprGenMixin.vp b/App/lib/core/Gen/Expr/ExprGenMixin.vp index 5ebbd65..c844359 100644 --- a/App/lib/core/Gen/Expr/ExprGenMixin.vp +++ b/App/lib/core/Gen/Expr/ExprGenMixin.vp @@ -51,7 +51,7 @@ novirtual class ExprGenMixin(ExprGenBase.ExprGenBase): # M2.4 `new stack|heap|memgr(x) [slife|hlife] T(args)`:只换"取存储",其余复用构造序列 elif k == ast.ASTKind.New: return self.Gen.CallGenCtor._translate_new_expr(pool, builder, mod, ast.New*(node), trans) elif k == ast.ASTKind.Compare: return self.Gen.ExprGenOps.translate_compare(builder, pool, mod, node, trans) - elif k == ast.ASTKind.UnaryOp: return self.Gen.ExprGenOps.translate_unaryop(builder, pool, mod, node, trans, target_ty) + elif k == ast.ASTKind.UnaryOp: return self.Gen.ExprGenOps.translate_unaryop(builder, pool, mod, node, trans) elif k == ast.ASTKind.BoolOp: return self.Gen.ExprGenOps.translate_boolop(builder, pool, mod, node, funcs_ptr, func_count, trans) elif k == ast.ASTKind.Subscript: return self.Gen.ExprGenName.translate_subscript(builder, pool, mod, node, trans) elif k == ast.ASTKind.Attribute: return self.Gen.ExprGenAttr.translate_attribute(builder, pool, mod, node, trans) diff --git a/App/lib/core/Gen/Expr/ExprGenOps.vp b/App/lib/core/Gen/Expr/ExprGenOps.vp index 49055bf..a882e8d 100644 --- a/App/lib/core/Gen/Expr/ExprGenOps.vp +++ b/App/lib/core/Gen/Expr/ExprGenOps.vp @@ -654,7 +654,7 @@ novirtual class ExprGenOps(ExprGenBase.ExprGenBase): return mlirlite.build_icmp(builder, predicate, lhs, rhs) # translate_unaryop - UnaryOp(op, operand) # ============================================================ - def translate_unaryop(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, node: ast.AST*, trans: HT.Translator* = None, target_ty: mlirlite.LLVMType* = None) -> mlirlite.Value*: + def translate_unaryop(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, node: ast.AST*, trans: HT.Translator* = None) -> mlirlite.Value*: """Translate unary operations (-x, +x, not x, ~x).""" uo: ast.UnaryOp* = ast.UnaryOp*(node) if uo is None: return None @@ -688,12 +688,11 @@ novirtual class ExprGenOps(ExprGenBase.ExprGenBase): operand_fbits: int = self.get_llvm_float_bits(operand.Ty) if operand_fbits > 0: # 编译期常量折叠:-c 直接产出常量并保持 IsConst - if operand.IsConst == 1: - # 目标类型是 32 位浮点(`float(-3.5)` / `x: float = -3.5`)→ 直接出 f32 常量, - # 不再"f64 常量 + fptrunc"(与 ExprGenConst.translate_constant 的浮点字面量同口径)。 - if target_ty is not None and self.get_llvm_float_bits(target_ty) == 32: - return mlirlite.ConstFloat(pool, target_ty, -operand.FloatVal) - return mlirlite.ConstFloat(pool, operand.Ty, -operand.FloatVal) + # 保持"按操作数自身类型出常量"(f64 常量 → 由使用处 coerce 出 fptrunc): + # 这里**不允许**改成按使用处目标类型直接出 f32 常量 —— 现场验证该路径产出的 + # f32 负常量在 MLIR 渲染阶段被判定为位宽不匹配(`_MlirFloatLiteral`), + # 整个 VKernel 编不过;正号字面量那条路(ExprGenConst.translate_constant)不受影响。 + if operand.IsConst == 1: return mlirlite.ConstFloat(pool, operand.Ty, -operand.FloatVal) return mlirlite.build_fneg(builder, operand) # 编译期常量折叠:-c 直接产出常量(IsConst=1)。否则 `v: int8 = -50` 会被当成运行时 i32 值, # 触发“隐式窄化禁止”,尽管其数值完全落在 i8 内(隐式窄化的“编译期常量”豁免失效)。 diff --git a/App/lib/core/Gen/Type/TypeGenCDef.vp b/App/lib/core/Gen/Type/TypeGenCDef.vp index 0e1cc6e..b87be48 100644 --- a/App/lib/core/Gen/Type/TypeGenCDef.vp +++ b/App/lib/core/Gen/Type/TypeGenCDef.vp @@ -26,8 +26,10 @@ define CDEF_IDX_FNV_MASK = 4294967295 # CDefine 浮点常量的宽度种类(CDefineDoubleFlags / XmodCdefDoubleFlags 条目编码)。 # 1=f64(double,默认),2=f32(float);0 表示非浮点。既有读取处一律按 `!= 0` 判定 # "是浮点常量",故 f32 天然兼容;只有浮点常量的物化处需要区分 64/32。 -define CDEFINE_FLOAT_KIND_F64 = 1 -define CDEFINE_FLOAT_KIND_F32 = 2 +# 必须写明 `: int`:无注解 define 按**值的最小可存宽度**物化(1/2 → i8), +# 直接当实参调用 `list[int].append(x: int)` 会落成 `i8 != i32`(mlir-opt 校验失败)。 +define CDEFINE_FLOAT_KIND_F64: int = 1 +define CDEFINE_FLOAT_KIND_F32: int = 2 # TypeGenCDef - split from TypeGenMixin (stage D): CDefine compile-time constant table (register/lookup/is/set/clear)