authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-12-21 14:33:02+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-12-27 15:13:14+02:00
log54160e7f6aecb4628df633ceaef4c6d956429a3d
tree8b523c4dad676be508f680fa8840fa3430a14191
parentaf9a9a13747b1e7007e29ff4f76e700f5bd7f7cf

Sema: make overflow arithmetic builtins return tuples


9 files changed, 104 insertions(+), 175 deletions(-)

src/AstGen.zig+4-24
...@@ -2505,7 +2505,6 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As...@@ -2505,7 +2505,6 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
2505 .err_union_code,2505 .err_union_code,
2506 .err_union_code_ptr,2506 .err_union_code_ptr,
2507 .ptr_type,2507 .ptr_type,
2508 .overflow_arithmetic_ptr,
2509 .enum_literal,2508 .enum_literal,
2510 .merge_error_sets,2509 .merge_error_sets,
2511 .error_union_type,2510 .error_union_type,
...@@ -2543,7 +2542,6 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As...@@ -2543,7 +2542,6 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
2543 .type_info,2542 .type_info,
2544 .size_of,2543 .size_of,
2545 .bit_size_of,2544 .bit_size_of,
2546 .log2_int_type,
2547 .typeof_log2_int_type,2545 .typeof_log2_int_type,
2548 .ptr_to_int,2546 .ptr_to_int,
2549 .align_of,2547 .align_of,
...@@ -8236,21 +8234,7 @@ fn builtinCall(...@@ -8236,21 +8234,7 @@ fn builtinCall(
8236 .add_with_overflow => return overflowArithmetic(gz, scope, ri, node, params, .add_with_overflow),8234 .add_with_overflow => return overflowArithmetic(gz, scope, ri, node, params, .add_with_overflow),
8237 .sub_with_overflow => return overflowArithmetic(gz, scope, ri, node, params, .sub_with_overflow),8235 .sub_with_overflow => return overflowArithmetic(gz, scope, ri, node, params, .sub_with_overflow),
8238 .mul_with_overflow => return overflowArithmetic(gz, scope, ri, node, params, .mul_with_overflow),8236 .mul_with_overflow => return overflowArithmetic(gz, scope, ri, node, params, .mul_with_overflow),
8239 .shl_with_overflow => {8237 .shl_with_overflow => return overflowArithmetic(gz, scope, ri, node, params, .shl_with_overflow),
8240 const int_type = try typeExpr(gz, scope, params[0]);
8241 const log2_int_type = try gz.addUnNode(.log2_int_type, int_type, params[0]);
8242 const ptr_type = try gz.addUnNode(.overflow_arithmetic_ptr, int_type, params[0]);
8243 const lhs = try expr(gz, scope, .{ .rl = .{ .ty = int_type } }, params[1]);
8244 const rhs = try expr(gz, scope, .{ .rl = .{ .ty = log2_int_type } }, params[2]);
8245 const ptr = try expr(gz, scope, .{ .rl = .{ .ty = ptr_type } }, params[3]);
8246 const result = try gz.addExtendedPayload(.shl_with_overflow, Zir.Inst.OverflowArithmetic{
8247 .node = gz.nodeIndexToRelative(node),
8248 .lhs = lhs,
8249 .rhs = rhs,
8250 .ptr = ptr,
8251 });
8252 return rvalue(gz, ri, result, node);
8253 },
82548238
8255 .atomic_load => {8239 .atomic_load => {
8256 const result = try gz.addPlNode(.atomic_load, node, Zir.Inst.AtomicLoad{8240 const result = try gz.addPlNode(.atomic_load, node, Zir.Inst.AtomicLoad{
...@@ -8691,16 +8675,12 @@ fn overflowArithmetic(...@@ -8691,16 +8675,12 @@ fn overflowArithmetic(
8691 params: []const Ast.Node.Index,8675 params: []const Ast.Node.Index,
8692 tag: Zir.Inst.Extended,8676 tag: Zir.Inst.Extended,
8693) InnerError!Zir.Inst.Ref {8677) InnerError!Zir.Inst.Ref {
8694 const int_type = try typeExpr(gz, scope, params[0]);8678 const lhs = try expr(gz, scope, .{ .rl = .none }, params[0]);
8695 const ptr_type = try gz.addUnNode(.overflow_arithmetic_ptr, int_type, params[0]);8679 const rhs = try expr(gz, scope, .{ .rl = .none }, params[1]);
8696 const lhs = try expr(gz, scope, .{ .rl = .{ .ty = int_type } }, params[1]);8680 const result = try gz.addExtendedPayload(tag, Zir.Inst.BinNode{
8697 const rhs = try expr(gz, scope, .{ .rl = .{ .ty = int_type } }, params[2]);
8698 const ptr = try expr(gz, scope, .{ .rl = .{ .ty = ptr_type } }, params[3]);
8699 const result = try gz.addExtendedPayload(tag, Zir.Inst.OverflowArithmetic{
8700 .node = gz.nodeIndexToRelative(node),8681 .node = gz.nodeIndexToRelative(node),
8701 .lhs = lhs,8682 .lhs = lhs,
8702 .rhs = rhs,8683 .rhs = rhs,
8703 .ptr = ptr,
8704 });8684 });
8705 return rvalue(gz, ri, result, node);8685 return rvalue(gz, ri, result, node);
8706}8686}
src/Autodoc.zig-20
...@@ -1510,26 +1510,6 @@ fn walkInstruction(...@@ -1510,26 +1510,6 @@ fn walkInstruction(
15101510
1511 // return operand;1511 // return operand;
1512 // },1512 // },
1513 .overflow_arithmetic_ptr => {
1514 const un_node = data[inst_index].un_node;
1515
1516 const elem_type_ref = try self.walkRef(file, parent_scope, parent_src, un_node.operand, false);
1517 const type_slot_index = self.types.items.len;
1518 try self.types.append(self.arena, .{
1519 .Pointer = .{
1520 .size = .One,
1521 .child = elem_type_ref.expr,
1522 .is_mutable = true,
1523 .is_volatile = false,
1524 .is_allowzero = false,
1525 },
1526 });
1527
1528 return DocData.WalkResult{
1529 .typeRef = .{ .type = @enumToInt(Ref.type_type) },
1530 .expr = .{ .type = type_slot_index },
1531 };
1532 },
1533 .ptr_type => {1513 .ptr_type => {
1534 const ptr = data[inst_index].ptr_type;1514 const ptr = data[inst_index].ptr_type;
1535 const extra = file.zir.extraData(Zir.Inst.PtrType, ptr.payload_index);1515 const extra = file.zir.extraData(Zir.Inst.PtrType, ptr.payload_index);
src/BuiltinFn.zig+4-4
...@@ -154,7 +154,7 @@ pub const list = list: {...@@ -154,7 +154,7 @@ pub const list = list: {
154 "@addWithOverflow",154 "@addWithOverflow",
155 .{155 .{
156 .tag = .add_with_overflow,156 .tag = .add_with_overflow,
157 .param_count = 4,157 .param_count = 2,
158 },158 },
159 },159 },
160 .{160 .{
...@@ -636,7 +636,7 @@ pub const list = list: {...@@ -636,7 +636,7 @@ pub const list = list: {
636 "@mulWithOverflow",636 "@mulWithOverflow",
637 .{637 .{
638 .tag = .mul_with_overflow,638 .tag = .mul_with_overflow,
639 .param_count = 4,639 .param_count = 2,
640 },640 },
641 },641 },
642 .{642 .{
...@@ -741,7 +741,7 @@ pub const list = list: {...@@ -741,7 +741,7 @@ pub const list = list: {
741 "@shlWithOverflow",741 "@shlWithOverflow",
742 .{742 .{
743 .tag = .shl_with_overflow,743 .tag = .shl_with_overflow,
744 .param_count = 4,744 .param_count = 2,
745 },745 },
746 },746 },
747 .{747 .{
...@@ -889,7 +889,7 @@ pub const list = list: {...@@ -889,7 +889,7 @@ pub const list = list: {
889 "@subWithOverflow",889 "@subWithOverflow",
890 .{890 .{
891 .tag = .sub_with_overflow,891 .tag = .sub_with_overflow,
892 .param_count = 4,892 .param_count = 2,
893 },893 },
894 },894 },
895 .{895 .{
src/Sema.zig+78-88
...@@ -971,7 +971,6 @@ fn analyzeBodyInner(...@@ -971,7 +971,6 @@ fn analyzeBodyInner(
971 .optional_payload_unsafe_ptr => try sema.zirOptionalPayloadPtr(block, inst, false),971 .optional_payload_unsafe_ptr => try sema.zirOptionalPayloadPtr(block, inst, false),
972 .optional_type => try sema.zirOptionalType(block, inst),972 .optional_type => try sema.zirOptionalType(block, inst),
973 .ptr_type => try sema.zirPtrType(block, inst),973 .ptr_type => try sema.zirPtrType(block, inst),
974 .overflow_arithmetic_ptr => try sema.zirOverflowArithmeticPtr(block, inst),
975 .ref => try sema.zirRef(block, inst),974 .ref => try sema.zirRef(block, inst),
976 .ret_err_value_code => try sema.zirRetErrValueCode(inst),975 .ret_err_value_code => try sema.zirRetErrValueCode(inst),
977 .shr => try sema.zirShr(block, inst, .shr),976 .shr => try sema.zirShr(block, inst, .shr),
...@@ -993,7 +992,6 @@ fn analyzeBodyInner(...@@ -993,7 +992,6 @@ fn analyzeBodyInner(
993 .bit_size_of => try sema.zirBitSizeOf(block, inst),992 .bit_size_of => try sema.zirBitSizeOf(block, inst),
994 .typeof => try sema.zirTypeof(block, inst),993 .typeof => try sema.zirTypeof(block, inst),
995 .typeof_builtin => try sema.zirTypeofBuiltin(block, inst),994 .typeof_builtin => try sema.zirTypeofBuiltin(block, inst),
996 .log2_int_type => try sema.zirLog2IntType(block, inst),
997 .typeof_log2_int_type => try sema.zirTypeofLog2IntType(block, inst),995 .typeof_log2_int_type => try sema.zirTypeofLog2IntType(block, inst),
998 .xor => try sema.zirBitwise(block, inst, .xor),996 .xor => try sema.zirBitwise(block, inst, .xor),
999 .struct_init_empty => try sema.zirStructInitEmpty(block, inst),997 .struct_init_empty => try sema.zirStructInitEmpty(block, inst),
...@@ -11762,7 +11760,7 @@ fn zirShl(...@@ -11762,7 +11760,7 @@ fn zirShl(
11762 if (scalar_ty.zigTypeTag() == .ComptimeInt) {11760 if (scalar_ty.zigTypeTag() == .ComptimeInt) {
11763 break :val shifted.wrapped_result;11761 break :val shifted.wrapped_result;
11764 }11762 }
11765 if (shifted.overflowed.compareAllWithZero(.eq)) {11763 if (shifted.overflow_bit.compareAllWithZero(.eq)) {
11766 break :val shifted.wrapped_result;11764 break :val shifted.wrapped_result;
11767 }11765 }
11768 return sema.fail(block, src, "operation caused overflow", .{});11766 return sema.fail(block, src, "operation caused overflow", .{});
...@@ -13783,24 +13781,37 @@ fn zirOverflowArithmetic(...@@ -13783,24 +13781,37 @@ fn zirOverflowArithmetic(
13783 const tracy = trace(@src());13781 const tracy = trace(@src());
13784 defer tracy.end();13782 defer tracy.end();
1378513783
13786 const extra = sema.code.extraData(Zir.Inst.OverflowArithmetic, extended.operand).data;13784 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
13787 const src = LazySrcLoc.nodeOffset(extra.node);13785 const src = LazySrcLoc.nodeOffset(extra.node);
1378813786
13789 const lhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };13787 const lhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
13790 const rhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };13788 const rhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };
13791 const ptr_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = extra.node };
1379213789
13793 const lhs = try sema.resolveInst(extra.lhs);13790 const uncasted_lhs = try sema.resolveInst(extra.lhs);
13794 const rhs = try sema.resolveInst(extra.rhs);13791 const uncasted_rhs = try sema.resolveInst(extra.rhs);
13795 const ptr = try sema.resolveInst(extra.ptr);
1379613792
13797 const lhs_ty = sema.typeOf(lhs);13793 const lhs_ty = sema.typeOf(uncasted_lhs);
13798 const rhs_ty = sema.typeOf(rhs);13794 const rhs_ty = sema.typeOf(uncasted_rhs);
13799 const mod = sema.mod;13795 const mod = sema.mod;
1380013796
13801 // Note, the types of lhs/rhs (also for shifting)/ptr are already correct as ensured by astgen.
13802 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);13797 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
13803 const dest_ty = lhs_ty;13798
13799 const instructions = &[_]Air.Inst.Ref{ uncasted_lhs, uncasted_rhs };
13800 const dest_ty = if (zir_tag == .shl_with_overflow)
13801 lhs_ty
13802 else
13803 try sema.resolvePeerTypes(block, src, instructions, .{
13804 .override = &[_]LazySrcLoc{ lhs_src, rhs_src },
13805 });
13806
13807 const rhs_dest_ty = if (zir_tag == .shl_with_overflow)
13808 try sema.log2IntType(block, lhs_ty, src)
13809 else
13810 dest_ty;
13811
13812 const lhs = try sema.coerce(block, dest_ty, uncasted_lhs, lhs_src);
13813 const rhs = try sema.coerce(block, rhs_dest_ty, uncasted_rhs, rhs_src);
13814
13804 if (dest_ty.scalarType().zigTypeTag() != .Int) {13815 if (dest_ty.scalarType().zigTypeTag() != .Int) {
13805 return sema.fail(block, src, "expected vector of integers or integer tag type, found '{}'", .{dest_ty.fmt(mod)});13816 return sema.fail(block, src, "expected vector of integers or integer tag type, found '{}'", .{dest_ty.fmt(mod)});
13806 }13817 }
...@@ -13809,14 +13820,11 @@ fn zirOverflowArithmetic(...@@ -13809,14 +13820,11 @@ fn zirOverflowArithmetic(
13809 const maybe_rhs_val = try sema.resolveMaybeUndefVal(rhs);13820 const maybe_rhs_val = try sema.resolveMaybeUndefVal(rhs);
1381013821
13811 const tuple_ty = try sema.overflowArithmeticTupleType(dest_ty);13822 const tuple_ty = try sema.overflowArithmeticTupleType(dest_ty);
13812 // TODO: Remove and use `ov_ty` instead.13823
13813 // This is a temporary type used until overflow arithmetic properly returns `u1` instead of `bool`.13824 var result: struct {
13814 const overflowed_ty = if (dest_ty.zigTypeTag() == .Vector) try Type.vector(sema.arena, dest_ty.vectorLen(), Type.bool) else Type.bool;13825 inst: Air.Inst.Ref = .none,
1381513826 wrapped: Value = Value.initTag(.unreachable_value),
13816 const result: struct {13827 overflow_bit: Value,
13817 /// TODO: Rename to `overflow_bit` and make of type `u1`.
13818 overflowed: Air.Inst.Ref,
13819 wrapped: Air.Inst.Ref,
13820 } = result: {13828 } = result: {
13821 switch (zir_tag) {13829 switch (zir_tag) {
13822 .add_with_overflow => {13830 .add_with_overflow => {
...@@ -13825,24 +13833,22 @@ fn zirOverflowArithmetic(...@@ -13825,24 +13833,22 @@ fn zirOverflowArithmetic(
13825 // Otherwise, if either of the argument is undefined, undefined is returned.13833 // Otherwise, if either of the argument is undefined, undefined is returned.
13826 if (maybe_lhs_val) |lhs_val| {13834 if (maybe_lhs_val) |lhs_val| {
13827 if (!lhs_val.isUndef() and (try lhs_val.compareAllWithZeroAdvanced(.eq, sema))) {13835 if (!lhs_val.isUndef() and (try lhs_val.compareAllWithZeroAdvanced(.eq, sema))) {
13828 break :result .{ .overflowed = try sema.addBool(overflowed_ty, false), .wrapped = rhs };13836 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, Value.zero), .inst = rhs };
13829 }13837 }
13830 }13838 }
13831 if (maybe_rhs_val) |rhs_val| {13839 if (maybe_rhs_val) |rhs_val| {
13832 if (!rhs_val.isUndef() and (try rhs_val.compareAllWithZeroAdvanced(.eq, sema))) {13840 if (!rhs_val.isUndef() and (try rhs_val.compareAllWithZeroAdvanced(.eq, sema))) {
13833 break :result .{ .overflowed = try sema.addBool(overflowed_ty, false), .wrapped = lhs };13841 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, Value.zero), .inst = lhs };
13834 }13842 }
13835 }13843 }
13836 if (maybe_lhs_val) |lhs_val| {13844 if (maybe_lhs_val) |lhs_val| {
13837 if (maybe_rhs_val) |rhs_val| {13845 if (maybe_rhs_val) |rhs_val| {
13838 if (lhs_val.isUndef() or rhs_val.isUndef()) {13846 if (lhs_val.isUndef() or rhs_val.isUndef()) {
13839 break :result .{ .overflowed = try sema.addConstUndef(overflowed_ty), .wrapped = try sema.addConstUndef(dest_ty) };13847 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };
13840 }13848 }
1384113849
13842 const result = try sema.intAddWithOverflow(lhs_val, rhs_val, dest_ty);13850 const result = try sema.intAddWithOverflow(lhs_val, rhs_val, dest_ty);
13843 const overflowed = try sema.addConstant(overflowed_ty, result.overflowed);13851 break :result .{ .overflow_bit = result.overflow_bit, .wrapped = result.wrapped_result };
13844 const wrapped = try sema.addConstant(dest_ty, result.wrapped_result);
13845 break :result .{ .overflowed = overflowed, .wrapped = wrapped };
13846 }13852 }
13847 }13853 }
13848 },13854 },
...@@ -13851,18 +13857,16 @@ fn zirOverflowArithmetic(...@@ -13851,18 +13857,16 @@ fn zirOverflowArithmetic(
13851 // Otherwise, if either result is undefined, both results are undefined.13857 // Otherwise, if either result is undefined, both results are undefined.
13852 if (maybe_rhs_val) |rhs_val| {13858 if (maybe_rhs_val) |rhs_val| {
13853 if (rhs_val.isUndef()) {13859 if (rhs_val.isUndef()) {
13854 break :result .{ .overflowed = try sema.addConstUndef(overflowed_ty), .wrapped = try sema.addConstUndef(dest_ty) };13860 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };
13855 } else if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {13861 } else if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
13856 break :result .{ .overflowed = try sema.addBool(overflowed_ty, false), .wrapped = lhs };13862 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, Value.zero), .inst = lhs };
13857 } else if (maybe_lhs_val) |lhs_val| {13863 } else if (maybe_lhs_val) |lhs_val| {
13858 if (lhs_val.isUndef()) {13864 if (lhs_val.isUndef()) {
13859 break :result .{ .overflowed = try sema.addConstUndef(overflowed_ty), .wrapped = try sema.addConstUndef(dest_ty) };13865 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };
13860 }13866 }
1386113867
13862 const result = try sema.intSubWithOverflow(lhs_val, rhs_val, dest_ty);13868 const result = try sema.intSubWithOverflow(lhs_val, rhs_val, dest_ty);
13863 const overflowed = try sema.addConstant(overflowed_ty, result.overflowed);13869 break :result .{ .overflow_bit = result.overflow_bit, .wrapped = result.wrapped_result };
13864 const wrapped = try sema.addConstant(dest_ty, result.wrapped_result);
13865 break :result .{ .overflowed = overflowed, .wrapped = wrapped };
13866 }13870 }
13867 }13871 }
13868 },13872 },
...@@ -13873,9 +13877,9 @@ fn zirOverflowArithmetic(...@@ -13873,9 +13877,9 @@ fn zirOverflowArithmetic(
13873 if (maybe_lhs_val) |lhs_val| {13877 if (maybe_lhs_val) |lhs_val| {
13874 if (!lhs_val.isUndef()) {13878 if (!lhs_val.isUndef()) {
13875 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {13879 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
13876 break :result .{ .overflowed = try sema.addBool(overflowed_ty, false), .wrapped = lhs };13880 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, Value.zero), .inst = lhs };
13877 } else if (try sema.compareAll(lhs_val, .eq, Value.one, dest_ty)) {13881 } else if (try sema.compareAll(lhs_val, .eq, try maybeRepeated(sema, dest_ty, Value.one), dest_ty)) {
13878 break :result .{ .overflowed = try sema.addBool(overflowed_ty, false), .wrapped = rhs };13882 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, Value.zero), .inst = rhs };
13879 }13883 }
13880 }13884 }
13881 }13885 }
...@@ -13883,9 +13887,9 @@ fn zirOverflowArithmetic(...@@ -13883,9 +13887,9 @@ fn zirOverflowArithmetic(
13883 if (maybe_rhs_val) |rhs_val| {13887 if (maybe_rhs_val) |rhs_val| {
13884 if (!rhs_val.isUndef()) {13888 if (!rhs_val.isUndef()) {
13885 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {13889 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
13886 break :result .{ .overflowed = try sema.addBool(overflowed_ty, false), .wrapped = rhs };13890 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, Value.zero), .inst = rhs };
13887 } else if (try sema.compareAll(rhs_val, .eq, Value.one, dest_ty)) {13891 } else if (try sema.compareAll(rhs_val, .eq, try maybeRepeated(sema, dest_ty, Value.one), dest_ty)) {
13888 break :result .{ .overflowed = try sema.addBool(overflowed_ty, false), .wrapped = lhs };13892 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, Value.zero), .inst = lhs };
13889 }13893 }
13890 }13894 }
13891 }13895 }
...@@ -13893,13 +13897,11 @@ fn zirOverflowArithmetic(...@@ -13893,13 +13897,11 @@ fn zirOverflowArithmetic(
13893 if (maybe_lhs_val) |lhs_val| {13897 if (maybe_lhs_val) |lhs_val| {
13894 if (maybe_rhs_val) |rhs_val| {13898 if (maybe_rhs_val) |rhs_val| {
13895 if (lhs_val.isUndef() or rhs_val.isUndef()) {13899 if (lhs_val.isUndef() or rhs_val.isUndef()) {
13896 break :result .{ .overflowed = try sema.addConstUndef(overflowed_ty), .wrapped = try sema.addConstUndef(dest_ty) };13900 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };
13897 }13901 }
1389813902
13899 const result = try lhs_val.intMulWithOverflow(rhs_val, dest_ty, sema.arena, mod);13903 const result = try lhs_val.intMulWithOverflow(rhs_val, dest_ty, sema.arena, mod);
13900 const overflowed = try sema.addConstant(overflowed_ty, result.overflowed);13904 break :result .{ .overflow_bit = result.overflow_bit, .wrapped = result.wrapped_result };
13901 const wrapped = try sema.addConstant(dest_ty, result.wrapped_result);
13902 break :result .{ .overflowed = overflowed, .wrapped = wrapped };
13903 }13905 }
13904 }13906 }
13905 },13907 },
...@@ -13909,24 +13911,22 @@ fn zirOverflowArithmetic(...@@ -13909,24 +13911,22 @@ fn zirOverflowArithmetic(
13909 // Oterhwise if either of the arguments is undefined, both results are undefined.13911 // Oterhwise if either of the arguments is undefined, both results are undefined.
13910 if (maybe_lhs_val) |lhs_val| {13912 if (maybe_lhs_val) |lhs_val| {
13911 if (!lhs_val.isUndef() and (try lhs_val.compareAllWithZeroAdvanced(.eq, sema))) {13913 if (!lhs_val.isUndef() and (try lhs_val.compareAllWithZeroAdvanced(.eq, sema))) {
13912 break :result .{ .overflowed = try sema.addBool(overflowed_ty, false), .wrapped = lhs };13914 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, Value.zero), .inst = lhs };
13913 }13915 }
13914 }13916 }
13915 if (maybe_rhs_val) |rhs_val| {13917 if (maybe_rhs_val) |rhs_val| {
13916 if (!rhs_val.isUndef() and (try rhs_val.compareAllWithZeroAdvanced(.eq, sema))) {13918 if (!rhs_val.isUndef() and (try rhs_val.compareAllWithZeroAdvanced(.eq, sema))) {
13917 break :result .{ .overflowed = try sema.addBool(overflowed_ty, false), .wrapped = lhs };13919 break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, Value.zero), .inst = lhs };
13918 }13920 }
13919 }13921 }
13920 if (maybe_lhs_val) |lhs_val| {13922 if (maybe_lhs_val) |lhs_val| {
13921 if (maybe_rhs_val) |rhs_val| {13923 if (maybe_rhs_val) |rhs_val| {
13922 if (lhs_val.isUndef() or rhs_val.isUndef()) {13924 if (lhs_val.isUndef() or rhs_val.isUndef()) {
13923 break :result .{ .overflowed = try sema.addConstUndef(overflowed_ty), .wrapped = try sema.addConstUndef(dest_ty) };13925 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };
13924 }13926 }
1392513927
13926 const result = try lhs_val.shlWithOverflow(rhs_val, dest_ty, sema.arena, sema.mod);13928 const result = try lhs_val.shlWithOverflow(rhs_val, dest_ty, sema.arena, sema.mod);
13927 const overflowed = try sema.addConstant(overflowed_ty, result.overflowed);13929 break :result .{ .overflow_bit = result.overflow_bit, .wrapped = result.wrapped_result };
13928 const wrapped = try sema.addConstant(dest_ty, result.wrapped_result);
13929 break :result .{ .overflowed = overflowed, .wrapped = wrapped };
13930 }13930 }
13931 }13931 }
13932 },13932 },
...@@ -13944,7 +13944,7 @@ fn zirOverflowArithmetic(...@@ -13944,7 +13944,7 @@ fn zirOverflowArithmetic(
13944 const runtime_src = if (maybe_lhs_val == null) lhs_src else rhs_src;13944 const runtime_src = if (maybe_lhs_val == null) lhs_src else rhs_src;
13945 try sema.requireRuntimeBlock(block, src, runtime_src);13945 try sema.requireRuntimeBlock(block, src, runtime_src);
1394613946
13947 const tuple = try block.addInst(.{13947 return block.addInst(.{
13948 .tag = air_tag,13948 .tag = air_tag,
13949 .data = .{ .ty_pl = .{13949 .data = .{ .ty_pl = .{
13950 .ty = try block.sema.addType(tuple_ty),13950 .ty = try block.sema.addType(tuple_ty),
...@@ -13954,16 +13954,32 @@ fn zirOverflowArithmetic(...@@ -13954,16 +13954,32 @@ fn zirOverflowArithmetic(
13954 }),13954 }),
13955 } },13955 } },
13956 });13956 });
13957 };
1395713958
13958 const wrapped = try sema.tupleFieldValByIndex(block, src, tuple, 0, tuple_ty);13959 if (result.inst != .none) {
13959 try sema.storePtr2(block, src, ptr, ptr_src, wrapped, src, .store);13960 if (try sema.resolveMaybeUndefVal(result.inst)) |some| {
13961 result.wrapped = some;
13962 result.inst = .none;
13963 }
13964 }
1396013965
13961 const overflow_bit = try sema.tupleFieldValByIndex(block, src, tuple, 1, tuple_ty);13966 if (result.inst == .none) {
13962 return block.addBitCast(overflowed_ty, overflow_bit);13967 const values = try sema.arena.alloc(Value, 2);
13963 };13968 values[0] = result.wrapped;
13969 values[1] = result.overflow_bit;
13970 const tuple_val = try Value.Tag.aggregate.create(sema.arena, values);
13971 return sema.addConstant(tuple_ty, tuple_val);
13972 }
13973
13974 const element_refs = try sema.arena.alloc(Air.Inst.Ref, 2);
13975 element_refs[0] = result.inst;
13976 element_refs[1] = try sema.addConstant(tuple_ty.structFieldType(1), result.overflow_bit);
13977 return block.addAggregateInit(tuple_ty, element_refs);
13978}
1396413979
13965 try sema.storePtr2(block, src, ptr, ptr_src, result.wrapped, src, .store);13980fn maybeRepeated(sema: *Sema, ty: Type, val: Value) !Value {
13966 return result.overflowed;13981 if (ty.zigTypeTag() != .Vector) return val;
13982 return Value.Tag.repeated.create(sema.arena, val);
13967}13983}
1396813984
13969fn overflowArithmeticTupleType(sema: *Sema, ty: Type) !Type {13985fn overflowArithmeticTupleType(sema: *Sema, ty: Type) !Type {
...@@ -16211,14 +16227,6 @@ fn zirTypeofLog2IntType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil...@@ -16211,14 +16227,6 @@ fn zirTypeofLog2IntType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
16211 return sema.addType(res_ty);16227 return sema.addType(res_ty);
16212}16228}
1621316229
16214fn zirLog2IntType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
16215 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
16216 const src = inst_data.src();
16217 const operand = try sema.resolveType(block, src, inst_data.operand);
16218 const res_ty = try sema.log2IntType(block, operand, src);
16219 return sema.addType(res_ty);
16220}
16221
16222fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) CompileError!Type {16230fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) CompileError!Type {
16223 switch (operand.zigTypeTag()) {16231 switch (operand.zigTypeTag()) {
16224 .ComptimeInt => return Type.comptime_int,16232 .ComptimeInt => return Type.comptime_int,
...@@ -17039,24 +17047,6 @@ fn floatOpAllowed(tag: Zir.Inst.Tag) bool {...@@ -17039,24 +17047,6 @@ fn floatOpAllowed(tag: Zir.Inst.Tag) bool {
17039 };17047 };
17040}17048}
1704117049
17042fn zirOverflowArithmeticPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
17043 const tracy = trace(@src());
17044 defer tracy.end();
17045
17046 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
17047 const elem_ty_src = inst_data.src();
17048 const elem_type = try sema.resolveType(block, elem_ty_src, inst_data.operand);
17049 const ty = try Type.ptr(sema.arena, sema.mod, .{
17050 .pointee_type = elem_type,
17051 .@"addrspace" = .generic,
17052 .mutable = true,
17053 .@"allowzero" = false,
17054 .@"volatile" = false,
17055 .size = .One,
17056 });
17057 return sema.addType(ty);
17058}
17059
17060fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {17050fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
17061 const tracy = trace(@src());17051 const tracy = trace(@src());
17062 defer tracy.end();17052 defer tracy.end();
...@@ -32613,11 +32603,11 @@ fn intSubWithOverflow(...@@ -32613,11 +32603,11 @@ fn intSubWithOverflow(
32613 const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf);32603 const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf);
32614 const rhs_elem = rhs.elemValueBuffer(sema.mod, i, &rhs_buf);32604 const rhs_elem = rhs.elemValueBuffer(sema.mod, i, &rhs_buf);
32615 const of_math_result = try sema.intSubWithOverflowScalar(lhs_elem, rhs_elem, ty.scalarType());32605 const of_math_result = try sema.intSubWithOverflowScalar(lhs_elem, rhs_elem, ty.scalarType());
32616 overflowed_data[i] = of_math_result.overflowed;32606 overflowed_data[i] = of_math_result.overflow_bit;
32617 scalar.* = of_math_result.wrapped_result;32607 scalar.* = of_math_result.wrapped_result;
32618 }32608 }
32619 return Value.OverflowArithmeticResult{32609 return Value.OverflowArithmeticResult{
32620 .overflowed = try Value.Tag.aggregate.create(sema.arena, overflowed_data),32610 .overflow_bit = try Value.Tag.aggregate.create(sema.arena, overflowed_data),
32621 .wrapped_result = try Value.Tag.aggregate.create(sema.arena, result_data),32611 .wrapped_result = try Value.Tag.aggregate.create(sema.arena, result_data),
32622 };32612 };
32623 }32613 }
...@@ -32645,7 +32635,7 @@ fn intSubWithOverflowScalar(...@@ -32645,7 +32635,7 @@ fn intSubWithOverflowScalar(
32645 const overflowed = result_bigint.subWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits);32635 const overflowed = result_bigint.subWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits);
32646 const wrapped_result = try Value.fromBigInt(sema.arena, result_bigint.toConst());32636 const wrapped_result = try Value.fromBigInt(sema.arena, result_bigint.toConst());
32647 return Value.OverflowArithmeticResult{32637 return Value.OverflowArithmeticResult{
32648 .overflowed = Value.makeBool(overflowed),32638 .overflow_bit = Value.boolToInt(overflowed),
32649 .wrapped_result = wrapped_result,32639 .wrapped_result = wrapped_result,
32650 };32640 };
32651}32641}
...@@ -32964,11 +32954,11 @@ fn intAddWithOverflow(...@@ -32964,11 +32954,11 @@ fn intAddWithOverflow(
32964 const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf);32954 const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf);
32965 const rhs_elem = rhs.elemValueBuffer(sema.mod, i, &rhs_buf);32955 const rhs_elem = rhs.elemValueBuffer(sema.mod, i, &rhs_buf);
32966 const of_math_result = try sema.intAddWithOverflowScalar(lhs_elem, rhs_elem, ty.scalarType());32956 const of_math_result = try sema.intAddWithOverflowScalar(lhs_elem, rhs_elem, ty.scalarType());
32967 overflowed_data[i] = of_math_result.overflowed;32957 overflowed_data[i] = of_math_result.overflow_bit;
32968 scalar.* = of_math_result.wrapped_result;32958 scalar.* = of_math_result.wrapped_result;
32969 }32959 }
32970 return Value.OverflowArithmeticResult{32960 return Value.OverflowArithmeticResult{
32971 .overflowed = try Value.Tag.aggregate.create(sema.arena, overflowed_data),32961 .overflow_bit = try Value.Tag.aggregate.create(sema.arena, overflowed_data),
32972 .wrapped_result = try Value.Tag.aggregate.create(sema.arena, result_data),32962 .wrapped_result = try Value.Tag.aggregate.create(sema.arena, result_data),
32973 };32963 };
32974 }32964 }
...@@ -32996,7 +32986,7 @@ fn intAddWithOverflowScalar(...@@ -32996,7 +32986,7 @@ fn intAddWithOverflowScalar(
32996 const overflowed = result_bigint.addWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits);32986 const overflowed = result_bigint.addWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits);
32997 const result = try Value.fromBigInt(sema.arena, result_bigint.toConst());32987 const result = try Value.fromBigInt(sema.arena, result_bigint.toConst());
32998 return Value.OverflowArithmeticResult{32988 return Value.OverflowArithmeticResult{
32999 .overflowed = Value.makeBool(overflowed),32989 .overflow_bit = Value.boolToInt(overflowed),
33000 .wrapped_result = result,32990 .wrapped_result = result,
33001 };32991 };
33002}32992}
src/TypedValue.zig+1-3
...@@ -225,9 +225,7 @@ pub fn print(...@@ -225,9 +225,7 @@ pub fn print(
225 .one => return writer.writeAll("1"),225 .one => return writer.writeAll("1"),
226 .void_value => return writer.writeAll("{}"),226 .void_value => return writer.writeAll("{}"),
227 .unreachable_value => return writer.writeAll("unreachable"),227 .unreachable_value => return writer.writeAll("unreachable"),
228 .the_only_possible_value => {228 .the_only_possible_value => return writer.writeAll("0"),
229 val = ty.onePossibleValue().?;
230 },
231 .bool_true => return writer.writeAll("true"),229 .bool_true => return writer.writeAll("true"),
232 .bool_false => return writer.writeAll("false"),230 .bool_false => return writer.writeAll("false"),
233 .ty => return val.castTag(.ty).?.data.print(writer, mod),231 .ty => return val.castTag(.ty).?.data.print(writer, mod),
src/Zir.zig+4-23
...@@ -539,9 +539,6 @@ pub const Inst = struct {...@@ -539,9 +539,6 @@ pub const Inst = struct {
539 /// Obtains the return type of the in-scope function.539 /// Obtains the return type of the in-scope function.
540 /// Uses the `node` union field.540 /// Uses the `node` union field.
541 ret_type,541 ret_type,
542 /// Create a pointer type for overflow arithmetic.
543 /// TODO remove when doing https://github.com/ziglang/zig/issues/10248
544 overflow_arithmetic_ptr,
545 /// Create a pointer type which can have a sentinel, alignment, address space, and/or bit range.542 /// Create a pointer type which can have a sentinel, alignment, address space, and/or bit range.
546 /// Uses the `ptr_type` union field.543 /// Uses the `ptr_type` union field.
547 ptr_type,544 ptr_type,
...@@ -600,9 +597,6 @@ pub const Inst = struct {...@@ -600,9 +597,6 @@ pub const Inst = struct {
600 /// Returns the integer type for the RHS of a shift operation.597 /// Returns the integer type for the RHS of a shift operation.
601 /// Uses the `un_node` field.598 /// Uses the `un_node` field.
602 typeof_log2_int_type,599 typeof_log2_int_type,
603 /// Given an integer type, returns the integer type for the RHS of a shift operation.
604 /// Uses the `un_node` field.
605 log2_int_type,
606 /// Asserts control-flow will not reach this instruction (`unreachable`).600 /// Asserts control-flow will not reach this instruction (`unreachable`).
607 /// Uses the `unreachable` union field.601 /// Uses the `unreachable` union field.
608 @"unreachable",602 @"unreachable",
...@@ -1121,7 +1115,6 @@ pub const Inst = struct {...@@ -1121,7 +1115,6 @@ pub const Inst = struct {
1121 .err_union_code,1115 .err_union_code,
1122 .err_union_code_ptr,1116 .err_union_code_ptr,
1123 .ptr_type,1117 .ptr_type,
1124 .overflow_arithmetic_ptr,
1125 .enum_literal,1118 .enum_literal,
1126 .merge_error_sets,1119 .merge_error_sets,
1127 .error_union_type,1120 .error_union_type,
...@@ -1132,7 +1125,6 @@ pub const Inst = struct {...@@ -1132,7 +1125,6 @@ pub const Inst = struct {
1132 .slice_sentinel,1125 .slice_sentinel,
1133 .import,1126 .import,
1134 .typeof_log2_int_type,1127 .typeof_log2_int_type,
1135 .log2_int_type,
1136 .resolve_inferred_alloc,1128 .resolve_inferred_alloc,
1137 .set_eval_branch_quota,1129 .set_eval_branch_quota,
1138 .switch_capture,1130 .switch_capture,
...@@ -1422,7 +1414,6 @@ pub const Inst = struct {...@@ -1422,7 +1414,6 @@ pub const Inst = struct {
1422 .err_union_code,1414 .err_union_code,
1423 .err_union_code_ptr,1415 .err_union_code_ptr,
1424 .ptr_type,1416 .ptr_type,
1425 .overflow_arithmetic_ptr,
1426 .enum_literal,1417 .enum_literal,
1427 .merge_error_sets,1418 .merge_error_sets,
1428 .error_union_type,1419 .error_union_type,
...@@ -1433,7 +1424,6 @@ pub const Inst = struct {...@@ -1433,7 +1424,6 @@ pub const Inst = struct {
1433 .slice_sentinel,1424 .slice_sentinel,
1434 .import,1425 .import,
1435 .typeof_log2_int_type,1426 .typeof_log2_int_type,
1436 .log2_int_type,
1437 .switch_capture,1427 .switch_capture,
1438 .switch_capture_ref,1428 .switch_capture_ref,
1439 .switch_capture_multi,1429 .switch_capture_multi,
...@@ -1664,7 +1654,6 @@ pub const Inst = struct {...@@ -1664,7 +1654,6 @@ pub const Inst = struct {
1664 .ret_err_value_code = .str_tok,1654 .ret_err_value_code = .str_tok,
1665 .ret_ptr = .node,1655 .ret_ptr = .node,
1666 .ret_type = .node,1656 .ret_type = .node,
1667 .overflow_arithmetic_ptr = .un_node,
1668 .ptr_type = .ptr_type,1657 .ptr_type = .ptr_type,
1669 .slice_start = .pl_node,1658 .slice_start = .pl_node,
1670 .slice_end = .pl_node,1659 .slice_end = .pl_node,
...@@ -1678,7 +1667,6 @@ pub const Inst = struct {...@@ -1678,7 +1667,6 @@ pub const Inst = struct {
1678 .negate_wrap = .un_node,1667 .negate_wrap = .un_node,
1679 .typeof = .un_node,1668 .typeof = .un_node,
1680 .typeof_log2_int_type = .un_node,1669 .typeof_log2_int_type = .un_node,
1681 .log2_int_type = .un_node,
1682 .@"unreachable" = .@"unreachable",1670 .@"unreachable" = .@"unreachable",
1683 .xor = .pl_node,1671 .xor = .pl_node,
1684 .optional_type = .un_node,1672 .optional_type = .un_node,
...@@ -1916,19 +1904,19 @@ pub const Inst = struct {...@@ -1916,19 +1904,19 @@ pub const Inst = struct {
1916 /// The AST node is the builtin call.1904 /// The AST node is the builtin call.
1917 typeof_peer,1905 typeof_peer,
1918 /// Implements the `@addWithOverflow` builtin.1906 /// Implements the `@addWithOverflow` builtin.
1919 /// `operand` is payload index to `OverflowArithmetic`.1907 /// `operand` is payload index to `BinNode`.
1920 /// `small` is unused.1908 /// `small` is unused.
1921 add_with_overflow,1909 add_with_overflow,
1922 /// Implements the `@subWithOverflow` builtin.1910 /// Implements the `@subWithOverflow` builtin.
1923 /// `operand` is payload index to `OverflowArithmetic`.1911 /// `operand` is payload index to `BinNode`.
1924 /// `small` is unused.1912 /// `small` is unused.
1925 sub_with_overflow,1913 sub_with_overflow,
1926 /// Implements the `@mulWithOverflow` builtin.1914 /// Implements the `@mulWithOverflow` builtin.
1927 /// `operand` is payload index to `OverflowArithmetic`.1915 /// `operand` is payload index to `BinNode`.
1928 /// `small` is unused.1916 /// `small` is unused.
1929 mul_with_overflow,1917 mul_with_overflow,
1930 /// Implements the `@shlWithOverflow` builtin.1918 /// Implements the `@shlWithOverflow` builtin.
1931 /// `operand` is payload index to `OverflowArithmetic`.1919 /// `operand` is payload index to `BinNode`.
1932 /// `small` is unused.1920 /// `small` is unused.
1933 shl_with_overflow,1921 shl_with_overflow,
1934 /// `operand` is payload index to `UnNode`.1922 /// `operand` is payload index to `UnNode`.
...@@ -3430,13 +3418,6 @@ pub const Inst = struct {...@@ -3430,13 +3418,6 @@ pub const Inst = struct {
3430 field_name: Ref,3418 field_name: Ref,
3431 };3419 };
34323420
3433 pub const OverflowArithmetic = struct {
3434 node: i32,
3435 lhs: Ref,
3436 rhs: Ref,
3437 ptr: Ref,
3438 };
3439
3440 pub const Cmpxchg = struct {3421 pub const Cmpxchg = struct {
3441 node: i32,3422 node: i32,
3442 ptr: Ref,3423 ptr: Ref,
src/print_zir.zig+1-5
...@@ -185,7 +185,6 @@ const Writer = struct {...@@ -185,7 +185,6 @@ const Writer = struct {
185 .size_of,185 .size_of,
186 .bit_size_of,186 .bit_size_of,
187 .typeof_log2_int_type,187 .typeof_log2_int_type,
188 .log2_int_type,
189 .ptr_to_int,188 .ptr_to_int,
190 .compile_error,189 .compile_error,
191 .set_eval_branch_quota,190 .set_eval_branch_quota,
...@@ -230,7 +229,6 @@ const Writer = struct {...@@ -230,7 +229,6 @@ const Writer = struct {
230 .validate_struct_init_ty,229 .validate_struct_init_ty,
231 .make_ptr_const,230 .make_ptr_const,
232 .validate_deref,231 .validate_deref,
233 .overflow_arithmetic_ptr,
234 .check_comptime_control_flow,232 .check_comptime_control_flow,
235 => try self.writeUnNode(stream, inst),233 => try self.writeUnNode(stream, inst),
236234
...@@ -1153,14 +1151,12 @@ const Writer = struct {...@@ -1153,14 +1151,12 @@ const Writer = struct {
1153 }1151 }
11541152
1155 fn writeOverflowArithmetic(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {1153 fn writeOverflowArithmetic(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {
1156 const extra = self.code.extraData(Zir.Inst.OverflowArithmetic, extended.operand).data;1154 const extra = self.code.extraData(Zir.Inst.BinNode, extended.operand).data;
1157 const src = LazySrcLoc.nodeOffset(extra.node);1155 const src = LazySrcLoc.nodeOffset(extra.node);
11581156
1159 try self.writeInstRef(stream, extra.lhs);1157 try self.writeInstRef(stream, extra.lhs);
1160 try stream.writeAll(", ");1158 try stream.writeAll(", ");
1161 try self.writeInstRef(stream, extra.rhs);1159 try self.writeInstRef(stream, extra.rhs);
1162 try stream.writeAll(", ");
1163 try self.writeInstRef(stream, extra.ptr);
1164 try stream.writeAll(")) ");1160 try stream.writeAll(")) ");
1165 try self.writeSrc(stream, src);1161 try self.writeSrc(stream, src);
1166 }1162 }
src/type.zig+1
...@@ -3123,6 +3123,7 @@ pub const Type = extern union {...@@ -3123,6 +3123,7 @@ pub const Type = extern union {
3123 for (tuple.types) |field_ty, i| {3123 for (tuple.types) |field_ty, i| {
3124 const val = tuple.values[i];3124 const val = tuple.values[i];
3125 if (val.tag() != .unreachable_value) continue; // comptime field3125 if (val.tag() != .unreachable_value) continue; // comptime field
3126 if (!(field_ty.hasRuntimeBits())) continue;
31263127
3127 switch (try field_ty.abiAlignmentAdvanced(target, strat)) {3128 switch (try field_ty.abiAlignmentAdvanced(target, strat)) {
3128 .scalar => |field_align| big_align = @max(big_align, field_align),3129 .scalar => |field_align| big_align = @max(big_align, field_align),
src/value.zig+11-8
...@@ -3259,8 +3259,7 @@ pub const Value = extern union {...@@ -3259,8 +3259,7 @@ pub const Value = extern union {
3259 }3259 }
32603260
3261 pub const OverflowArithmeticResult = struct {3261 pub const OverflowArithmeticResult = struct {
3262 /// TODO: Rename to `overflow_bit` and make of type `u1`.3262 overflow_bit: Value,
3263 overflowed: Value,
3264 wrapped_result: Value,3263 wrapped_result: Value,
3265 };3264 };
32663265
...@@ -3395,11 +3394,11 @@ pub const Value = extern union {...@@ -3395,11 +3394,11 @@ pub const Value = extern union {
3395 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);3394 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
3396 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);3395 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
3397 const of_math_result = try intMulWithOverflowScalar(lhs_elem, rhs_elem, ty.scalarType(), arena, target);3396 const of_math_result = try intMulWithOverflowScalar(lhs_elem, rhs_elem, ty.scalarType(), arena, target);
3398 overflowed_data[i] = of_math_result.overflowed;3397 overflowed_data[i] = of_math_result.overflow_bit;
3399 scalar.* = of_math_result.wrapped_result;3398 scalar.* = of_math_result.wrapped_result;
3400 }3399 }
3401 return OverflowArithmeticResult{3400 return OverflowArithmeticResult{
3402 .overflowed = try Value.Tag.aggregate.create(arena, overflowed_data),3401 .overflow_bit = try Value.Tag.aggregate.create(arena, overflowed_data),
3403 .wrapped_result = try Value.Tag.aggregate.create(arena, result_data),3402 .wrapped_result = try Value.Tag.aggregate.create(arena, result_data),
3404 };3403 };
3405 }3404 }
...@@ -3436,7 +3435,7 @@ pub const Value = extern union {...@@ -3436,7 +3435,7 @@ pub const Value = extern union {
3436 }3435 }
34373436
3438 return OverflowArithmeticResult{3437 return OverflowArithmeticResult{
3439 .overflowed = makeBool(overflowed),3438 .overflow_bit = boolToInt(overflowed),
3440 .wrapped_result = try fromBigInt(arena, result_bigint.toConst()),3439 .wrapped_result = try fromBigInt(arena, result_bigint.toConst()),
3441 };3440 };
3442 }3441 }
...@@ -4141,11 +4140,11 @@ pub const Value = extern union {...@@ -4141,11 +4140,11 @@ pub const Value = extern union {
4141 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);4140 const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf);
4142 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);4141 const rhs_elem = rhs.elemValueBuffer(mod, i, &rhs_buf);
4143 const of_math_result = try shlWithOverflowScalar(lhs_elem, rhs_elem, ty.scalarType(), allocator, target);4142 const of_math_result = try shlWithOverflowScalar(lhs_elem, rhs_elem, ty.scalarType(), allocator, target);
4144 overflowed_data[i] = of_math_result.overflowed;4143 overflowed_data[i] = of_math_result.overflow_bit;
4145 scalar.* = of_math_result.wrapped_result;4144 scalar.* = of_math_result.wrapped_result;
4146 }4145 }
4147 return OverflowArithmeticResult{4146 return OverflowArithmeticResult{
4148 .overflowed = try Value.Tag.aggregate.create(allocator, overflowed_data),4147 .overflow_bit = try Value.Tag.aggregate.create(allocator, overflowed_data),
4149 .wrapped_result = try Value.Tag.aggregate.create(allocator, result_data),4148 .wrapped_result = try Value.Tag.aggregate.create(allocator, result_data),
4150 };4149 };
4151 }4150 }
...@@ -4178,7 +4177,7 @@ pub const Value = extern union {...@@ -4178,7 +4177,7 @@ pub const Value = extern union {
4178 result_bigint.truncate(result_bigint.toConst(), info.signedness, info.bits);4177 result_bigint.truncate(result_bigint.toConst(), info.signedness, info.bits);
4179 }4178 }
4180 return OverflowArithmeticResult{4179 return OverflowArithmeticResult{
4181 .overflowed = makeBool(overflowed),4180 .overflow_bit = boolToInt(overflowed),
4182 .wrapped_result = try fromBigInt(allocator, result_bigint.toConst()),4181 .wrapped_result = try fromBigInt(allocator, result_bigint.toConst()),
4183 };4182 };
4184 }4183 }
...@@ -5492,6 +5491,10 @@ pub const Value = extern union {...@@ -5492,6 +5491,10 @@ pub const Value = extern union {
5492 return if (x) Value.true else Value.false;5491 return if (x) Value.true else Value.false;
5493 }5492 }
54945493
5494 pub fn boolToInt(x: bool) Value {
5495 return if (x) Value.one else Value.zero;
5496 }
5497
5495 pub const RuntimeIndex = enum(u32) {5498 pub const RuntimeIndex = enum(u32) {
5496 zero = 0,5499 zero = 0,
5497 comptime_field_ptr = std.math.maxInt(u32),5500 comptime_field_ptr = std.math.maxInt(u32),