fix(gen): 常量适配限定为位运算,算术一律按 C 语义拓宽(修 i8 乘法回绕致 memhub 不变式误报)
This commit is contained in:
1 parent
e7b05c6a3d
commit
001f8afc37
1 file changed
+7
-4
@@ -1268,14 +1268,17 @@ novirtual class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
else: rhs = mlirlite.build_trunc(builder, rhs, lhs.Ty)
|
||||
rhs_bits = lhs_bits
|
||||
else:
|
||||
# 「常量适配」只对**位运算(& | ^)**生效:位运算结果不会超出参与值的位宽,把能无损落进另一侧的
|
||||
# 常量降下来是安全的。**算术(+ - * / %)不做适配**——窄位宽下会回绕(如 define 的
|
||||
# `(MEMBUDDY_MAX_ORDERS + 1) * 8`:i8(32)+1 → 33、再 ×8 溢出成 8),必须按 C 语义把窄操作数拓宽。
|
||||
is_bitwise_op: int = 0
|
||||
if op == ast.OpKind.BitAnd or op == ast.OpKind.BitOr or op == ast.OpKind.BitXor: is_bitwise_op = 1
|
||||
if lhs_bits > rhs_bits:
|
||||
# 宽侧是「值能无损落进窄侧」的编译期常量时,把**常量**降到窄侧类型(C 语义:常量优先适配另一侧),
|
||||
# 否则 `crc(u32) ^ 0xFFFFFFFF(i64)` 会把 crc 抬成 64 位,结果再赋回 32 位时报隐式窄化。
|
||||
if self._const_fits_int_type(lhs, rhs.Ty) != 0: lhs = self.coerce_to_type(builder, lhs, rhs.Ty, node, trans)
|
||||
if is_bitwise_op != 0 and self._const_fits_int_type(lhs, rhs.Ty) != 0: lhs = self.coerce_to_type(builder, lhs, rhs.Ty, node, trans)
|
||||
elif self.should_zext_widen(pool, rhs, lhs, rhs_node, trans) != 0: rhs = mlirlite.build_zext(builder, rhs, lhs.Ty)
|
||||
else: rhs = self.coerce_to_type(builder, rhs, lhs.Ty, node, trans)
|
||||
elif rhs_bits > lhs_bits:
|
||||
if self._const_fits_int_type(rhs, lhs.Ty) != 0: rhs = self.coerce_to_type(builder, rhs, lhs.Ty, node, trans)
|
||||
if is_bitwise_op != 0 and self._const_fits_int_type(rhs, lhs.Ty) != 0: rhs = self.coerce_to_type(builder, rhs, lhs.Ty, node, trans)
|
||||
elif self.should_zext_widen(pool, lhs, rhs, lhs_node, trans) != 0: lhs = mlirlite.build_zext(builder, lhs, rhs.Ty)
|
||||
else: lhs = self.coerce_to_type(builder, lhs, rhs.Ty, node, trans)
|
||||
|
||||
|
||||
Reference in new issue
Block a user