fix(gen): -x/~x 对编译期常量折叠,修负字面量被隐式窄化误拦

This commit is contained in:
TermiNexus committed 2026-10-12 18:25:24 +08:00
1 parent 87914b0a51
commit f044d94e90
1 file changed
+12 -2
+12 -2
View File
@@ -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)