From 910c746ee2cd64d3107c02869dcafdad32821d2b Mon Sep 17 00:00:00 2001 From: Motiejus Date: Sat, 7 Mar 2026 07:28:42 +0000 Subject: [PATCH] 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) --- stage0/sema.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/stage0/sema.c b/stage0/sema.c index 1646886d70..8ad7c9836f 100644 --- a/stage0/sema.c +++ b/stage0/sema.c @@ -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); }