fix(codegen): keep unary constant folding within the operand width
This commit is contained in:
1 parent
e63fc34057
commit
8e86eea159
1 file changed
+17
-2
@@ -781,7 +781,15 @@ novirtual class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
# 触发“隐式窄化禁止”,尽管其数值完全落在 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)
|
||||
# Keep the folded value inside the operand's accepted literal range
|
||||
# [-2^(N-1), 2^N-1]: -1 stays -1, while -(-128) / -200 wrap to the N-bit pattern
|
||||
# instead of emitting an unparsable wide value.
|
||||
neg_c: int64 = -operand.IntVal
|
||||
if operand_bits < 64:
|
||||
neg_lo: int64 = -(int64(1) << (operand_bits - 1))
|
||||
neg_hi: int64 = (int64(1) << operand_bits) - 1
|
||||
if neg_c < neg_lo or neg_c > neg_hi: neg_c = neg_c & neg_hi
|
||||
return mlirlite.const_int(pool, operand_bits, neg_c)
|
||||
# Integer: -x = 0 - x;0 常量必须与**当前**操作数同宽(u 类不提升后可能是 i8/i16/i32/i64)
|
||||
zero: mlirlite.Value* = mlirlite.const_int32(pool, 0)
|
||||
if operand_bits != 0 and operand_bits != 32: zero = mlirlite.const_int(pool, operand_bits, 0)
|
||||
@@ -800,7 +808,14 @@ novirtual class ExprGenOps(ExprGenBase.ExprGenBase):
|
||||
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)
|
||||
# ~0x80 is -129 in the wide domain; for i8 emit 0x7F (127) instead. Values that
|
||||
# already fit the literal range (e.g. ~0 = -1) are left untouched.
|
||||
inv_c: int64 = operand.IntVal ^ -1
|
||||
if operand_bits_inv < 64:
|
||||
inv_lo: int64 = -(int64(1) << (operand_bits_inv - 1))
|
||||
inv_hi: int64 = (int64(1) << operand_bits_inv) - 1
|
||||
if inv_c < inv_lo or inv_c > inv_hi: inv_c = inv_c & inv_hi
|
||||
return mlirlite.const_int(pool, operand_bits_inv, inv_c)
|
||||
# -1 掩码必须与**当前**操作数同宽(u 类不提升后可能是 i8/i16/i32/i64)
|
||||
neg1: mlirlite.Value* = mlirlite.const_int32(pool, -1)
|
||||
if operand_bits_inv != 0 and operand_bits_inv != 32: neg1 = mlirlite.const_int(pool, operand_bits_inv, -1)
|
||||
|
||||
Reference in new issue
Block a user