From 54160e7f6aecb4628df633ceaef4c6d956429a3d Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Wed, 21 Dec 2022 14:33:02 +0200 Subject: [PATCH] Sema: make overflow arithmetic builtins return tuples --- src/AstGen.zig | 28 ++------ src/Autodoc.zig | 20 ------ src/BuiltinFn.zig | 8 +-- src/Sema.zig | 166 +++++++++++++++++++++------------------------ src/TypedValue.zig | 4 +- src/Zir.zig | 27 ++------ src/print_zir.zig | 6 +- src/type.zig | 1 + src/value.zig | 19 +++--- 9 files changed, 104 insertions(+), 175 deletions(-) diff --git a/src/AstGen.zig b/src/AstGen.zig index 405bc1ccc3..1f8e2dd881 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -2505,7 +2505,6 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As .err_union_code, .err_union_code_ptr, .ptr_type, - .overflow_arithmetic_ptr, .enum_literal, .merge_error_sets, .error_union_type, @@ -2543,7 +2542,6 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As .type_info, .size_of, .bit_size_of, - .log2_int_type, .typeof_log2_int_type, .ptr_to_int, .align_of, @@ -8236,21 +8234,7 @@ fn builtinCall( .add_with_overflow => return overflowArithmetic(gz, scope, ri, node, params, .add_with_overflow), .sub_with_overflow => return overflowArithmetic(gz, scope, ri, node, params, .sub_with_overflow), .mul_with_overflow => return overflowArithmetic(gz, scope, ri, node, params, .mul_with_overflow), - .shl_with_overflow => { - const int_type = try typeExpr(gz, scope, params[0]); - const log2_int_type = try gz.addUnNode(.log2_int_type, int_type, params[0]); - const ptr_type = try gz.addUnNode(.overflow_arithmetic_ptr, int_type, params[0]); - const lhs = try expr(gz, scope, .{ .rl = .{ .ty = int_type } }, params[1]); - const rhs = try expr(gz, scope, .{ .rl = .{ .ty = log2_int_type } }, params[2]); - const ptr = try expr(gz, scope, .{ .rl = .{ .ty = ptr_type } }, params[3]); - const result = try gz.addExtendedPayload(.shl_with_overflow, Zir.Inst.OverflowArithmetic{ - .node = gz.nodeIndexToRelative(node), - .lhs = lhs, - .rhs = rhs, - .ptr = ptr, - }); - return rvalue(gz, ri, result, node); - }, + .shl_with_overflow => return overflowArithmetic(gz, scope, ri, node, params, .shl_with_overflow), .atomic_load => { const result = try gz.addPlNode(.atomic_load, node, Zir.Inst.AtomicLoad{ @@ -8691,16 +8675,12 @@ fn overflowArithmetic( params: []const Ast.Node.Index, tag: Zir.Inst.Extended, ) InnerError!Zir.Inst.Ref { - const int_type = try typeExpr(gz, scope, params[0]); - const ptr_type = try gz.addUnNode(.overflow_arithmetic_ptr, int_type, params[0]); - const lhs = try expr(gz, scope, .{ .rl = .{ .ty = int_type } }, params[1]); - const rhs = try expr(gz, scope, .{ .rl = .{ .ty = int_type } }, params[2]); - const ptr = try expr(gz, scope, .{ .rl = .{ .ty = ptr_type } }, params[3]); - const result = try gz.addExtendedPayload(tag, Zir.Inst.OverflowArithmetic{ + const lhs = try expr(gz, scope, .{ .rl = .none }, params[0]); + const rhs = try expr(gz, scope, .{ .rl = .none }, params[1]); + const result = try gz.addExtendedPayload(tag, Zir.Inst.BinNode{ .node = gz.nodeIndexToRelative(node), .lhs = lhs, .rhs = rhs, - .ptr = ptr, }); return rvalue(gz, ri, result, node); } diff --git a/src/Autodoc.zig b/src/Autodoc.zig index 246b97037a..7664d6cdbf 100644 --- a/src/Autodoc.zig +++ b/src/Autodoc.zig @@ -1510,26 +1510,6 @@ fn walkInstruction( // return operand; // }, - .overflow_arithmetic_ptr => { - const un_node = data[inst_index].un_node; - - const elem_type_ref = try self.walkRef(file, parent_scope, parent_src, un_node.operand, false); - const type_slot_index = self.types.items.len; - try self.types.append(self.arena, .{ - .Pointer = .{ - .size = .One, - .child = elem_type_ref.expr, - .is_mutable = true, - .is_volatile = false, - .is_allowzero = false, - }, - }); - - return DocData.WalkResult{ - .typeRef = .{ .type = @enumToInt(Ref.type_type) }, - .expr = .{ .type = type_slot_index }, - }; - }, .ptr_type => { const ptr = data[inst_index].ptr_type; const extra = file.zir.extraData(Zir.Inst.PtrType, ptr.payload_index); diff --git a/src/BuiltinFn.zig b/src/BuiltinFn.zig index 7e23be2a3a..b71d96c3dd 100644 --- a/src/BuiltinFn.zig +++ b/src/BuiltinFn.zig @@ -154,7 +154,7 @@ pub const list = list: { "@addWithOverflow", .{ .tag = .add_with_overflow, - .param_count = 4, + .param_count = 2, }, }, .{ @@ -636,7 +636,7 @@ pub const list = list: { "@mulWithOverflow", .{ .tag = .mul_with_overflow, - .param_count = 4, + .param_count = 2, }, }, .{ @@ -741,7 +741,7 @@ pub const list = list: { "@shlWithOverflow", .{ .tag = .shl_with_overflow, - .param_count = 4, + .param_count = 2, }, }, .{ @@ -889,7 +889,7 @@ pub const list = list: { "@subWithOverflow", .{ .tag = .sub_with_overflow, - .param_count = 4, + .param_count = 2, }, }, .{ diff --git a/src/Sema.zig b/src/Sema.zig index d25f3076d2..6546708aaa 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -971,7 +971,6 @@ fn analyzeBodyInner( .optional_payload_unsafe_ptr => try sema.zirOptionalPayloadPtr(block, inst, false), .optional_type => try sema.zirOptionalType(block, inst), .ptr_type => try sema.zirPtrType(block, inst), - .overflow_arithmetic_ptr => try sema.zirOverflowArithmeticPtr(block, inst), .ref => try sema.zirRef(block, inst), .ret_err_value_code => try sema.zirRetErrValueCode(inst), .shr => try sema.zirShr(block, inst, .shr), @@ -993,7 +992,6 @@ fn analyzeBodyInner( .bit_size_of => try sema.zirBitSizeOf(block, inst), .typeof => try sema.zirTypeof(block, inst), .typeof_builtin => try sema.zirTypeofBuiltin(block, inst), - .log2_int_type => try sema.zirLog2IntType(block, inst), .typeof_log2_int_type => try sema.zirTypeofLog2IntType(block, inst), .xor => try sema.zirBitwise(block, inst, .xor), .struct_init_empty => try sema.zirStructInitEmpty(block, inst), @@ -11762,7 +11760,7 @@ fn zirShl( if (scalar_ty.zigTypeTag() == .ComptimeInt) { break :val shifted.wrapped_result; } - if (shifted.overflowed.compareAllWithZero(.eq)) { + if (shifted.overflow_bit.compareAllWithZero(.eq)) { break :val shifted.wrapped_result; } return sema.fail(block, src, "operation caused overflow", .{}); @@ -13783,24 +13781,37 @@ fn zirOverflowArithmetic( const tracy = trace(@src()); defer tracy.end(); - const extra = sema.code.extraData(Zir.Inst.OverflowArithmetic, extended.operand).data; + const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data; const src = LazySrcLoc.nodeOffset(extra.node); const lhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node }; const rhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node }; - const ptr_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = extra.node }; - const lhs = try sema.resolveInst(extra.lhs); - const rhs = try sema.resolveInst(extra.rhs); - const ptr = try sema.resolveInst(extra.ptr); + const uncasted_lhs = try sema.resolveInst(extra.lhs); + const uncasted_rhs = try sema.resolveInst(extra.rhs); - const lhs_ty = sema.typeOf(lhs); - const rhs_ty = sema.typeOf(rhs); + const lhs_ty = sema.typeOf(uncasted_lhs); + const rhs_ty = sema.typeOf(uncasted_rhs); const mod = sema.mod; - // Note, the types of lhs/rhs (also for shifting)/ptr are already correct as ensured by astgen. try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); - const dest_ty = lhs_ty; + + const instructions = &[_]Air.Inst.Ref{ uncasted_lhs, uncasted_rhs }; + const dest_ty = if (zir_tag == .shl_with_overflow) + lhs_ty + else + try sema.resolvePeerTypes(block, src, instructions, .{ + .override = &[_]LazySrcLoc{ lhs_src, rhs_src }, + }); + + const rhs_dest_ty = if (zir_tag == .shl_with_overflow) + try sema.log2IntType(block, lhs_ty, src) + else + dest_ty; + + const lhs = try sema.coerce(block, dest_ty, uncasted_lhs, lhs_src); + const rhs = try sema.coerce(block, rhs_dest_ty, uncasted_rhs, rhs_src); + if (dest_ty.scalarType().zigTypeTag() != .Int) { return sema.fail(block, src, "expected vector of integers or integer tag type, found '{}'", .{dest_ty.fmt(mod)}); } @@ -13809,14 +13820,11 @@ fn zirOverflowArithmetic( const maybe_rhs_val = try sema.resolveMaybeUndefVal(rhs); const tuple_ty = try sema.overflowArithmeticTupleType(dest_ty); - // TODO: Remove and use `ov_ty` instead. - // This is a temporary type used until overflow arithmetic properly returns `u1` instead of `bool`. - const overflowed_ty = if (dest_ty.zigTypeTag() == .Vector) try Type.vector(sema.arena, dest_ty.vectorLen(), Type.bool) else Type.bool; - const result: struct { - /// TODO: Rename to `overflow_bit` and make of type `u1`. - overflowed: Air.Inst.Ref, - wrapped: Air.Inst.Ref, + var result: struct { + inst: Air.Inst.Ref = .none, + wrapped: Value = Value.initTag(.unreachable_value), + overflow_bit: Value, } = result: { switch (zir_tag) { .add_with_overflow => { @@ -13825,24 +13833,22 @@ fn zirOverflowArithmetic( // Otherwise, if either of the argument is undefined, undefined is returned. if (maybe_lhs_val) |lhs_val| { if (!lhs_val.isUndef() and (try lhs_val.compareAllWithZeroAdvanced(.eq, sema))) { - break :result .{ .overflowed = try sema.addBool(overflowed_ty, false), .wrapped = rhs }; + break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, Value.zero), .inst = rhs }; } } if (maybe_rhs_val) |rhs_val| { if (!rhs_val.isUndef() and (try rhs_val.compareAllWithZeroAdvanced(.eq, sema))) { - break :result .{ .overflowed = try sema.addBool(overflowed_ty, false), .wrapped = lhs }; + break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, Value.zero), .inst = lhs }; } } if (maybe_lhs_val) |lhs_val| { if (maybe_rhs_val) |rhs_val| { if (lhs_val.isUndef() or rhs_val.isUndef()) { - break :result .{ .overflowed = try sema.addConstUndef(overflowed_ty), .wrapped = try sema.addConstUndef(dest_ty) }; + break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef }; } const result = try sema.intAddWithOverflow(lhs_val, rhs_val, dest_ty); - const overflowed = try sema.addConstant(overflowed_ty, result.overflowed); - const wrapped = try sema.addConstant(dest_ty, result.wrapped_result); - break :result .{ .overflowed = overflowed, .wrapped = wrapped }; + break :result .{ .overflow_bit = result.overflow_bit, .wrapped = result.wrapped_result }; } } }, @@ -13851,18 +13857,16 @@ fn zirOverflowArithmetic( // Otherwise, if either result is undefined, both results are undefined. if (maybe_rhs_val) |rhs_val| { if (rhs_val.isUndef()) { - break :result .{ .overflowed = try sema.addConstUndef(overflowed_ty), .wrapped = try sema.addConstUndef(dest_ty) }; + break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef }; } else if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) { - break :result .{ .overflowed = try sema.addBool(overflowed_ty, false), .wrapped = lhs }; + break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, Value.zero), .inst = lhs }; } else if (maybe_lhs_val) |lhs_val| { if (lhs_val.isUndef()) { - break :result .{ .overflowed = try sema.addConstUndef(overflowed_ty), .wrapped = try sema.addConstUndef(dest_ty) }; + break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef }; } const result = try sema.intSubWithOverflow(lhs_val, rhs_val, dest_ty); - const overflowed = try sema.addConstant(overflowed_ty, result.overflowed); - const wrapped = try sema.addConstant(dest_ty, result.wrapped_result); - break :result .{ .overflowed = overflowed, .wrapped = wrapped }; + break :result .{ .overflow_bit = result.overflow_bit, .wrapped = result.wrapped_result }; } } }, @@ -13873,9 +13877,9 @@ fn zirOverflowArithmetic( if (maybe_lhs_val) |lhs_val| { if (!lhs_val.isUndef()) { if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) { - break :result .{ .overflowed = try sema.addBool(overflowed_ty, false), .wrapped = lhs }; - } else if (try sema.compareAll(lhs_val, .eq, Value.one, dest_ty)) { - break :result .{ .overflowed = try sema.addBool(overflowed_ty, false), .wrapped = rhs }; + break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, Value.zero), .inst = lhs }; + } else if (try sema.compareAll(lhs_val, .eq, try maybeRepeated(sema, dest_ty, Value.one), dest_ty)) { + break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, Value.zero), .inst = rhs }; } } } @@ -13883,9 +13887,9 @@ fn zirOverflowArithmetic( if (maybe_rhs_val) |rhs_val| { if (!rhs_val.isUndef()) { if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) { - break :result .{ .overflowed = try sema.addBool(overflowed_ty, false), .wrapped = rhs }; - } else if (try sema.compareAll(rhs_val, .eq, Value.one, dest_ty)) { - break :result .{ .overflowed = try sema.addBool(overflowed_ty, false), .wrapped = lhs }; + break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, Value.zero), .inst = rhs }; + } else if (try sema.compareAll(rhs_val, .eq, try maybeRepeated(sema, dest_ty, Value.one), dest_ty)) { + break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, Value.zero), .inst = lhs }; } } } @@ -13893,13 +13897,11 @@ fn zirOverflowArithmetic( if (maybe_lhs_val) |lhs_val| { if (maybe_rhs_val) |rhs_val| { if (lhs_val.isUndef() or rhs_val.isUndef()) { - break :result .{ .overflowed = try sema.addConstUndef(overflowed_ty), .wrapped = try sema.addConstUndef(dest_ty) }; + break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef }; } const result = try lhs_val.intMulWithOverflow(rhs_val, dest_ty, sema.arena, mod); - const overflowed = try sema.addConstant(overflowed_ty, result.overflowed); - const wrapped = try sema.addConstant(dest_ty, result.wrapped_result); - break :result .{ .overflowed = overflowed, .wrapped = wrapped }; + break :result .{ .overflow_bit = result.overflow_bit, .wrapped = result.wrapped_result }; } } }, @@ -13909,24 +13911,22 @@ fn zirOverflowArithmetic( // Oterhwise if either of the arguments is undefined, both results are undefined. if (maybe_lhs_val) |lhs_val| { if (!lhs_val.isUndef() and (try lhs_val.compareAllWithZeroAdvanced(.eq, sema))) { - break :result .{ .overflowed = try sema.addBool(overflowed_ty, false), .wrapped = lhs }; + break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, Value.zero), .inst = lhs }; } } if (maybe_rhs_val) |rhs_val| { if (!rhs_val.isUndef() and (try rhs_val.compareAllWithZeroAdvanced(.eq, sema))) { - break :result .{ .overflowed = try sema.addBool(overflowed_ty, false), .wrapped = lhs }; + break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, Value.zero), .inst = lhs }; } } if (maybe_lhs_val) |lhs_val| { if (maybe_rhs_val) |rhs_val| { if (lhs_val.isUndef() or rhs_val.isUndef()) { - break :result .{ .overflowed = try sema.addConstUndef(overflowed_ty), .wrapped = try sema.addConstUndef(dest_ty) }; + break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef }; } const result = try lhs_val.shlWithOverflow(rhs_val, dest_ty, sema.arena, sema.mod); - const overflowed = try sema.addConstant(overflowed_ty, result.overflowed); - const wrapped = try sema.addConstant(dest_ty, result.wrapped_result); - break :result .{ .overflowed = overflowed, .wrapped = wrapped }; + break :result .{ .overflow_bit = result.overflow_bit, .wrapped = result.wrapped_result }; } } }, @@ -13944,7 +13944,7 @@ fn zirOverflowArithmetic( const runtime_src = if (maybe_lhs_val == null) lhs_src else rhs_src; try sema.requireRuntimeBlock(block, src, runtime_src); - const tuple = try block.addInst(.{ + return block.addInst(.{ .tag = air_tag, .data = .{ .ty_pl = .{ .ty = try block.sema.addType(tuple_ty), @@ -13954,16 +13954,32 @@ fn zirOverflowArithmetic( }), } }, }); - - const wrapped = try sema.tupleFieldValByIndex(block, src, tuple, 0, tuple_ty); - try sema.storePtr2(block, src, ptr, ptr_src, wrapped, src, .store); - - const overflow_bit = try sema.tupleFieldValByIndex(block, src, tuple, 1, tuple_ty); - return block.addBitCast(overflowed_ty, overflow_bit); }; - try sema.storePtr2(block, src, ptr, ptr_src, result.wrapped, src, .store); - return result.overflowed; + if (result.inst != .none) { + if (try sema.resolveMaybeUndefVal(result.inst)) |some| { + result.wrapped = some; + result.inst = .none; + } + } + + if (result.inst == .none) { + const values = try sema.arena.alloc(Value, 2); + values[0] = result.wrapped; + values[1] = result.overflow_bit; + const tuple_val = try Value.Tag.aggregate.create(sema.arena, values); + return sema.addConstant(tuple_ty, tuple_val); + } + + const element_refs = try sema.arena.alloc(Air.Inst.Ref, 2); + element_refs[0] = result.inst; + element_refs[1] = try sema.addConstant(tuple_ty.structFieldType(1), result.overflow_bit); + return block.addAggregateInit(tuple_ty, element_refs); +} + +fn maybeRepeated(sema: *Sema, ty: Type, val: Value) !Value { + if (ty.zigTypeTag() != .Vector) return val; + return Value.Tag.repeated.create(sema.arena, val); } fn overflowArithmeticTupleType(sema: *Sema, ty: Type) !Type { @@ -16211,14 +16227,6 @@ fn zirTypeofLog2IntType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil return sema.addType(res_ty); } -fn zirLog2IntType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { - const inst_data = sema.code.instructions.items(.data)[inst].un_node; - const src = inst_data.src(); - const operand = try sema.resolveType(block, src, inst_data.operand); - const res_ty = try sema.log2IntType(block, operand, src); - return sema.addType(res_ty); -} - fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) CompileError!Type { switch (operand.zigTypeTag()) { .ComptimeInt => return Type.comptime_int, @@ -17039,24 +17047,6 @@ fn floatOpAllowed(tag: Zir.Inst.Tag) bool { }; } -fn zirOverflowArithmeticPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { - const tracy = trace(@src()); - defer tracy.end(); - - const inst_data = sema.code.instructions.items(.data)[inst].un_node; - const elem_ty_src = inst_data.src(); - const elem_type = try sema.resolveType(block, elem_ty_src, inst_data.operand); - const ty = try Type.ptr(sema.arena, sema.mod, .{ - .pointee_type = elem_type, - .@"addrspace" = .generic, - .mutable = true, - .@"allowzero" = false, - .@"volatile" = false, - .size = .One, - }); - return sema.addType(ty); -} - fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -32613,11 +32603,11 @@ fn intSubWithOverflow( const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf); const rhs_elem = rhs.elemValueBuffer(sema.mod, i, &rhs_buf); const of_math_result = try sema.intSubWithOverflowScalar(lhs_elem, rhs_elem, ty.scalarType()); - overflowed_data[i] = of_math_result.overflowed; + overflowed_data[i] = of_math_result.overflow_bit; scalar.* = of_math_result.wrapped_result; } return Value.OverflowArithmeticResult{ - .overflowed = try Value.Tag.aggregate.create(sema.arena, overflowed_data), + .overflow_bit = try Value.Tag.aggregate.create(sema.arena, overflowed_data), .wrapped_result = try Value.Tag.aggregate.create(sema.arena, result_data), }; } @@ -32645,7 +32635,7 @@ fn intSubWithOverflowScalar( const overflowed = result_bigint.subWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits); const wrapped_result = try Value.fromBigInt(sema.arena, result_bigint.toConst()); return Value.OverflowArithmeticResult{ - .overflowed = Value.makeBool(overflowed), + .overflow_bit = Value.boolToInt(overflowed), .wrapped_result = wrapped_result, }; } @@ -32964,11 +32954,11 @@ fn intAddWithOverflow( const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf); const rhs_elem = rhs.elemValueBuffer(sema.mod, i, &rhs_buf); const of_math_result = try sema.intAddWithOverflowScalar(lhs_elem, rhs_elem, ty.scalarType()); - overflowed_data[i] = of_math_result.overflowed; + overflowed_data[i] = of_math_result.overflow_bit; scalar.* = of_math_result.wrapped_result; } return Value.OverflowArithmeticResult{ - .overflowed = try Value.Tag.aggregate.create(sema.arena, overflowed_data), + .overflow_bit = try Value.Tag.aggregate.create(sema.arena, overflowed_data), .wrapped_result = try Value.Tag.aggregate.create(sema.arena, result_data), }; } @@ -32996,7 +32986,7 @@ fn intAddWithOverflowScalar( const overflowed = result_bigint.addWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits); const result = try Value.fromBigInt(sema.arena, result_bigint.toConst()); return Value.OverflowArithmeticResult{ - .overflowed = Value.makeBool(overflowed), + .overflow_bit = Value.boolToInt(overflowed), .wrapped_result = result, }; } diff --git a/src/TypedValue.zig b/src/TypedValue.zig index 805448d540..6e096ee90a 100644 --- a/src/TypedValue.zig +++ b/src/TypedValue.zig @@ -225,9 +225,7 @@ pub fn print( .one => return writer.writeAll("1"), .void_value => return writer.writeAll("{}"), .unreachable_value => return writer.writeAll("unreachable"), - .the_only_possible_value => { - val = ty.onePossibleValue().?; - }, + .the_only_possible_value => return writer.writeAll("0"), .bool_true => return writer.writeAll("true"), .bool_false => return writer.writeAll("false"), .ty => return val.castTag(.ty).?.data.print(writer, mod), diff --git a/src/Zir.zig b/src/Zir.zig index cb0923eddf..ffe1f4c345 100644 --- a/src/Zir.zig +++ b/src/Zir.zig @@ -539,9 +539,6 @@ pub const Inst = struct { /// Obtains the return type of the in-scope function. /// Uses the `node` union field. ret_type, - /// Create a pointer type for overflow arithmetic. - /// TODO remove when doing https://github.com/ziglang/zig/issues/10248 - overflow_arithmetic_ptr, /// Create a pointer type which can have a sentinel, alignment, address space, and/or bit range. /// Uses the `ptr_type` union field. ptr_type, @@ -600,9 +597,6 @@ pub const Inst = struct { /// Returns the integer type for the RHS of a shift operation. /// Uses the `un_node` field. typeof_log2_int_type, - /// Given an integer type, returns the integer type for the RHS of a shift operation. - /// Uses the `un_node` field. - log2_int_type, /// Asserts control-flow will not reach this instruction (`unreachable`). /// Uses the `unreachable` union field. @"unreachable", @@ -1121,7 +1115,6 @@ pub const Inst = struct { .err_union_code, .err_union_code_ptr, .ptr_type, - .overflow_arithmetic_ptr, .enum_literal, .merge_error_sets, .error_union_type, @@ -1132,7 +1125,6 @@ pub const Inst = struct { .slice_sentinel, .import, .typeof_log2_int_type, - .log2_int_type, .resolve_inferred_alloc, .set_eval_branch_quota, .switch_capture, @@ -1422,7 +1414,6 @@ pub const Inst = struct { .err_union_code, .err_union_code_ptr, .ptr_type, - .overflow_arithmetic_ptr, .enum_literal, .merge_error_sets, .error_union_type, @@ -1433,7 +1424,6 @@ pub const Inst = struct { .slice_sentinel, .import, .typeof_log2_int_type, - .log2_int_type, .switch_capture, .switch_capture_ref, .switch_capture_multi, @@ -1664,7 +1654,6 @@ pub const Inst = struct { .ret_err_value_code = .str_tok, .ret_ptr = .node, .ret_type = .node, - .overflow_arithmetic_ptr = .un_node, .ptr_type = .ptr_type, .slice_start = .pl_node, .slice_end = .pl_node, @@ -1678,7 +1667,6 @@ pub const Inst = struct { .negate_wrap = .un_node, .typeof = .un_node, .typeof_log2_int_type = .un_node, - .log2_int_type = .un_node, .@"unreachable" = .@"unreachable", .xor = .pl_node, .optional_type = .un_node, @@ -1916,19 +1904,19 @@ pub const Inst = struct { /// The AST node is the builtin call. typeof_peer, /// Implements the `@addWithOverflow` builtin. - /// `operand` is payload index to `OverflowArithmetic`. + /// `operand` is payload index to `BinNode`. /// `small` is unused. add_with_overflow, /// Implements the `@subWithOverflow` builtin. - /// `operand` is payload index to `OverflowArithmetic`. + /// `operand` is payload index to `BinNode`. /// `small` is unused. sub_with_overflow, /// Implements the `@mulWithOverflow` builtin. - /// `operand` is payload index to `OverflowArithmetic`. + /// `operand` is payload index to `BinNode`. /// `small` is unused. mul_with_overflow, /// Implements the `@shlWithOverflow` builtin. - /// `operand` is payload index to `OverflowArithmetic`. + /// `operand` is payload index to `BinNode`. /// `small` is unused. shl_with_overflow, /// `operand` is payload index to `UnNode`. @@ -3430,13 +3418,6 @@ pub const Inst = struct { field_name: Ref, }; - pub const OverflowArithmetic = struct { - node: i32, - lhs: Ref, - rhs: Ref, - ptr: Ref, - }; - pub const Cmpxchg = struct { node: i32, ptr: Ref, diff --git a/src/print_zir.zig b/src/print_zir.zig index bc4dc84075..49c97a5bc7 100644 --- a/src/print_zir.zig +++ b/src/print_zir.zig @@ -185,7 +185,6 @@ const Writer = struct { .size_of, .bit_size_of, .typeof_log2_int_type, - .log2_int_type, .ptr_to_int, .compile_error, .set_eval_branch_quota, @@ -230,7 +229,6 @@ const Writer = struct { .validate_struct_init_ty, .make_ptr_const, .validate_deref, - .overflow_arithmetic_ptr, .check_comptime_control_flow, => try self.writeUnNode(stream, inst), @@ -1153,14 +1151,12 @@ const Writer = struct { } fn writeOverflowArithmetic(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void { - const extra = self.code.extraData(Zir.Inst.OverflowArithmetic, extended.operand).data; + const extra = self.code.extraData(Zir.Inst.BinNode, extended.operand).data; const src = LazySrcLoc.nodeOffset(extra.node); try self.writeInstRef(stream, extra.lhs); try stream.writeAll(", "); try self.writeInstRef(stream, extra.rhs); - try stream.writeAll(", "); - try self.writeInstRef(stream, extra.ptr); try stream.writeAll(")) "); try self.writeSrc(stream, src); } diff --git a/src/type.zig b/src/type.zig index 349d755779..43a3636ba3 100644 --- a/src/type.zig +++ b/src/type.zig @@ -3123,6 +3123,7 @@ pub const Type = extern union { for (tuple.types) |field_ty, i| { const val = tuple.values[i]; if (val.tag() != .unreachable_value) continue; // comptime field + if (!(field_ty.hasRuntimeBits())) continue; switch (try field_ty.abiAlignmentAdvanced(target, strat)) { .scalar => |field_align| big_align = @max(big_align, field_align), diff --git a/src/value.zig b/src/value.zig index a607a3551e..c86e5ab12c 100644 --- a/src/value.zig +++ b/src/value.zig @@ -3259,8 +3259,7 @@ pub const Value = extern union { } pub const OverflowArithmeticResult = struct { - /// TODO: Rename to `overflow_bit` and make of type `u1`. - overflowed: Value, + overflow_bit: Value, wrapped_result: Value, }; @@ -3395,11 +3394,11 @@ pub const Value = extern union { const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf); const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf); const of_math_result = try intMulWithOverflowScalar(lhs_elem, rhs_elem, ty.scalarType(), arena, target); - overflowed_data[i] = of_math_result.overflowed; + overflowed_data[i] = of_math_result.overflow_bit; scalar.* = of_math_result.wrapped_result; } return OverflowArithmeticResult{ - .overflowed = try Value.Tag.aggregate.create(arena, overflowed_data), + .overflow_bit = try Value.Tag.aggregate.create(arena, overflowed_data), .wrapped_result = try Value.Tag.aggregate.create(arena, result_data), }; } @@ -3436,7 +3435,7 @@ pub const Value = extern union { } return OverflowArithmeticResult{ - .overflowed = makeBool(overflowed), + .overflow_bit = boolToInt(overflowed), .wrapped_result = try fromBigInt(arena, result_bigint.toConst()), }; } @@ -4141,11 +4140,11 @@ pub const Value = extern union { const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf); const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf); const of_math_result = try shlWithOverflowScalar(lhs_elem, rhs_elem, ty.scalarType(), allocator, target); - overflowed_data[i] = of_math_result.overflowed; + overflowed_data[i] = of_math_result.overflow_bit; scalar.* = of_math_result.wrapped_result; } return OverflowArithmeticResult{ - .overflowed = try Value.Tag.aggregate.create(allocator, overflowed_data), + .overflow_bit = try Value.Tag.aggregate.create(allocator, overflowed_data), .wrapped_result = try Value.Tag.aggregate.create(allocator, result_data), }; } @@ -4178,7 +4177,7 @@ pub const Value = extern union { result_bigint.truncate(result_bigint.toConst(), info.signedness, info.bits); } return OverflowArithmeticResult{ - .overflowed = makeBool(overflowed), + .overflow_bit = boolToInt(overflowed), .wrapped_result = try fromBigInt(allocator, result_bigint.toConst()), }; } @@ -5492,6 +5491,10 @@ pub const Value = extern union { return if (x) Value.true else Value.false; } + pub fn boolToInt(x: bool) Value { + return if (x) Value.one else Value.zero; + } + pub const RuntimeIndex = enum(u32) { zero = 0, comptime_field_ptr = std.math.maxInt(u32),