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); }