From f044d94e900f23331c8380fea5e9623850dc017c Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Mon, 12 Oct 2026 18:25:24 +0800 Subject: [PATCH] =?UTF-8?q?fix(gen):=20-x/~x=20=E5=AF=B9=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E6=9C=9F=E5=B8=B8=E9=87=8F=E6=8A=98=E5=8F=A0=EF=BC=8C=E4=BF=AE?= =?UTF-8?q?=E8=B4=9F=E5=AD=97=E9=9D=A2=E9=87=8F=E8=A2=AB=E9=9A=90=E5=BC=8F?= =?UTF-8?q?=E7=AA=84=E5=8C=96=E8=AF=AF=E6=8B=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- App/lib/core/Gen/Expr/ExprGenOps.vp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/App/lib/core/Gen/Expr/ExprGenOps.vp b/App/lib/core/Gen/Expr/ExprGenOps.vp index 9e73006..5985c58 100644 --- a/App/lib/core/Gen/Expr/ExprGenOps.vp +++ b/App/lib/core/Gen/Expr/ExprGenOps.vp @@ -569,9 +569,16 @@ novirtual class ExprGenOps(ExprGenBase.ExprGenBase): # -x # Float type uses fneg (emit fneg directly to avoid 0.0 - x type mismatch) operand_fbits: int = self.get_llvm_float_bits(operand.Ty) - if operand_fbits > 0: return mlirlite.build_fneg(builder, operand) - # Integer: -x = 0 - x, choosing the zero constant by bit width (avoid i32/i64 mismatch) + if operand_fbits > 0: + # 编译期常量折叠:-c 直接产出常量并保持 IsConst + 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 内(隐式窄化的“编译期常量”豁免失效)。 operand_bits: int = self.get_llvm_type_bits(operand.Ty) + if operand_bits != 0 and operand.IsConst == 1: + return mlirlite.const_int(pool, operand_bits, -operand.IntVal) + # Integer: -x = 0 - x, choosing the zero constant by bit width (avoid i32/i64 mismatch) zero: mlirlite.Value* = mlirlite.const_int32(pool, 0) if operand_bits == 64: zero = mlirlite.const_int64(pool, 0) elif operand_bits > 0 and operand_bits != 32: @@ -590,6 +597,9 @@ novirtual class ExprGenOps(ExprGenBase.ExprGenBase): elif uo.op == ast.OpKind.Invert: # ~x = x ^ -1 operand_bits_inv: int = self.get_llvm_type_bits(operand.Ty) + # 编译期常量折叠:~c 直接产出常量并保持 IsConst(与 -c 相同的窄化豁免口径) + if operand_bits_inv != 0 and operand.IsConst == 1: + return mlirlite.const_int(pool, operand_bits_inv, operand.IntVal ^ -1) neg1: mlirlite.Value* = mlirlite.const_int32(pool, -1) if operand_bits_inv == 64: neg1 = mlirlite.const_int64(pool, -1) return mlirlite.build_xor(builder, operand, neg1)