fix(gen): 二元运算按常量无损适配另一侧位宽,修 crc(uint)^0xFFFFFFFF 被抬成 64 位
This commit is contained in:
1 parent
8453698f66
commit
65c72fd55c
2 files changed
+21
-2
No files matched your search
@@ -121,6 +121,21 @@ novirtual class ExprGenBase:
|
||||
def get_ptr_level(self, ty: mlirlite.LLVMType*) -> int:
|
||||
"""Compute pointer level (0=non-ptr, 1=ptr, 2=ptr-to-ptr); delegates to TSpec.SpecTypePtrLevel."""
|
||||
return TSpec.SpecTypePtrLevel(ty)
|
||||
# _const_fits_int_type - 编译期整型常量的值能否**无损**落进目标整型位宽。
|
||||
# 有符号或无符号任一解释放得下即算「放得下」(位型不变);用于二元运算按常量适配另一侧位宽。
|
||||
def _const_fits_int_type(self, val: mlirlite.Value*, target_ty: mlirlite.LLVMType*) -> int:
|
||||
"""1 = the integer constant's value fits the target integer width losslessly; else 0."""
|
||||
if val is None or target_ty is None or val.IsConst != 1: return 0
|
||||
bits: int = self.get_llvm_type_bits(target_ty)
|
||||
if bits <= 0 or bits > 63: return 0
|
||||
v: int64 = val.IntVal
|
||||
lo: int64 = -(int64(1) << (bits - 1))
|
||||
hi: int64 = (int64(1) << (bits - 1)) - 1
|
||||
if v >= lo and v <= hi: return 1
|
||||
if v >= 0:
|
||||
if bits == 63: return 1
|
||||
if v <= (int64(1) << bits) - 1: return 1
|
||||
return 0
|
||||
# _is_zero_int_literal - is the AST node the integer literal 0?
|
||||
# Used for ptr != 0 / ptr == 0, where 0 means NULL and is allowed.
|
||||
def _is_zero_int_literal(self, node: ast.AST*) -> int:
|
||||
|
||||
@@ -1230,10 +1230,14 @@ novirtual class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
rhs_bits = 32
|
||||
|
||||
if lhs_bits > rhs_bits:
|
||||
if self.should_zext_widen(pool, rhs, lhs, rhs_node, trans) != 0: rhs = mlirlite.build_zext(builder, rhs, lhs.Ty)
|
||||
# 宽侧是「值能无损落进窄侧」的编译期常量时,把**常量**降到窄侧类型(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)
|
||||
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.should_zext_widen(pool, lhs, rhs, lhs_node, trans) != 0: lhs = mlirlite.build_zext(builder, lhs, rhs.Ty)
|
||||
if 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)
|
||||
|
||||
# Bitwise type safety: when both sides are pointers (lhs_bits==0 and rhs_bits==0), bitwise ops are illegal (LLVM
|
||||
|
||||
Reference in new issue
Block a user