sema: fix zirAbs result type for integer operands

- Unsigned int: @abs is identity, return operand directly
- Signed int: result type is the unsigned equivalent (toUnsigned)
- Float/comptime: unchanged (result_ty = operand_ty)

Matches src/Sema.zig zirAbs behavior.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-07 07:28:42 +00:00
parent d728da32f4
commit 910c746ee2

View File

@@ -1198,11 +1198,28 @@ static AirInstRef zirAbs(Sema* sema, SemaBlock* block, uint32_t inst) {
AirInstRef operand = resolveInst(sema, operand_ref);
TypeIndex operand_ty = semaTypeOf(sema, operand);
// For floats, result type is the same as operand type.
// Emit AIR_INST_ABS as ty_op.
TypeIndex result_ty = operand_ty;
if (sema->ip->items[operand_ty].tag == IP_KEY_INT_TYPE) {
if (!sema->ip->items[operand_ty].data.int_type.signedness) {
// Unsigned int: @abs is identity.
// Ported from src/Sema.zig zirAbs: `.int => if (signed) toUnsigned
// else return operand`
return operand;
}
// Signed int: result type is the unsigned equivalent.
// Ported from src/Sema.zig operand_ty.toUnsigned(pt).
InternPoolKey key;
memset(&key, 0, sizeof(key));
key.tag = IP_KEY_INT_TYPE;
key.data.int_type.bits
= sema->ip->items[operand_ty].data.int_type.bits;
key.data.int_type.signedness = false;
result_ty = ipIntern(sema->ip, key);
}
AirInstData data;
memset(&data, 0, sizeof(data));
data.ty_op.ty_ref = AIR_REF_FROM_IP(operand_ty);
data.ty_op.ty_ref = AIR_REF_FROM_IP(result_ty);
data.ty_op.operand = operand;
return semaAddInst(block, AIR_INST_ABS, data);
}