| ... | @@ -2228,7 +2228,6 @@ fn zirEnumDecl( | ... | @@ -2228,7 +2228,6 @@ fn zirEnumDecl( |
| 2228 | enum_obj.tag_ty_inferred = true; | 2228 | enum_obj.tag_ty_inferred = true; |
| 2229 | } | 2229 | } |
| 2230 | } | 2230 | } |
| 2231 | const target = mod.getTarget(); | | |
| 2232 | | 2231 | |
| 2233 | try enum_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len); | 2232 | try enum_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len); |
| 2234 | const any_values = for (sema.code.extra[body_end..][0..bit_bags_count]) |bag| { | 2233 | const any_values = for (sema.code.extra[body_end..][0..bit_bags_count]) |bag| { |
| ... | @@ -2291,7 +2290,7 @@ fn zirEnumDecl( | ... | @@ -2291,7 +2290,7 @@ fn zirEnumDecl( |
| 2291 | }); | 2290 | }); |
| 2292 | } else if (any_values) { | 2291 | } else if (any_values) { |
| 2293 | const tag_val = if (last_tag_val) |val| | 2292 | const tag_val = if (last_tag_val) |val| |
| 2294 | try val.intAdd(Value.one, enum_obj.tag_ty, sema.arena, target) | 2293 | try sema.intAdd(block, src, val, Value.one, enum_obj.tag_ty) |
| 2295 | else | 2294 | else |
| 2296 | Value.zero; | 2295 | Value.zero; |
| 2297 | last_tag_val = tag_val; | 2296 | last_tag_val = tag_val; |
| ... | @@ -6054,7 +6053,7 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -6054,7 +6053,7 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 6054 | if (int_val.isUndef()) { | 6053 | if (int_val.isUndef()) { |
| 6055 | return sema.failWithUseOfUndef(block, operand_src); | 6054 | return sema.failWithUseOfUndef(block, operand_src); |
| 6056 | } | 6055 | } |
| 6057 | if (!dest_ty.enumHasInt(int_val, sema.mod)) { | 6056 | if (!(try sema.enumHasInt(block, src, dest_ty, int_val))) { |
| 6058 | const msg = msg: { | 6057 | const msg = msg: { |
| 6059 | const msg = try sema.errMsg( | 6058 | const msg = try sema.errMsg( |
| 6060 | block, | 6059 | block, |
| ... | @@ -7082,7 +7081,7 @@ fn intCast( | ... | @@ -7082,7 +7081,7 @@ fn intCast( |
| 7082 | // range to account for negative values. | 7081 | // range to account for negative values. |
| 7083 | const dest_range_val = if (wanted_info.signedness == .signed) range_val: { | 7082 | const dest_range_val = if (wanted_info.signedness == .signed) range_val: { |
| 7084 | const range_minus_one = try dest_max_val.shl(Value.one, unsigned_operand_ty, sema.arena, target); | 7083 | const range_minus_one = try dest_max_val.shl(Value.one, unsigned_operand_ty, sema.arena, target); |
| 7085 | break :range_val try range_minus_one.intAdd(Value.one, unsigned_operand_ty, sema.arena, target); | 7084 | break :range_val try sema.intAdd(block, operand_src, range_minus_one, Value.one, unsigned_operand_ty); |
| 7086 | } else dest_max_val; | 7085 | } else dest_max_val; |
| 7087 | const dest_range = try sema.addConstant(unsigned_operand_ty, dest_range_val); | 7086 | const dest_range = try sema.addConstant(unsigned_operand_ty, dest_range_val); |
| 7088 | | 7087 | |
| ... | @@ -8203,8 +8202,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -8203,8 +8202,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8203 | // Validation above ensured these will succeed. | 8202 | // Validation above ensured these will succeed. |
| 8204 | const first_tv = sema.resolveInstConst(&child_block, .unneeded, item_first) catch unreachable; | 8203 | const first_tv = sema.resolveInstConst(&child_block, .unneeded, item_first) catch unreachable; |
| 8205 | const last_tv = sema.resolveInstConst(&child_block, .unneeded, item_last) catch unreachable; | 8204 | const last_tv = sema.resolveInstConst(&child_block, .unneeded, item_last) catch unreachable; |
| 8206 | if (Value.compare(operand_val, .gte, first_tv.val, operand_ty, sema.mod) and | 8205 | if ((try sema.compare(block, src, operand_val, .gte, first_tv.val, operand_ty)) and |
| 8207 | Value.compare(operand_val, .lte, last_tv.val, operand_ty, sema.mod)) | 8206 | (try sema.compare(block, src, operand_val, .lte, last_tv.val, operand_ty))) |
| 8208 | { | 8207 | { |
| 8209 | return sema.resolveBlockBody(block, src, &child_block, body, inst, merges); | 8208 | return sema.resolveBlockBody(block, src, &child_block, body, inst, merges); |
| 8210 | } | 8209 | } |
| ... | @@ -8878,7 +8877,7 @@ fn zirShl( | ... | @@ -8878,7 +8877,7 @@ fn zirShl( |
| 8878 | if (rhs_val.isUndef()) { | 8877 | if (rhs_val.isUndef()) { |
| 8879 | return sema.addConstUndef(sema.typeOf(lhs)); | 8878 | return sema.addConstUndef(sema.typeOf(lhs)); |
| 8880 | } | 8879 | } |
| 8881 | if (rhs_val.compareWithZero(.eq)) { | 8880 | if (try rhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) { |
| 8882 | return lhs; | 8881 | return lhs; |
| 8883 | } | 8882 | } |
| 8884 | } | 8883 | } |
| ... | @@ -8895,7 +8894,7 @@ fn zirShl( | ... | @@ -8895,7 +8894,7 @@ fn zirShl( |
| 8895 | } | 8894 | } |
| 8896 | const int_info = scalar_ty.intInfo(target); | 8895 | const int_info = scalar_ty.intInfo(target); |
| 8897 | const truncated = try shifted.intTrunc(lhs_ty, sema.arena, int_info.signedness, int_info.bits, target); | 8896 | const truncated = try shifted.intTrunc(lhs_ty, sema.arena, int_info.signedness, int_info.bits, target); |
| 8898 | if (truncated.compare(.eq, shifted, lhs_ty, sema.mod)) { | 8897 | if (try sema.compare(block, src, truncated, .eq, shifted, lhs_ty)) { |
| 8899 | break :val shifted; | 8898 | break :val shifted; |
| 8900 | } | 8899 | } |
| 8901 | return sema.addConstUndef(lhs_ty); | 8900 | return sema.addConstUndef(lhs_ty); |
| ... | @@ -8999,13 +8998,13 @@ fn zirShr( | ... | @@ -8999,13 +8998,13 @@ fn zirShr( |
| 8999 | return sema.addConstUndef(lhs_ty); | 8998 | return sema.addConstUndef(lhs_ty); |
| 9000 | } | 8999 | } |
| 9001 | // If rhs is 0, return lhs without doing any calculations. | 9000 | // If rhs is 0, return lhs without doing any calculations. |
| 9002 | if (rhs_val.compareWithZero(.eq)) { | 9001 | if (try rhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) { |
| 9003 | return sema.addConstant(lhs_ty, lhs_val); | 9002 | return sema.addConstant(lhs_ty, lhs_val); |
| 9004 | } | 9003 | } |
| 9005 | if (air_tag == .shr_exact) { | 9004 | if (air_tag == .shr_exact) { |
| 9006 | // Detect if any ones would be shifted out. | 9005 | // Detect if any ones would be shifted out. |
| 9007 | const truncated = try lhs_val.intTruncBitsAsValue(lhs_ty, sema.arena, .unsigned, rhs_val, target); | 9006 | const truncated = try lhs_val.intTruncBitsAsValue(lhs_ty, sema.arena, .unsigned, rhs_val, target); |
| 9008 | if (!truncated.compareWithZero(.eq)) { | 9007 | if (!(try truncated.compareWithZeroAdvanced(.eq, sema.kit(block, src)))) { |
| 9009 | return sema.addConstUndef(lhs_ty); | 9008 | return sema.addConstUndef(lhs_ty); |
| 9010 | } | 9009 | } |
| 9011 | } | 9010 | } |
| ... | @@ -9015,7 +9014,7 @@ fn zirShr( | ... | @@ -9015,7 +9014,7 @@ fn zirShr( |
| 9015 | // Even if lhs is not comptime known, we can still deduce certain things based | 9014 | // Even if lhs is not comptime known, we can still deduce certain things based |
| 9016 | // on rhs. | 9015 | // on rhs. |
| 9017 | // If rhs is 0, return lhs without doing any calculations. | 9016 | // If rhs is 0, return lhs without doing any calculations. |
| 9018 | if (rhs_val.compareWithZero(.eq)) { | 9017 | if (try rhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) { |
| 9019 | return lhs; | 9018 | return lhs; |
| 9020 | } | 9019 | } |
| 9021 | break :rs lhs_src; | 9020 | break :rs lhs_src; |
| ... | @@ -9578,12 +9577,12 @@ fn zirOverflowArithmetic( | ... | @@ -9578,12 +9577,12 @@ fn zirOverflowArithmetic( |
| 9578 | // to the result, even if it is undefined.. | 9577 | // to the result, even if it is undefined.. |
| 9579 | // Otherwise, if either of the argument is undefined, undefined is returned. | 9578 | // Otherwise, if either of the argument is undefined, undefined is returned. |
| 9580 | if (maybe_lhs_val) |lhs_val| { | 9579 | if (maybe_lhs_val) |lhs_val| { |
| 9581 | if (!lhs_val.isUndef() and lhs_val.compareWithZero(.eq)) { | 9580 | if (!lhs_val.isUndef() and (try lhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src)))) { |
| 9582 | break :result .{ .overflowed = try sema.addBool(overflowed_ty, false), .wrapped = rhs }; | 9581 | break :result .{ .overflowed = try sema.addBool(overflowed_ty, false), .wrapped = rhs }; |
| 9583 | } | 9582 | } |
| 9584 | } | 9583 | } |
| 9585 | if (maybe_rhs_val) |rhs_val| { | 9584 | if (maybe_rhs_val) |rhs_val| { |
| 9586 | if (!rhs_val.isUndef() and rhs_val.compareWithZero(.eq)) { | 9585 | if (!rhs_val.isUndef() and (try rhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src)))) { |
| 9587 | break :result .{ .overflowed = try sema.addBool(overflowed_ty, false), .wrapped = lhs }; | 9586 | break :result .{ .overflowed = try sema.addBool(overflowed_ty, false), .wrapped = lhs }; |
| 9588 | } | 9587 | } |
| 9589 | } | 9588 | } |
| ... | @@ -9593,7 +9592,7 @@ fn zirOverflowArithmetic( | ... | @@ -9593,7 +9592,7 @@ fn zirOverflowArithmetic( |
| 9593 | break :result .{ .overflowed = try sema.addConstUndef(overflowed_ty), .wrapped = try sema.addConstUndef(dest_ty) }; | 9592 | break :result .{ .overflowed = try sema.addConstUndef(overflowed_ty), .wrapped = try sema.addConstUndef(dest_ty) }; |
| 9594 | } | 9593 | } |
| 9595 | | 9594 | |
| 9596 | const result = try lhs_val.intAddWithOverflow(rhs_val, dest_ty, sema.arena, target); | 9595 | const result = try sema.intAddWithOverflow(block, src, lhs_val, rhs_val, dest_ty); |
| 9597 | const overflowed = try sema.addConstant(overflowed_ty, result.overflowed); | 9596 | const overflowed = try sema.addConstant(overflowed_ty, result.overflowed); |
| 9598 | const wrapped = try sema.addConstant(dest_ty, result.wrapped_result); | 9597 | const wrapped = try sema.addConstant(dest_ty, result.wrapped_result); |
| 9599 | break :result .{ .overflowed = overflowed, .wrapped = wrapped }; | 9598 | break :result .{ .overflowed = overflowed, .wrapped = wrapped }; |
| ... | @@ -9606,14 +9605,14 @@ fn zirOverflowArithmetic( | ... | @@ -9606,14 +9605,14 @@ fn zirOverflowArithmetic( |
| 9606 | if (maybe_rhs_val) |rhs_val| { | 9605 | if (maybe_rhs_val) |rhs_val| { |
| 9607 | if (rhs_val.isUndef()) { | 9606 | if (rhs_val.isUndef()) { |
| 9608 | break :result .{ .overflowed = try sema.addConstUndef(overflowed_ty), .wrapped = try sema.addConstUndef(dest_ty) }; | 9607 | break :result .{ .overflowed = try sema.addConstUndef(overflowed_ty), .wrapped = try sema.addConstUndef(dest_ty) }; |
| 9609 | } else if (rhs_val.compareWithZero(.eq)) { | 9608 | } else if (try rhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) { |
| 9610 | break :result .{ .overflowed = try sema.addBool(overflowed_ty, false), .wrapped = lhs }; | 9609 | break :result .{ .overflowed = try sema.addBool(overflowed_ty, false), .wrapped = lhs }; |
| 9611 | } else if (maybe_lhs_val) |lhs_val| { | 9610 | } else if (maybe_lhs_val) |lhs_val| { |
| 9612 | if (lhs_val.isUndef()) { | 9611 | if (lhs_val.isUndef()) { |
| 9613 | break :result .{ .overflowed = try sema.addConstUndef(overflowed_ty), .wrapped = try sema.addConstUndef(dest_ty) }; | 9612 | break :result .{ .overflowed = try sema.addConstUndef(overflowed_ty), .wrapped = try sema.addConstUndef(dest_ty) }; |
| 9614 | } | 9613 | } |
| 9615 | | 9614 | |
| 9616 | const result = try lhs_val.intSubWithOverflow(rhs_val, dest_ty, sema.arena, target); | 9615 | const result = try sema.intSubWithOverflow(block, src, lhs_val, rhs_val, dest_ty); |
| 9617 | const overflowed = try sema.addConstant(overflowed_ty, result.overflowed); | 9616 | const overflowed = try sema.addConstant(overflowed_ty, result.overflowed); |
| 9618 | const wrapped = try sema.addConstant(dest_ty, result.wrapped_result); | 9617 | const wrapped = try sema.addConstant(dest_ty, result.wrapped_result); |
| 9619 | break :result .{ .overflowed = overflowed, .wrapped = wrapped }; | 9618 | break :result .{ .overflowed = overflowed, .wrapped = wrapped }; |
| ... | @@ -9626,9 +9625,9 @@ fn zirOverflowArithmetic( | ... | @@ -9626,9 +9625,9 @@ fn zirOverflowArithmetic( |
| 9626 | // Otherwise, if either of the arguments is undefined, both results are undefined. | 9625 | // Otherwise, if either of the arguments is undefined, both results are undefined. |
| 9627 | if (maybe_lhs_val) |lhs_val| { | 9626 | if (maybe_lhs_val) |lhs_val| { |
| 9628 | if (!lhs_val.isUndef()) { | 9627 | if (!lhs_val.isUndef()) { |
| 9629 | if (lhs_val.compareWithZero(.eq)) { | 9628 | if (try lhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) { |
| 9630 | break :result .{ .overflowed = try sema.addBool(overflowed_ty, false), .wrapped = lhs }; | 9629 | break :result .{ .overflowed = try sema.addBool(overflowed_ty, false), .wrapped = lhs }; |
| 9631 | } else if (lhs_val.compare(.eq, Value.one, dest_ty, mod)) { | 9630 | } else if (try sema.compare(block, src, lhs_val, .eq, Value.one, dest_ty)) { |
| 9632 | break :result .{ .overflowed = try sema.addBool(overflowed_ty, false), .wrapped = rhs }; | 9631 | break :result .{ .overflowed = try sema.addBool(overflowed_ty, false), .wrapped = rhs }; |
| 9633 | } | 9632 | } |
| 9634 | } | 9633 | } |
| ... | @@ -9636,9 +9635,9 @@ fn zirOverflowArithmetic( | ... | @@ -9636,9 +9635,9 @@ fn zirOverflowArithmetic( |
| 9636 | | 9635 | |
| 9637 | if (maybe_rhs_val) |rhs_val| { | 9636 | if (maybe_rhs_val) |rhs_val| { |
| 9638 | if (!rhs_val.isUndef()) { | 9637 | if (!rhs_val.isUndef()) { |
| 9639 | if (rhs_val.compareWithZero(.eq)) { | 9638 | if (try rhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) { |
| 9640 | break :result .{ .overflowed = try sema.addBool(overflowed_ty, false), .wrapped = rhs }; | 9639 | break :result .{ .overflowed = try sema.addBool(overflowed_ty, false), .wrapped = rhs }; |
| 9641 | } else if (rhs_val.compare(.eq, Value.one, dest_ty, mod)) { | 9640 | } else if (try sema.compare(block, src, rhs_val, .eq, Value.one, dest_ty)) { |
| 9642 | break :result .{ .overflowed = try sema.addBool(overflowed_ty, false), .wrapped = lhs }; | 9641 | break :result .{ .overflowed = try sema.addBool(overflowed_ty, false), .wrapped = lhs }; |
| 9643 | } | 9642 | } |
| 9644 | } | 9643 | } |
| ... | @@ -9662,12 +9661,12 @@ fn zirOverflowArithmetic( | ... | @@ -9662,12 +9661,12 @@ fn zirOverflowArithmetic( |
| 9662 | // If rhs is zero, the result is lhs (even if undefined) and no overflow occurred. | 9661 | // If rhs is zero, the result is lhs (even if undefined) and no overflow occurred. |
| 9663 | // Oterhwise if either of the arguments is undefined, both results are undefined. | 9662 | // Oterhwise if either of the arguments is undefined, both results are undefined. |
| 9664 | if (maybe_lhs_val) |lhs_val| { | 9663 | if (maybe_lhs_val) |lhs_val| { |
| 9665 | if (!lhs_val.isUndef() and lhs_val.compareWithZero(.eq)) { | 9664 | if (!lhs_val.isUndef() and (try lhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src)))) { |
| 9666 | break :result .{ .overflowed = try sema.addBool(overflowed_ty, false), .wrapped = lhs }; | 9665 | break :result .{ .overflowed = try sema.addBool(overflowed_ty, false), .wrapped = lhs }; |
| 9667 | } | 9666 | } |
| 9668 | } | 9667 | } |
| 9669 | if (maybe_rhs_val) |rhs_val| { | 9668 | if (maybe_rhs_val) |rhs_val| { |
| 9670 | if (!rhs_val.isUndef() and rhs_val.compareWithZero(.eq)) { | 9669 | if (!rhs_val.isUndef() and (try rhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src)))) { |
| 9671 | break :result .{ .overflowed = try sema.addBool(overflowed_ty, false), .wrapped = lhs }; | 9670 | break :result .{ .overflowed = try sema.addBool(overflowed_ty, false), .wrapped = lhs }; |
| 9672 | } | 9671 | } |
| 9673 | } | 9672 | } |
| ... | @@ -9815,7 +9814,7 @@ fn analyzeArithmetic( | ... | @@ -9815,7 +9814,7 @@ fn analyzeArithmetic( |
| 9815 | // overflow (max_int), causing illegal behavior. | 9814 | // overflow (max_int), causing illegal behavior. |
| 9816 | // For floats: either operand being undef makes the result undef. | 9815 | // For floats: either operand being undef makes the result undef. |
| 9817 | if (maybe_lhs_val) |lhs_val| { | 9816 | if (maybe_lhs_val) |lhs_val| { |
| 9818 | if (!lhs_val.isUndef() and lhs_val.compareWithZero(.eq)) { | 9817 | if (!lhs_val.isUndef() and (try lhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src)))) { |
| 9819 | return casted_rhs; | 9818 | return casted_rhs; |
| 9820 | } | 9819 | } |
| 9821 | } | 9820 | } |
| ... | @@ -9827,7 +9826,7 @@ fn analyzeArithmetic( | ... | @@ -9827,7 +9826,7 @@ fn analyzeArithmetic( |
| 9827 | return sema.addConstUndef(resolved_type); | 9826 | return sema.addConstUndef(resolved_type); |
| 9828 | } | 9827 | } |
| 9829 | } | 9828 | } |
| 9830 | if (rhs_val.compareWithZero(.eq)) { | 9829 | if (try rhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) { |
| 9831 | return casted_lhs; | 9830 | return casted_lhs; |
| 9832 | } | 9831 | } |
| 9833 | } | 9832 | } |
| ... | @@ -9841,15 +9840,15 @@ fn analyzeArithmetic( | ... | @@ -9841,15 +9840,15 @@ fn analyzeArithmetic( |
| 9841 | } | 9840 | } |
| 9842 | if (maybe_rhs_val) |rhs_val| { | 9841 | if (maybe_rhs_val) |rhs_val| { |
| 9843 | if (is_int) { | 9842 | if (is_int) { |
| 9844 | const sum = try lhs_val.intAdd(rhs_val, resolved_type, sema.arena, target); | 9843 | const sum = try sema.intAdd(block, src, lhs_val, rhs_val, resolved_type); |
| 9845 | if (!sum.intFitsInType(resolved_type, target)) { | 9844 | if (!(try sema.intFitsInType(block, src, sum, resolved_type))) { |
| 9846 | return sema.failWithIntegerOverflow(block, src, resolved_type, sum); | 9845 | return sema.failWithIntegerOverflow(block, src, resolved_type, sum); |
| 9847 | } | 9846 | } |
| 9848 | return sema.addConstant(resolved_type, sum); | 9847 | return sema.addConstant(resolved_type, sum); |
| 9849 | } else { | 9848 | } else { |
| 9850 | return sema.addConstant( | 9849 | return sema.addConstant( |
| 9851 | resolved_type, | 9850 | resolved_type, |
| 9852 | try lhs_val.floatAdd(rhs_val, resolved_type, sema.arena, target), | 9851 | try sema.floatAdd(lhs_val, rhs_val, resolved_type), |
| 9853 | ); | 9852 | ); |
| 9854 | } | 9853 | } |
| 9855 | } else break :rs .{ .src = rhs_src, .air_tag = .add }; | 9854 | } else break :rs .{ .src = rhs_src, .air_tag = .add }; |
| ... | @@ -9860,7 +9859,7 @@ fn analyzeArithmetic( | ... | @@ -9860,7 +9859,7 @@ fn analyzeArithmetic( |
| 9860 | // If either of the operands are zero, the other operand is returned. | 9859 | // If either of the operands are zero, the other operand is returned. |
| 9861 | // If either of the operands are undefined, the result is undefined. | 9860 | // If either of the operands are undefined, the result is undefined. |
| 9862 | if (maybe_lhs_val) |lhs_val| { | 9861 | if (maybe_lhs_val) |lhs_val| { |
| 9863 | if (!lhs_val.isUndef() and lhs_val.compareWithZero(.eq)) { | 9862 | if (!lhs_val.isUndef() and (try lhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src)))) { |
| 9864 | return casted_rhs; | 9863 | return casted_rhs; |
| 9865 | } | 9864 | } |
| 9866 | } | 9865 | } |
| ... | @@ -9868,13 +9867,13 @@ fn analyzeArithmetic( | ... | @@ -9868,13 +9867,13 @@ fn analyzeArithmetic( |
| 9868 | if (rhs_val.isUndef()) { | 9867 | if (rhs_val.isUndef()) { |
| 9869 | return sema.addConstUndef(resolved_type); | 9868 | return sema.addConstUndef(resolved_type); |
| 9870 | } | 9869 | } |
| 9871 | if (rhs_val.compareWithZero(.eq)) { | 9870 | if (try rhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) { |
| 9872 | return casted_lhs; | 9871 | return casted_lhs; |
| 9873 | } | 9872 | } |
| 9874 | if (maybe_lhs_val) |lhs_val| { | 9873 | if (maybe_lhs_val) |lhs_val| { |
| 9875 | return sema.addConstant( | 9874 | return sema.addConstant( |
| 9876 | resolved_type, | 9875 | resolved_type, |
| 9877 | try lhs_val.numberAddWrap(rhs_val, resolved_type, sema.arena, target), | 9876 | try sema.numberAddWrap(block, src, lhs_val, rhs_val, resolved_type), |
| 9878 | ); | 9877 | ); |
| 9879 | } else break :rs .{ .src = lhs_src, .air_tag = .addwrap }; | 9878 | } else break :rs .{ .src = lhs_src, .air_tag = .addwrap }; |
| 9880 | } else break :rs .{ .src = rhs_src, .air_tag = .addwrap }; | 9879 | } else break :rs .{ .src = rhs_src, .air_tag = .addwrap }; |
| ... | @@ -9884,7 +9883,7 @@ fn analyzeArithmetic( | ... | @@ -9884,7 +9883,7 @@ fn analyzeArithmetic( |
| 9884 | // If either of the operands are zero, then the other operand is returned. | 9883 | // If either of the operands are zero, then the other operand is returned. |
| 9885 | // If either of the operands are undefined, the result is undefined. | 9884 | // If either of the operands are undefined, the result is undefined. |
| 9886 | if (maybe_lhs_val) |lhs_val| { | 9885 | if (maybe_lhs_val) |lhs_val| { |
| 9887 | if (!lhs_val.isUndef() and lhs_val.compareWithZero(.eq)) { | 9886 | if (!lhs_val.isUndef() and (try lhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src)))) { |
| 9888 | return casted_rhs; | 9887 | return casted_rhs; |
| 9889 | } | 9888 | } |
| 9890 | } | 9889 | } |
| ... | @@ -9892,12 +9891,12 @@ fn analyzeArithmetic( | ... | @@ -9892,12 +9891,12 @@ fn analyzeArithmetic( |
| 9892 | if (rhs_val.isUndef()) { | 9891 | if (rhs_val.isUndef()) { |
| 9893 | return sema.addConstUndef(resolved_type); | 9892 | return sema.addConstUndef(resolved_type); |
| 9894 | } | 9893 | } |
| 9895 | if (rhs_val.compareWithZero(.eq)) { | 9894 | if (try rhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) { |
| 9896 | return casted_lhs; | 9895 | return casted_lhs; |
| 9897 | } | 9896 | } |
| 9898 | if (maybe_lhs_val) |lhs_val| { | 9897 | if (maybe_lhs_val) |lhs_val| { |
| 9899 | const val = if (scalar_tag == .ComptimeInt) | 9898 | const val = if (scalar_tag == .ComptimeInt) |
| 9900 | try lhs_val.intAdd(rhs_val, resolved_type, sema.arena, target) | 9899 | try sema.intAdd(block, src, lhs_val, rhs_val, resolved_type) |
| 9901 | else | 9900 | else |
| 9902 | try lhs_val.intAddSat(rhs_val, resolved_type, sema.arena, target); | 9901 | try lhs_val.intAddSat(rhs_val, resolved_type, sema.arena, target); |
| 9903 | | 9902 | |
| ... | @@ -9921,7 +9920,7 @@ fn analyzeArithmetic( | ... | @@ -9921,7 +9920,7 @@ fn analyzeArithmetic( |
| 9921 | return sema.addConstUndef(resolved_type); | 9920 | return sema.addConstUndef(resolved_type); |
| 9922 | } | 9921 | } |
| 9923 | } | 9922 | } |
| 9924 | if (rhs_val.compareWithZero(.eq)) { | 9923 | if (try rhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) { |
| 9925 | return casted_lhs; | 9924 | return casted_lhs; |
| 9926 | } | 9925 | } |
| 9927 | } | 9926 | } |
| ... | @@ -9935,15 +9934,15 @@ fn analyzeArithmetic( | ... | @@ -9935,15 +9934,15 @@ fn analyzeArithmetic( |
| 9935 | } | 9934 | } |
| 9936 | if (maybe_rhs_val) |rhs_val| { | 9935 | if (maybe_rhs_val) |rhs_val| { |
| 9937 | if (is_int) { | 9936 | if (is_int) { |
| 9938 | const diff = try lhs_val.intSub(rhs_val, resolved_type, sema.arena, target); | 9937 | const diff = try sema.intSub(block, src, lhs_val, rhs_val, resolved_type); |
| 9939 | if (!diff.intFitsInType(resolved_type, target)) { | 9938 | if (!(try sema.intFitsInType(block, src, diff, resolved_type))) { |
| 9940 | return sema.failWithIntegerOverflow(block, src, resolved_type, diff); | 9939 | return sema.failWithIntegerOverflow(block, src, resolved_type, diff); |
| 9941 | } | 9940 | } |
| 9942 | return sema.addConstant(resolved_type, diff); | 9941 | return sema.addConstant(resolved_type, diff); |
| 9943 | } else { | 9942 | } else { |
| 9944 | return sema.addConstant( | 9943 | return sema.addConstant( |
| 9945 | resolved_type, | 9944 | resolved_type, |
| 9946 | try lhs_val.floatSub(rhs_val, resolved_type, sema.arena, target), | 9945 | try sema.floatSub(lhs_val, rhs_val, resolved_type), |
| 9947 | ); | 9946 | ); |
| 9948 | } | 9947 | } |
| 9949 | } else break :rs .{ .src = rhs_src, .air_tag = .sub }; | 9948 | } else break :rs .{ .src = rhs_src, .air_tag = .sub }; |
| ... | @@ -9957,7 +9956,7 @@ fn analyzeArithmetic( | ... | @@ -9957,7 +9956,7 @@ fn analyzeArithmetic( |
| 9957 | if (rhs_val.isUndef()) { | 9956 | if (rhs_val.isUndef()) { |
| 9958 | return sema.addConstUndef(resolved_type); | 9957 | return sema.addConstUndef(resolved_type); |
| 9959 | } | 9958 | } |
| 9960 | if (rhs_val.compareWithZero(.eq)) { | 9959 | if (try rhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) { |
| 9961 | return casted_lhs; | 9960 | return casted_lhs; |
| 9962 | } | 9961 | } |
| 9963 | } | 9962 | } |
| ... | @@ -9968,7 +9967,7 @@ fn analyzeArithmetic( | ... | @@ -9968,7 +9967,7 @@ fn analyzeArithmetic( |
| 9968 | if (maybe_rhs_val) |rhs_val| { | 9967 | if (maybe_rhs_val) |rhs_val| { |
| 9969 | return sema.addConstant( | 9968 | return sema.addConstant( |
| 9970 | resolved_type, | 9969 | resolved_type, |
| 9971 | try lhs_val.numberSubWrap(rhs_val, resolved_type, sema.arena, target), | 9970 | try sema.numberSubWrap(block, src, lhs_val, rhs_val, resolved_type), |
| 9972 | ); | 9971 | ); |
| 9973 | } else break :rs .{ .src = rhs_src, .air_tag = .subwrap }; | 9972 | } else break :rs .{ .src = rhs_src, .air_tag = .subwrap }; |
| 9974 | } else break :rs .{ .src = lhs_src, .air_tag = .subwrap }; | 9973 | } else break :rs .{ .src = lhs_src, .air_tag = .subwrap }; |
| ... | @@ -9981,7 +9980,7 @@ fn analyzeArithmetic( | ... | @@ -9981,7 +9980,7 @@ fn analyzeArithmetic( |
| 9981 | if (rhs_val.isUndef()) { | 9980 | if (rhs_val.isUndef()) { |
| 9982 | return sema.addConstUndef(resolved_type); | 9981 | return sema.addConstUndef(resolved_type); |
| 9983 | } | 9982 | } |
| 9984 | if (rhs_val.compareWithZero(.eq)) { | 9983 | if (try rhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) { |
| 9985 | return casted_lhs; | 9984 | return casted_lhs; |
| 9986 | } | 9985 | } |
| 9987 | } | 9986 | } |
| ... | @@ -9991,7 +9990,7 @@ fn analyzeArithmetic( | ... | @@ -9991,7 +9990,7 @@ fn analyzeArithmetic( |
| 9991 | } | 9990 | } |
| 9992 | if (maybe_rhs_val) |rhs_val| { | 9991 | if (maybe_rhs_val) |rhs_val| { |
| 9993 | const val = if (scalar_tag == .ComptimeInt) | 9992 | const val = if (scalar_tag == .ComptimeInt) |
| 9994 | try lhs_val.intSub(rhs_val, resolved_type, sema.arena, target) | 9993 | try sema.intSub(block, src, lhs_val, rhs_val, resolved_type) |
| 9995 | else | 9994 | else |
| 9996 | try lhs_val.intSubSat(rhs_val, resolved_type, sema.arena, target); | 9995 | try lhs_val.intSubSat(rhs_val, resolved_type, sema.arena, target); |
| 9997 | | 9996 | |
| ... | @@ -10032,7 +10031,7 @@ fn analyzeArithmetic( | ... | @@ -10032,7 +10031,7 @@ fn analyzeArithmetic( |
| 10032 | .Int, .ComptimeInt, .ComptimeFloat => { | 10031 | .Int, .ComptimeInt, .ComptimeFloat => { |
| 10033 | if (maybe_lhs_val) |lhs_val| { | 10032 | if (maybe_lhs_val) |lhs_val| { |
| 10034 | if (!lhs_val.isUndef()) { | 10033 | if (!lhs_val.isUndef()) { |
| 10035 | if (lhs_val.compareWithZero(.eq)) { | 10034 | if (try lhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) { |
| 10036 | return sema.addConstant(resolved_type, Value.zero); | 10035 | return sema.addConstant(resolved_type, Value.zero); |
| 10037 | } | 10036 | } |
| 10038 | } | 10037 | } |
| ... | @@ -10041,7 +10040,7 @@ fn analyzeArithmetic( | ... | @@ -10041,7 +10040,7 @@ fn analyzeArithmetic( |
| 10041 | if (rhs_val.isUndef()) { | 10040 | if (rhs_val.isUndef()) { |
| 10042 | return sema.failWithUseOfUndef(block, rhs_src); | 10041 | return sema.failWithUseOfUndef(block, rhs_src); |
| 10043 | } | 10042 | } |
| 10044 | if (rhs_val.compareWithZero(.eq)) { | 10043 | if (try rhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) { |
| 10045 | return sema.failWithDivideByZero(block, rhs_src); | 10044 | return sema.failWithDivideByZero(block, rhs_src); |
| 10046 | } | 10045 | } |
| 10047 | } | 10046 | } |
| ... | @@ -10053,7 +10052,7 @@ fn analyzeArithmetic( | ... | @@ -10053,7 +10052,7 @@ fn analyzeArithmetic( |
| 10053 | if (lhs_val.isUndef()) { | 10052 | if (lhs_val.isUndef()) { |
| 10054 | if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) { | 10053 | if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) { |
| 10055 | if (maybe_rhs_val) |rhs_val| { | 10054 | if (maybe_rhs_val) |rhs_val| { |
| 10056 | if (rhs_val.compare(.neq, Value.negative_one, resolved_type, mod)) { | 10055 | if (try sema.compare(block, src, rhs_val, .neq, Value.negative_one, resolved_type)) { |
| 10057 | return sema.addConstUndef(resolved_type); | 10056 | return sema.addConstUndef(resolved_type); |
| 10058 | } | 10057 | } |
| 10059 | } | 10058 | } |
| ... | @@ -10111,7 +10110,7 @@ fn analyzeArithmetic( | ... | @@ -10111,7 +10110,7 @@ fn analyzeArithmetic( |
| 10111 | // If the lhs is undefined, result is undefined. | 10110 | // If the lhs is undefined, result is undefined. |
| 10112 | if (maybe_lhs_val) |lhs_val| { | 10111 | if (maybe_lhs_val) |lhs_val| { |
| 10113 | if (!lhs_val.isUndef()) { | 10112 | if (!lhs_val.isUndef()) { |
| 10114 | if (lhs_val.compareWithZero(.eq)) { | 10113 | if (try lhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) { |
| 10115 | return sema.addConstant(resolved_type, Value.zero); | 10114 | return sema.addConstant(resolved_type, Value.zero); |
| 10116 | } | 10115 | } |
| 10117 | } | 10116 | } |
| ... | @@ -10120,7 +10119,7 @@ fn analyzeArithmetic( | ... | @@ -10120,7 +10119,7 @@ fn analyzeArithmetic( |
| 10120 | if (rhs_val.isUndef()) { | 10119 | if (rhs_val.isUndef()) { |
| 10121 | return sema.failWithUseOfUndef(block, rhs_src); | 10120 | return sema.failWithUseOfUndef(block, rhs_src); |
| 10122 | } | 10121 | } |
| 10123 | if (rhs_val.compareWithZero(.eq)) { | 10122 | if (try rhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) { |
| 10124 | return sema.failWithDivideByZero(block, rhs_src); | 10123 | return sema.failWithDivideByZero(block, rhs_src); |
| 10125 | } | 10124 | } |
| 10126 | } | 10125 | } |
| ... | @@ -10128,7 +10127,7 @@ fn analyzeArithmetic( | ... | @@ -10128,7 +10127,7 @@ fn analyzeArithmetic( |
| 10128 | if (lhs_val.isUndef()) { | 10127 | if (lhs_val.isUndef()) { |
| 10129 | if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) { | 10128 | if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) { |
| 10130 | if (maybe_rhs_val) |rhs_val| { | 10129 | if (maybe_rhs_val) |rhs_val| { |
| 10131 | if (rhs_val.compare(.neq, Value.negative_one, resolved_type, mod)) { | 10130 | if (try sema.compare(block, src, rhs_val, .neq, Value.negative_one, resolved_type)) { |
| 10132 | return sema.addConstUndef(resolved_type); | 10131 | return sema.addConstUndef(resolved_type); |
| 10133 | } | 10132 | } |
| 10134 | } | 10133 | } |
| ... | @@ -10174,7 +10173,7 @@ fn analyzeArithmetic( | ... | @@ -10174,7 +10173,7 @@ fn analyzeArithmetic( |
| 10174 | // If the lhs is undefined, result is undefined. | 10173 | // If the lhs is undefined, result is undefined. |
| 10175 | if (maybe_lhs_val) |lhs_val| { | 10174 | if (maybe_lhs_val) |lhs_val| { |
| 10176 | if (!lhs_val.isUndef()) { | 10175 | if (!lhs_val.isUndef()) { |
| 10177 | if (lhs_val.compareWithZero(.eq)) { | 10176 | if (try lhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) { |
| 10178 | return sema.addConstant(resolved_type, Value.zero); | 10177 | return sema.addConstant(resolved_type, Value.zero); |
| 10179 | } | 10178 | } |
| 10180 | } | 10179 | } |
| ... | @@ -10183,7 +10182,7 @@ fn analyzeArithmetic( | ... | @@ -10183,7 +10182,7 @@ fn analyzeArithmetic( |
| 10183 | if (rhs_val.isUndef()) { | 10182 | if (rhs_val.isUndef()) { |
| 10184 | return sema.failWithUseOfUndef(block, rhs_src); | 10183 | return sema.failWithUseOfUndef(block, rhs_src); |
| 10185 | } | 10184 | } |
| 10186 | if (rhs_val.compareWithZero(.eq)) { | 10185 | if (try rhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) { |
| 10187 | return sema.failWithDivideByZero(block, rhs_src); | 10186 | return sema.failWithDivideByZero(block, rhs_src); |
| 10188 | } | 10187 | } |
| 10189 | } | 10188 | } |
| ... | @@ -10191,7 +10190,7 @@ fn analyzeArithmetic( | ... | @@ -10191,7 +10190,7 @@ fn analyzeArithmetic( |
| 10191 | if (lhs_val.isUndef()) { | 10190 | if (lhs_val.isUndef()) { |
| 10192 | if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) { | 10191 | if (lhs_scalar_ty.isSignedInt() and rhs_scalar_ty.isSignedInt()) { |
| 10193 | if (maybe_rhs_val) |rhs_val| { | 10192 | if (maybe_rhs_val) |rhs_val| { |
| 10194 | if (rhs_val.compare(.neq, Value.negative_one, resolved_type, mod)) { | 10193 | if (try sema.compare(block, src, rhs_val, .neq, Value.negative_one, resolved_type)) { |
| 10195 | return sema.addConstUndef(resolved_type); | 10194 | return sema.addConstUndef(resolved_type); |
| 10196 | } | 10195 | } |
| 10197 | } | 10196 | } |
| ... | @@ -10236,7 +10235,7 @@ fn analyzeArithmetic( | ... | @@ -10236,7 +10235,7 @@ fn analyzeArithmetic( |
| 10236 | if (lhs_val.isUndef()) { | 10235 | if (lhs_val.isUndef()) { |
| 10237 | return sema.failWithUseOfUndef(block, rhs_src); | 10236 | return sema.failWithUseOfUndef(block, rhs_src); |
| 10238 | } else { | 10237 | } else { |
| 10239 | if (lhs_val.compareWithZero(.eq)) { | 10238 | if (try lhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) { |
| 10240 | return sema.addConstant(resolved_type, Value.zero); | 10239 | return sema.addConstant(resolved_type, Value.zero); |
| 10241 | } | 10240 | } |
| 10242 | } | 10241 | } |
| ... | @@ -10245,7 +10244,7 @@ fn analyzeArithmetic( | ... | @@ -10245,7 +10244,7 @@ fn analyzeArithmetic( |
| 10245 | if (rhs_val.isUndef()) { | 10244 | if (rhs_val.isUndef()) { |
| 10246 | return sema.failWithUseOfUndef(block, rhs_src); | 10245 | return sema.failWithUseOfUndef(block, rhs_src); |
| 10247 | } | 10246 | } |
| 10248 | if (rhs_val.compareWithZero(.eq)) { | 10247 | if (try rhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) { |
| 10249 | return sema.failWithDivideByZero(block, rhs_src); | 10248 | return sema.failWithDivideByZero(block, rhs_src); |
| 10250 | } | 10249 | } |
| 10251 | } | 10250 | } |
| ... | @@ -10278,10 +10277,10 @@ fn analyzeArithmetic( | ... | @@ -10278,10 +10277,10 @@ fn analyzeArithmetic( |
| 10278 | // For floats: either operand being undef makes the result undef. | 10277 | // For floats: either operand being undef makes the result undef. |
| 10279 | if (maybe_lhs_val) |lhs_val| { | 10278 | if (maybe_lhs_val) |lhs_val| { |
| 10280 | if (!lhs_val.isUndef()) { | 10279 | if (!lhs_val.isUndef()) { |
| 10281 | if (lhs_val.compareWithZero(.eq)) { | 10280 | if (try lhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) { |
| 10282 | return sema.addConstant(resolved_type, Value.zero); | 10281 | return sema.addConstant(resolved_type, Value.zero); |
| 10283 | } | 10282 | } |
| 10284 | if (lhs_val.compare(.eq, Value.one, resolved_type, mod)) { | 10283 | if (try sema.compare(block, src, lhs_val, .eq, Value.one, resolved_type)) { |
| 10285 | return casted_rhs; | 10284 | return casted_rhs; |
| 10286 | } | 10285 | } |
| 10287 | } | 10286 | } |
| ... | @@ -10294,10 +10293,10 @@ fn analyzeArithmetic( | ... | @@ -10294,10 +10293,10 @@ fn analyzeArithmetic( |
| 10294 | return sema.addConstUndef(resolved_type); | 10293 | return sema.addConstUndef(resolved_type); |
| 10295 | } | 10294 | } |
| 10296 | } | 10295 | } |
| 10297 | if (rhs_val.compareWithZero(.eq)) { | 10296 | if (try rhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) { |
| 10298 | return sema.addConstant(resolved_type, Value.zero); | 10297 | return sema.addConstant(resolved_type, Value.zero); |
| 10299 | } | 10298 | } |
| 10300 | if (rhs_val.compare(.eq, Value.one, resolved_type, mod)) { | 10299 | if (try sema.compare(block, src, rhs_val, .eq, Value.one, resolved_type)) { |
| 10301 | return casted_lhs; | 10300 | return casted_lhs; |
| 10302 | } | 10301 | } |
| 10303 | if (maybe_lhs_val) |lhs_val| { | 10302 | if (maybe_lhs_val) |lhs_val| { |
| ... | @@ -10310,7 +10309,7 @@ fn analyzeArithmetic( | ... | @@ -10310,7 +10309,7 @@ fn analyzeArithmetic( |
| 10310 | } | 10309 | } |
| 10311 | if (is_int) { | 10310 | if (is_int) { |
| 10312 | const product = try lhs_val.intMul(rhs_val, resolved_type, sema.arena, target); | 10311 | const product = try lhs_val.intMul(rhs_val, resolved_type, sema.arena, target); |
| 10313 | if (!product.intFitsInType(resolved_type, target)) { | 10312 | if (!(try sema.intFitsInType(block, src, product, resolved_type))) { |
| 10314 | return sema.failWithIntegerOverflow(block, src, resolved_type, product); | 10313 | return sema.failWithIntegerOverflow(block, src, resolved_type, product); |
| 10315 | } | 10314 | } |
| 10316 | return sema.addConstant(resolved_type, product); | 10315 | return sema.addConstant(resolved_type, product); |
| ... | @@ -10330,10 +10329,10 @@ fn analyzeArithmetic( | ... | @@ -10330,10 +10329,10 @@ fn analyzeArithmetic( |
| 10330 | // If either of the operands are undefined, result is undefined. | 10329 | // If either of the operands are undefined, result is undefined. |
| 10331 | if (maybe_lhs_val) |lhs_val| { | 10330 | if (maybe_lhs_val) |lhs_val| { |
| 10332 | if (!lhs_val.isUndef()) { | 10331 | if (!lhs_val.isUndef()) { |
| 10333 | if (lhs_val.compareWithZero(.eq)) { | 10332 | if (try lhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) { |
| 10334 | return sema.addConstant(resolved_type, Value.zero); | 10333 | return sema.addConstant(resolved_type, Value.zero); |
| 10335 | } | 10334 | } |
| 10336 | if (lhs_val.compare(.eq, Value.one, resolved_type, mod)) { | 10335 | if (try sema.compare(block, src, lhs_val, .eq, Value.one, resolved_type)) { |
| 10337 | return casted_rhs; | 10336 | return casted_rhs; |
| 10338 | } | 10337 | } |
| 10339 | } | 10338 | } |
| ... | @@ -10342,10 +10341,10 @@ fn analyzeArithmetic( | ... | @@ -10342,10 +10341,10 @@ fn analyzeArithmetic( |
| 10342 | if (rhs_val.isUndef()) { | 10341 | if (rhs_val.isUndef()) { |
| 10343 | return sema.addConstUndef(resolved_type); | 10342 | return sema.addConstUndef(resolved_type); |
| 10344 | } | 10343 | } |
| 10345 | if (rhs_val.compareWithZero(.eq)) { | 10344 | if (try rhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) { |
| 10346 | return sema.addConstant(resolved_type, Value.zero); | 10345 | return sema.addConstant(resolved_type, Value.zero); |
| 10347 | } | 10346 | } |
| 10348 | if (rhs_val.compare(.eq, Value.one, resolved_type, mod)) { | 10347 | if (try sema.compare(block, src, rhs_val, .eq, Value.one, resolved_type)) { |
| 10349 | return casted_lhs; | 10348 | return casted_lhs; |
| 10350 | } | 10349 | } |
| 10351 | if (maybe_lhs_val) |lhs_val| { | 10350 | if (maybe_lhs_val) |lhs_val| { |
| ... | @@ -10366,10 +10365,10 @@ fn analyzeArithmetic( | ... | @@ -10366,10 +10365,10 @@ fn analyzeArithmetic( |
| 10366 | // If either of the operands are undefined, result is undefined. | 10365 | // If either of the operands are undefined, result is undefined. |
| 10367 | if (maybe_lhs_val) |lhs_val| { | 10366 | if (maybe_lhs_val) |lhs_val| { |
| 10368 | if (!lhs_val.isUndef()) { | 10367 | if (!lhs_val.isUndef()) { |
| 10369 | if (lhs_val.compareWithZero(.eq)) { | 10368 | if (try lhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) { |
| 10370 | return sema.addConstant(resolved_type, Value.zero); | 10369 | return sema.addConstant(resolved_type, Value.zero); |
| 10371 | } | 10370 | } |
| 10372 | if (lhs_val.compare(.eq, Value.one, resolved_type, mod)) { | 10371 | if (try sema.compare(block, src, lhs_val, .eq, Value.one, resolved_type)) { |
| 10373 | return casted_rhs; | 10372 | return casted_rhs; |
| 10374 | } | 10373 | } |
| 10375 | } | 10374 | } |
| ... | @@ -10378,10 +10377,10 @@ fn analyzeArithmetic( | ... | @@ -10378,10 +10377,10 @@ fn analyzeArithmetic( |
| 10378 | if (rhs_val.isUndef()) { | 10377 | if (rhs_val.isUndef()) { |
| 10379 | return sema.addConstUndef(resolved_type); | 10378 | return sema.addConstUndef(resolved_type); |
| 10380 | } | 10379 | } |
| 10381 | if (rhs_val.compareWithZero(.eq)) { | 10380 | if (try rhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) { |
| 10382 | return sema.addConstant(resolved_type, Value.zero); | 10381 | return sema.addConstant(resolved_type, Value.zero); |
| 10383 | } | 10382 | } |
| 10384 | if (rhs_val.compare(.eq, Value.one, resolved_type, mod)) { | 10383 | if (try sema.compare(block, src, rhs_val, .eq, Value.one, resolved_type)) { |
| 10385 | return casted_lhs; | 10384 | return casted_lhs; |
| 10386 | } | 10385 | } |
| 10387 | if (maybe_lhs_val) |lhs_val| { | 10386 | if (maybe_lhs_val) |lhs_val| { |
| ... | @@ -10417,7 +10416,7 @@ fn analyzeArithmetic( | ... | @@ -10417,7 +10416,7 @@ fn analyzeArithmetic( |
| 10417 | if (lhs_val.isUndef()) { | 10416 | if (lhs_val.isUndef()) { |
| 10418 | return sema.failWithUseOfUndef(block, lhs_src); | 10417 | return sema.failWithUseOfUndef(block, lhs_src); |
| 10419 | } | 10418 | } |
| 10420 | if (lhs_val.compareWithZero(.eq)) { | 10419 | if (try lhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) { |
| 10421 | return sema.addConstant(resolved_type, Value.zero); | 10420 | return sema.addConstant(resolved_type, Value.zero); |
| 10422 | } | 10421 | } |
| 10423 | } else if (lhs_scalar_ty.isSignedInt()) { | 10422 | } else if (lhs_scalar_ty.isSignedInt()) { |
| ... | @@ -10427,23 +10426,23 @@ fn analyzeArithmetic( | ... | @@ -10427,23 +10426,23 @@ fn analyzeArithmetic( |
| 10427 | if (rhs_val.isUndef()) { | 10426 | if (rhs_val.isUndef()) { |
| 10428 | return sema.failWithUseOfUndef(block, rhs_src); | 10427 | return sema.failWithUseOfUndef(block, rhs_src); |
| 10429 | } | 10428 | } |
| 10430 | if (rhs_val.compareWithZero(.eq)) { | 10429 | if (try rhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) { |
| 10431 | return sema.failWithDivideByZero(block, rhs_src); | 10430 | return sema.failWithDivideByZero(block, rhs_src); |
| 10432 | } | 10431 | } |
| 10433 | if (maybe_lhs_val) |lhs_val| { | 10432 | if (maybe_lhs_val) |lhs_val| { |
| 10434 | const rem_result = try lhs_val.intRem(rhs_val, resolved_type, sema.arena, target); | 10433 | const rem_result = try lhs_val.intRem(rhs_val, resolved_type, sema.arena, target); |
| 10435 | // If this answer could possibly be different by doing `intMod`, | 10434 | // If this answer could possibly be different by doing `intMod`, |
| 10436 | // we must emit a compile error. Otherwise, it's OK. | 10435 | // we must emit a compile error. Otherwise, it's OK. |
| 10437 | if (rhs_val.compareWithZero(.lt) != lhs_val.compareWithZero(.lt) and | 10436 | if ((try rhs_val.compareWithZeroAdvanced(.lt, sema.kit(block, src))) != (try lhs_val.compareWithZeroAdvanced(.lt, sema.kit(block, src))) and |
| 10438 | !rem_result.compareWithZero(.eq)) | 10437 | !(try rem_result.compareWithZeroAdvanced(.eq, sema.kit(block, src)))) |
| 10439 | { | 10438 | { |
| 10440 | const bad_src = if (lhs_val.compareWithZero(.lt)) | 10439 | const bad_src = if (try lhs_val.compareWithZeroAdvanced(.lt, sema.kit(block, src))) |
| 10441 | lhs_src | 10440 | lhs_src |
| 10442 | else | 10441 | else |
| 10443 | rhs_src; | 10442 | rhs_src; |
| 10444 | return sema.failWithModRemNegative(block, bad_src, lhs_ty, rhs_ty); | 10443 | return sema.failWithModRemNegative(block, bad_src, lhs_ty, rhs_ty); |
| 10445 | } | 10444 | } |
| 10446 | if (lhs_val.compareWithZero(.lt)) { | 10445 | if (try lhs_val.compareWithZeroAdvanced(.lt, sema.kit(block, src))) { |
| 10447 | // Negative | 10446 | // Negative |
| 10448 | return sema.addConstant(resolved_type, Value.zero); | 10447 | return sema.addConstant(resolved_type, Value.zero); |
| 10449 | } | 10448 | } |
| ... | @@ -10461,14 +10460,14 @@ fn analyzeArithmetic( | ... | @@ -10461,14 +10460,14 @@ fn analyzeArithmetic( |
| 10461 | if (rhs_val.isUndef()) { | 10460 | if (rhs_val.isUndef()) { |
| 10462 | return sema.failWithUseOfUndef(block, rhs_src); | 10461 | return sema.failWithUseOfUndef(block, rhs_src); |
| 10463 | } | 10462 | } |
| 10464 | if (rhs_val.compareWithZero(.eq)) { | 10463 | if (try rhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) { |
| 10465 | return sema.failWithDivideByZero(block, rhs_src); | 10464 | return sema.failWithDivideByZero(block, rhs_src); |
| 10466 | } | 10465 | } |
| 10467 | if (rhs_val.compareWithZero(.lt)) { | 10466 | if (try rhs_val.compareWithZeroAdvanced(.lt, sema.kit(block, src))) { |
| 10468 | return sema.failWithModRemNegative(block, rhs_src, lhs_ty, rhs_ty); | 10467 | return sema.failWithModRemNegative(block, rhs_src, lhs_ty, rhs_ty); |
| 10469 | } | 10468 | } |
| 10470 | if (maybe_lhs_val) |lhs_val| { | 10469 | if (maybe_lhs_val) |lhs_val| { |
| 10471 | if (lhs_val.isUndef() or lhs_val.compareWithZero(.lt)) { | 10470 | if (lhs_val.isUndef() or (try lhs_val.compareWithZeroAdvanced(.lt, sema.kit(block, src)))) { |
| 10472 | return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty); | 10471 | return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty); |
| 10473 | } | 10472 | } |
| 10474 | return sema.addConstant( | 10473 | return sema.addConstant( |
| ... | @@ -10504,7 +10503,7 @@ fn analyzeArithmetic( | ... | @@ -10504,7 +10503,7 @@ fn analyzeArithmetic( |
| 10504 | if (rhs_val.isUndef()) { | 10503 | if (rhs_val.isUndef()) { |
| 10505 | return sema.failWithUseOfUndef(block, rhs_src); | 10504 | return sema.failWithUseOfUndef(block, rhs_src); |
| 10506 | } | 10505 | } |
| 10507 | if (rhs_val.compareWithZero(.eq)) { | 10506 | if (try rhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) { |
| 10508 | return sema.failWithDivideByZero(block, rhs_src); | 10507 | return sema.failWithDivideByZero(block, rhs_src); |
| 10509 | } | 10508 | } |
| 10510 | if (maybe_lhs_val) |lhs_val| { | 10509 | if (maybe_lhs_val) |lhs_val| { |
| ... | @@ -10523,7 +10522,7 @@ fn analyzeArithmetic( | ... | @@ -10523,7 +10522,7 @@ fn analyzeArithmetic( |
| 10523 | if (rhs_val.isUndef()) { | 10522 | if (rhs_val.isUndef()) { |
| 10524 | return sema.failWithUseOfUndef(block, rhs_src); | 10523 | return sema.failWithUseOfUndef(block, rhs_src); |
| 10525 | } | 10524 | } |
| 10526 | if (rhs_val.compareWithZero(.eq)) { | 10525 | if (try rhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) { |
| 10527 | return sema.failWithDivideByZero(block, rhs_src); | 10526 | return sema.failWithDivideByZero(block, rhs_src); |
| 10528 | } | 10527 | } |
| 10529 | } | 10528 | } |
| ... | @@ -10561,7 +10560,7 @@ fn analyzeArithmetic( | ... | @@ -10561,7 +10560,7 @@ fn analyzeArithmetic( |
| 10561 | if (rhs_val.isUndef()) { | 10560 | if (rhs_val.isUndef()) { |
| 10562 | return sema.failWithUseOfUndef(block, rhs_src); | 10561 | return sema.failWithUseOfUndef(block, rhs_src); |
| 10563 | } | 10562 | } |
| 10564 | if (rhs_val.compareWithZero(.eq)) { | 10563 | if (try rhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) { |
| 10565 | return sema.failWithDivideByZero(block, rhs_src); | 10564 | return sema.failWithDivideByZero(block, rhs_src); |
| 10566 | } | 10565 | } |
| 10567 | if (maybe_lhs_val) |lhs_val| { | 10566 | if (maybe_lhs_val) |lhs_val| { |
| ... | @@ -10580,7 +10579,7 @@ fn analyzeArithmetic( | ... | @@ -10580,7 +10579,7 @@ fn analyzeArithmetic( |
| 10580 | if (rhs_val.isUndef()) { | 10579 | if (rhs_val.isUndef()) { |
| 10581 | return sema.failWithUseOfUndef(block, rhs_src); | 10580 | return sema.failWithUseOfUndef(block, rhs_src); |
| 10582 | } | 10581 | } |
| 10583 | if (rhs_val.compareWithZero(.eq)) { | 10582 | if (try rhs_val.compareWithZeroAdvanced(.eq, sema.kit(block, src))) { |
| 10584 | return sema.failWithDivideByZero(block, rhs_src); | 10583 | return sema.failWithDivideByZero(block, rhs_src); |
| 10585 | } | 10584 | } |
| 10586 | } | 10585 | } |
| ... | @@ -11095,11 +11094,11 @@ fn cmpSelf( | ... | @@ -11095,11 +11094,11 @@ fn cmpSelf( |
| 11095 | | 11094 | |
| 11096 | if (resolved_type.zigTypeTag() == .Vector) { | 11095 | if (resolved_type.zigTypeTag() == .Vector) { |
| 11097 | const result_ty = try Type.vector(sema.arena, resolved_type.vectorLen(), Type.@"bool"); | 11096 | const result_ty = try Type.vector(sema.arena, resolved_type.vectorLen(), Type.@"bool"); |
| 11098 | const cmp_val = try lhs_val.compareVector(op, rhs_val, resolved_type, sema.arena, sema.mod); | 11097 | const cmp_val = try sema.compareVector(block, lhs_src, lhs_val, op, rhs_val, resolved_type); |
| 11099 | return sema.addConstant(result_ty, cmp_val); | 11098 | return sema.addConstant(result_ty, cmp_val); |
| 11100 | } | 11099 | } |
| 11101 | | 11100 | |
| 11102 | if (lhs_val.compare(op, rhs_val, resolved_type, sema.mod)) { | 11101 | if (try sema.compare(block, lhs_src, lhs_val, op, rhs_val, resolved_type)) { |
| 11103 | return Air.Inst.Ref.bool_true; | 11102 | return Air.Inst.Ref.bool_true; |
| 11104 | } else { | 11103 | } else { |
| 11105 | return Air.Inst.Ref.bool_false; | 11104 | return Air.Inst.Ref.bool_false; |
| ... | @@ -11157,24 +11156,22 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -11157,24 +11156,22 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 11157 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; | 11156 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 11158 | const src = inst_data.src(); | 11157 | const src = inst_data.src(); |
| 11159 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; | 11158 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 11160 | const operand_ty = try sema.resolveType(block, operand_src, inst_data.operand); | 11159 | const ty = try sema.resolveType(block, operand_src, inst_data.operand); |
| 11161 | try sema.resolveTypeLayout(block, src, operand_ty); | 11160 | switch (ty.zigTypeTag()) { |
| 11162 | const target = sema.mod.getTarget(); | | |
| 11163 | const abi_size = switch (operand_ty.zigTypeTag()) { | | |
| 11164 | .Fn => unreachable, | 11161 | .Fn => unreachable, |
| 11165 | .NoReturn, | 11162 | .NoReturn, |
| 11166 | .Undefined, | 11163 | .Undefined, |
| 11167 | .Null, | 11164 | .Null, |
| 11168 | .BoundFn, | 11165 | .BoundFn, |
| 11169 | .Opaque, | 11166 | .Opaque, |
| 11170 | => return sema.fail(block, src, "no size available for type '{}'", .{operand_ty.fmt(sema.mod)}), | 11167 | => return sema.fail(block, src, "no size available for type '{}'", .{ty.fmt(sema.mod)}), |
| 11171 | | 11168 | |
| 11172 | .Type, | 11169 | .Type, |
| 11173 | .EnumLiteral, | 11170 | .EnumLiteral, |
| 11174 | .ComptimeFloat, | 11171 | .ComptimeFloat, |
| 11175 | .ComptimeInt, | 11172 | .ComptimeInt, |
| 11176 | .Void, | 11173 | .Void, |
| 11177 | => 0, | 11174 | => return sema.addIntUnsigned(Type.comptime_int, 0), |
| 11178 | | 11175 | |
| 11179 | .Bool, | 11176 | .Bool, |
| 11180 | .Int, | 11177 | .Int, |
| ... | @@ -11190,9 +11187,14 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -11190,9 +11187,14 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 11190 | .Vector, | 11187 | .Vector, |
| 11191 | .Frame, | 11188 | .Frame, |
| 11192 | .AnyFrame, | 11189 | .AnyFrame, |
| 11193 | => operand_ty.abiSize(target), | 11190 | => {}, |
| 11194 | }; | 11191 | } |
| 11195 | return sema.addIntUnsigned(Type.comptime_int, abi_size); | 11192 | const target = sema.mod.getTarget(); |
| | 11193 | const val = try ty.lazyAbiSize(target, sema.arena); |
| | 11194 | if (val.tag() == .lazy_size) { |
| | 11195 | try sema.queueFullTypeResolution(ty); |
| | 11196 | } |
| | 11197 | return sema.addConstant(Type.comptime_int, val); |
| 11196 | } | 11198 | } |
| 11197 | | 11199 | |
| 11198 | fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 11200 | fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -11202,7 +11204,7 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -11202,7 +11204,7 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 11202 | const operand_ty = try sema.resolveTypeFields(block, operand_src, unresolved_operand_ty); | 11204 | const operand_ty = try sema.resolveTypeFields(block, operand_src, unresolved_operand_ty); |
| 11203 | const target = sema.mod.getTarget(); | 11205 | const target = sema.mod.getTarget(); |
| 11204 | const bit_size = operand_ty.bitSize(target); | 11206 | const bit_size = operand_ty.bitSize(target); |
| 11205 | return sema.addIntUnsigned(Type.initTag(.comptime_int), bit_size); | 11207 | return sema.addIntUnsigned(Type.comptime_int, bit_size); |
| 11206 | } | 11208 | } |
| 11207 | | 11209 | |
| 11208 | fn zirThis( | 11210 | fn zirThis( |
| ... | @@ -13516,10 +13518,11 @@ fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -13516,10 +13518,11 @@ fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 13516 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; | 13518 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 13517 | const ty = try sema.resolveType(block, operand_src, inst_data.operand); | 13519 | const ty = try sema.resolveType(block, operand_src, inst_data.operand); |
| 13518 | const target = sema.mod.getTarget(); | 13520 | const target = sema.mod.getTarget(); |
| 13519 | return sema.addConstant( | 13521 | const val = try ty.lazyAbiAlignment(target, sema.arena); |
| 13520 | Type.comptime_int, | 13522 | if (val.tag() == .lazy_align) { |
| 13521 | try ty.lazyAbiAlignment(target, sema.arena), | 13523 | try sema.queueFullTypeResolution(ty); |
| 13522 | ); | 13524 | } |
| | 13525 | return sema.addConstant(Type.comptime_int, val); |
| 13523 | } | 13526 | } |
| 13524 | | 13527 | |
| 13525 | fn zirBoolToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 13528 | fn zirBoolToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -14362,16 +14365,7 @@ fn zirFloatToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -14362,16 +14365,7 @@ fn zirFloatToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 14362 | try sema.checkFloatType(block, operand_src, operand_ty); | 14365 | try sema.checkFloatType(block, operand_src, operand_ty); |
| 14363 | | 14366 | |
| 14364 | if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| { | 14367 | if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| { |
| 14365 | const target = sema.mod.getTarget(); | 14368 | const result_val = try sema.floatToInt(block, operand_src, val, operand_ty, dest_ty); |
| 14366 | const result_val = val.floatToInt(sema.arena, operand_ty, dest_ty, target) catch |err| switch (err) { | | |
| 14367 | error.FloatCannotFit => { | | |
| 14368 | return sema.fail(block, operand_src, "integer value {d} cannot be stored in type '{}'", .{ | | |
| 14369 | @floor(val.toFloat(f64)), | | |
| 14370 | dest_ty.fmt(sema.mod), | | |
| 14371 | }); | | |
| 14372 | }, | | |
| 14373 | else => |e| return e, | | |
| 14374 | }; | | |
| 14375 | return sema.addConstant(dest_ty, result_val); | 14369 | return sema.addConstant(dest_ty, result_val); |
| 14376 | } | 14370 | } |
| 14377 | | 14371 | |
| ... | @@ -15563,7 +15557,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -15563,7 +15557,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 15563 | .Xor => accum = try accum.bitwiseXor(elem_val, scalar_ty, sema.arena, target), | 15557 | .Xor => accum = try accum.bitwiseXor(elem_val, scalar_ty, sema.arena, target), |
| 15564 | .Min => accum = accum.numberMin(elem_val, target), | 15558 | .Min => accum = accum.numberMin(elem_val, target), |
| 15565 | .Max => accum = accum.numberMax(elem_val, target), | 15559 | .Max => accum = accum.numberMax(elem_val, target), |
| 15566 | .Add => accum = try accum.numberAddWrap(elem_val, scalar_ty, sema.arena, target), | 15560 | .Add => accum = try sema.numberAddWrap(block, operand_src, accum, elem_val, scalar_ty), |
| 15567 | .Mul => accum = try accum.numberMulWrap(elem_val, scalar_ty, sema.arena, target), | 15561 | .Mul => accum = try accum.numberMulWrap(elem_val, scalar_ty, sema.arena, target), |
| 15568 | } | 15562 | } |
| 15569 | } | 15563 | } |
| ... | @@ -15958,14 +15952,14 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -15958,14 +15952,14 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 15958 | const new_val = switch (op) { | 15952 | const new_val = switch (op) { |
| 15959 | // zig fmt: off | 15953 | // zig fmt: off |
| 15960 | .Xchg => operand_val, | 15954 | .Xchg => operand_val, |
| 15961 | .Add => try stored_val.numberAddWrap(operand_val, elem_ty, sema.arena, target), | 15955 | .Add => try sema.numberAddWrap(block, src, stored_val, operand_val, elem_ty), |
| 15962 | .Sub => try stored_val.numberSubWrap(operand_val, elem_ty, sema.arena, target), | 15956 | .Sub => try sema.numberSubWrap(block, src, stored_val, operand_val, elem_ty), |
| 15963 | .And => try stored_val.bitwiseAnd (operand_val, elem_ty, sema.arena, target), | 15957 | .And => try stored_val.bitwiseAnd (operand_val, elem_ty, sema.arena, target), |
| 15964 | .Nand => try stored_val.bitwiseNand (operand_val, elem_ty, sema.arena, target), | 15958 | .Nand => try stored_val.bitwiseNand (operand_val, elem_ty, sema.arena, target), |
| 15965 | .Or => try stored_val.bitwiseOr (operand_val, elem_ty, sema.arena, target), | 15959 | .Or => try stored_val.bitwiseOr (operand_val, elem_ty, sema.arena, target), |
| 15966 | .Xor => try stored_val.bitwiseXor (operand_val, elem_ty, sema.arena, target), | 15960 | .Xor => try stored_val.bitwiseXor (operand_val, elem_ty, sema.arena, target), |
| 15967 | .Max => stored_val.numberMax (operand_val, target), | 15961 | .Max => stored_val.numberMax (operand_val, target), |
| 15968 | .Min => stored_val.numberMin (operand_val, target), | 15962 | .Min => stored_val.numberMin (operand_val, target), |
| 15969 | // zig fmt: on | 15963 | // zig fmt: on |
| 15970 | }; | 15964 | }; |
| 15971 | try sema.storePtrVal(block, src, ptr_val, new_val, elem_ty); | 15965 | try sema.storePtrVal(block, src, ptr_val, new_val, elem_ty); |
| ... | @@ -18890,18 +18884,13 @@ fn coerce( | ... | @@ -18890,18 +18884,13 @@ fn coerce( |
| 18890 | .{ val.fmtValue(inst_ty, sema.mod), dest_ty.fmt(sema.mod) }, | 18884 | .{ val.fmtValue(inst_ty, sema.mod), dest_ty.fmt(sema.mod) }, |
| 18891 | ); | 18885 | ); |
| 18892 | } | 18886 | } |
| 18893 | const result_val = val.floatToInt(sema.arena, inst_ty, dest_ty, target) catch |err| switch (err) { | 18887 | const result_val = try sema.floatToInt(block, inst_src, val, inst_ty, dest_ty); |
| 18894 | error.FloatCannotFit => { | | |
| 18895 | return sema.fail(block, inst_src, "integer value {d} cannot be stored in type '{}'", .{ @floor(val.toFloat(f64)), dest_ty.fmt(sema.mod) }); | | |
| 18896 | }, | | |
| 18897 | else => |e| return e, | | |
| 18898 | }; | | |
| 18899 | return try sema.addConstant(dest_ty, result_val); | 18888 | return try sema.addConstant(dest_ty, result_val); |
| 18900 | }, | 18889 | }, |
| 18901 | .Int, .ComptimeInt => { | 18890 | .Int, .ComptimeInt => { |
| 18902 | if (try sema.resolveDefinedValue(block, inst_src, inst)) |val| { | 18891 | if (try sema.resolveDefinedValue(block, inst_src, inst)) |val| { |
| 18903 | // comptime known integer to other number | 18892 | // comptime known integer to other number |
| 18904 | if (!val.intFitsInType(dest_ty, target)) { | 18893 | if (!(try sema.intFitsInType(block, inst_src, val, dest_ty))) { |
| 18905 | return sema.fail(block, inst_src, "type {} cannot represent integer value {}", .{ dest_ty.fmt(sema.mod), val.fmtValue(inst_ty, sema.mod) }); | 18894 | return sema.fail(block, inst_src, "type {} cannot represent integer value {}", .{ dest_ty.fmt(sema.mod), val.fmtValue(inst_ty, sema.mod) }); |
| 18906 | } | 18895 | } |
| 18907 | return try sema.addConstant(dest_ty, val); | 18896 | return try sema.addConstant(dest_ty, val); |
| ... | @@ -21093,7 +21082,7 @@ fn analyzeSlice( | ... | @@ -21093,7 +21082,7 @@ fn analyzeSlice( |
| 21093 | sema.arena, | 21082 | sema.arena, |
| 21094 | array_ty.arrayLenIncludingSentinel(), | 21083 | array_ty.arrayLenIncludingSentinel(), |
| 21095 | ); | 21084 | ); |
| 21096 | if (end_val.compare(.gt, len_s_val, Type.usize, mod)) { | 21085 | if (try sema.compare(block, src, end_val, .gt, len_s_val, Type.usize)) { |
| 21097 | const sentinel_label: []const u8 = if (array_ty.sentinel() != null) | 21086 | const sentinel_label: []const u8 = if (array_ty.sentinel() != null) |
| 21098 | " +1 (sentinel)" | 21087 | " +1 (sentinel)" |
| 21099 | else | 21088 | else |
| ... | @@ -21133,7 +21122,7 @@ fn analyzeSlice( | ... | @@ -21133,7 +21122,7 @@ fn analyzeSlice( |
| 21133 | .data = slice_val.sliceLen(mod) + @boolToInt(has_sentinel), | 21122 | .data = slice_val.sliceLen(mod) + @boolToInt(has_sentinel), |
| 21134 | }; | 21123 | }; |
| 21135 | const slice_len_val = Value.initPayload(&int_payload.base); | 21124 | const slice_len_val = Value.initPayload(&int_payload.base); |
| 21136 | if (end_val.compare(.gt, slice_len_val, Type.usize, mod)) { | 21125 | if (try sema.compare(block, src, end_val, .gt, slice_len_val, Type.usize)) { |
| 21137 | const sentinel_label: []const u8 = if (has_sentinel) | 21126 | const sentinel_label: []const u8 = if (has_sentinel) |
| 21138 | " +1 (sentinel)" | 21127 | " +1 (sentinel)" |
| 21139 | else | 21128 | else |
| ... | @@ -21191,7 +21180,7 @@ fn analyzeSlice( | ... | @@ -21191,7 +21180,7 @@ fn analyzeSlice( |
| 21191 | // requirement: start <= end | 21180 | // requirement: start <= end |
| 21192 | if (try sema.resolveDefinedValue(block, src, end)) |end_val| { | 21181 | if (try sema.resolveDefinedValue(block, src, end)) |end_val| { |
| 21193 | if (try sema.resolveDefinedValue(block, src, start)) |start_val| { | 21182 | if (try sema.resolveDefinedValue(block, src, start)) |start_val| { |
| 21194 | if (start_val.compare(.gt, end_val, Type.usize, mod)) { | 21183 | if (try sema.compare(block, src, start_val, .gt, end_val, Type.usize)) { |
| 21195 | return sema.fail( | 21184 | return sema.fail( |
| 21196 | block, | 21185 | block, |
| 21197 | start_src, | 21186 | start_src, |
| ... | @@ -21399,11 +21388,11 @@ fn cmpNumeric( | ... | @@ -21399,11 +21388,11 @@ fn cmpNumeric( |
| 21399 | // a signed integer with mantissa bits + 1, and if there was any non-integral part of the float, | 21388 | // a signed integer with mantissa bits + 1, and if there was any non-integral part of the float, |
| 21400 | // add/subtract 1. | 21389 | // add/subtract 1. |
| 21401 | const lhs_is_signed = if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val| | 21390 | const lhs_is_signed = if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val| |
| 21402 | lhs_val.compareWithZero(.lt) | 21391 | (try lhs_val.compareWithZeroAdvanced(.lt, sema.kit(block, src))) |
| 21403 | else | 21392 | else |
| 21404 | (lhs_ty.isRuntimeFloat() or lhs_ty.isSignedInt()); | 21393 | (lhs_ty.isRuntimeFloat() or lhs_ty.isSignedInt()); |
| 21405 | const rhs_is_signed = if (try sema.resolveDefinedValue(block, rhs_src, rhs)) |rhs_val| | 21394 | const rhs_is_signed = if (try sema.resolveDefinedValue(block, rhs_src, rhs)) |rhs_val| |
| 21406 | rhs_val.compareWithZero(.lt) | 21395 | (try rhs_val.compareWithZeroAdvanced(.lt, sema.kit(block, src))) |
| 21407 | else | 21396 | else |
| 21408 | (rhs_ty.isRuntimeFloat() or rhs_ty.isSignedInt()); | 21397 | (rhs_ty.isRuntimeFloat() or rhs_ty.isSignedInt()); |
| 21409 | const dest_int_is_signed = lhs_is_signed or rhs_is_signed; | 21398 | const dest_int_is_signed = lhs_is_signed or rhs_is_signed; |
| ... | @@ -21541,7 +21530,7 @@ fn cmpVector( | ... | @@ -21541,7 +21530,7 @@ fn cmpVector( |
| 21541 | if (lhs_val.isUndef() or rhs_val.isUndef()) { | 21530 | if (lhs_val.isUndef() or rhs_val.isUndef()) { |
| 21542 | return sema.addConstUndef(result_ty); | 21531 | return sema.addConstUndef(result_ty); |
| 21543 | } | 21532 | } |
| 21544 | const cmp_val = try lhs_val.compareVector(op, rhs_val, lhs_ty, sema.arena, sema.mod); | 21533 | const cmp_val = try sema.compareVector(block, src, lhs_val, op, rhs_val, lhs_ty); |
| 21545 | return sema.addConstant(result_ty, cmp_val); | 21534 | return sema.addConstant(result_ty, cmp_val); |
| 21546 | } else { | 21535 | } else { |
| 21547 | break :src rhs_src; | 21536 | break :src rhs_src; |
| ... | @@ -22904,8 +22893,6 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil | ... | @@ -22904,8 +22893,6 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil |
| 22904 | enum_field_names = &union_obj.tag_ty.castTag(.enum_simple).?.data.fields; | 22893 | enum_field_names = &union_obj.tag_ty.castTag(.enum_simple).?.data.fields; |
| 22905 | } | 22894 | } |
| 22906 | | 22895 | |
| 22907 | const target = sema.mod.getTarget(); | | |
| 22908 | | | |
| 22909 | const bits_per_field = 4; | 22896 | const bits_per_field = 4; |
| 22910 | const fields_per_u32 = 32 / bits_per_field; | 22897 | const fields_per_u32 = 32 / bits_per_field; |
| 22911 | const bit_bags_count = std.math.divCeil(usize, fields_len, fields_per_u32) catch unreachable; | 22898 | const bit_bags_count = std.math.divCeil(usize, fields_len, fields_per_u32) catch unreachable; |
| ... | @@ -22969,7 +22956,7 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil | ... | @@ -22969,7 +22956,7 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil |
| 22969 | }); | 22956 | }); |
| 22970 | } else { | 22957 | } else { |
| 22971 | const val = if (last_tag_val) |val| | 22958 | const val = if (last_tag_val) |val| |
| 22972 | try val.intAdd(Value.one, int_tag_ty, sema.arena, target) | 22959 | try sema.intAdd(block, src, val, Value.one, int_tag_ty) |
| 22973 | else | 22960 | else |
| 22974 | Value.zero; | 22961 | Value.zero; |
| 22975 | last_tag_val = val; | 22962 | last_tag_val = val; |
| ... | @@ -24119,3 +24106,707 @@ fn queueFullTypeResolution(sema: *Sema, ty: Type) !void { | ... | @@ -24119,3 +24106,707 @@ fn queueFullTypeResolution(sema: *Sema, ty: Type) !void { |
| 24119 | const inst_ref = try sema.addType(ty); | 24106 | const inst_ref = try sema.addType(ty); |
| 24120 | try sema.types_to_resolve.append(sema.gpa, inst_ref); | 24107 | try sema.types_to_resolve.append(sema.gpa, inst_ref); |
| 24121 | } | 24108 | } |
| | 24109 | |
| | 24110 | fn intAdd(sema: *Sema, block: *Block, src: LazySrcLoc, lhs: Value, rhs: Value, ty: Type) !Value { |
| | 24111 | if (ty.zigTypeTag() == .Vector) { |
| | 24112 | const result_data = try sema.arena.alloc(Value, ty.vectorLen()); |
| | 24113 | for (result_data) |*scalar, i| { |
| | 24114 | scalar.* = try sema.intAddScalar(block, src, lhs.indexVectorlike(i), rhs.indexVectorlike(i)); |
| | 24115 | } |
| | 24116 | return Value.Tag.aggregate.create(sema.arena, result_data); |
| | 24117 | } |
| | 24118 | return sema.intAddScalar(block, src, lhs, rhs); |
| | 24119 | } |
| | 24120 | |
| | 24121 | fn intAddScalar(sema: *Sema, block: *Block, src: LazySrcLoc, lhs: Value, rhs: Value) !Value { |
| | 24122 | // TODO is this a performance issue? maybe we should try the operation without |
| | 24123 | // resorting to BigInt first. |
| | 24124 | var lhs_space: Value.BigIntSpace = undefined; |
| | 24125 | var rhs_space: Value.BigIntSpace = undefined; |
| | 24126 | const target = sema.mod.getTarget(); |
| | 24127 | const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, target, sema.kit(block, src)); |
| | 24128 | const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, target, sema.kit(block, src)); |
| | 24129 | const limbs = try sema.arena.alloc( |
| | 24130 | std.math.big.Limb, |
| | 24131 | std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1, |
| | 24132 | ); |
| | 24133 | var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined }; |
| | 24134 | result_bigint.add(lhs_bigint, rhs_bigint); |
| | 24135 | return Value.fromBigInt(sema.arena, result_bigint.toConst()); |
| | 24136 | } |
| | 24137 | |
| | 24138 | /// Supports both (vectors of) floats and ints; handles undefined scalars. |
| | 24139 | fn numberAddWrap( |
| | 24140 | sema: *Sema, |
| | 24141 | block: *Block, |
| | 24142 | src: LazySrcLoc, |
| | 24143 | lhs: Value, |
| | 24144 | rhs: Value, |
| | 24145 | ty: Type, |
| | 24146 | ) !Value { |
| | 24147 | if (ty.zigTypeTag() == .Vector) { |
| | 24148 | const result_data = try sema.arena.alloc(Value, ty.vectorLen()); |
| | 24149 | for (result_data) |*scalar, i| { |
| | 24150 | scalar.* = try sema.numberAddWrapScalar(block, src, lhs.indexVectorlike(i), rhs.indexVectorlike(i), ty.scalarType()); |
| | 24151 | } |
| | 24152 | return Value.Tag.aggregate.create(sema.arena, result_data); |
| | 24153 | } |
| | 24154 | return sema.numberAddWrapScalar(block, src, lhs, rhs, ty); |
| | 24155 | } |
| | 24156 | |
| | 24157 | /// Supports both floats and ints; handles undefined. |
| | 24158 | fn numberAddWrapScalar( |
| | 24159 | sema: *Sema, |
| | 24160 | block: *Block, |
| | 24161 | src: LazySrcLoc, |
| | 24162 | lhs: Value, |
| | 24163 | rhs: Value, |
| | 24164 | ty: Type, |
| | 24165 | ) !Value { |
| | 24166 | if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef); |
| | 24167 | |
| | 24168 | if (ty.zigTypeTag() == .ComptimeInt) { |
| | 24169 | return sema.intAdd(block, src, lhs, rhs, ty); |
| | 24170 | } |
| | 24171 | |
| | 24172 | if (ty.isAnyFloat()) { |
| | 24173 | return sema.floatAdd(lhs, rhs, ty); |
| | 24174 | } |
| | 24175 | |
| | 24176 | const overflow_result = try sema.intAddWithOverflow(block, src, lhs, rhs, ty); |
| | 24177 | return overflow_result.wrapped_result; |
| | 24178 | } |
| | 24179 | |
| | 24180 | fn intSub( |
| | 24181 | sema: *Sema, |
| | 24182 | block: *Block, |
| | 24183 | src: LazySrcLoc, |
| | 24184 | lhs: Value, |
| | 24185 | rhs: Value, |
| | 24186 | ty: Type, |
| | 24187 | ) !Value { |
| | 24188 | if (ty.zigTypeTag() == .Vector) { |
| | 24189 | const result_data = try sema.arena.alloc(Value, ty.vectorLen()); |
| | 24190 | for (result_data) |*scalar, i| { |
| | 24191 | scalar.* = try sema.intSubScalar(block, src, lhs.indexVectorlike(i), rhs.indexVectorlike(i)); |
| | 24192 | } |
| | 24193 | return Value.Tag.aggregate.create(sema.arena, result_data); |
| | 24194 | } |
| | 24195 | return sema.intSubScalar(block, src, lhs, rhs); |
| | 24196 | } |
| | 24197 | |
| | 24198 | fn intSubScalar(sema: *Sema, block: *Block, src: LazySrcLoc, lhs: Value, rhs: Value) !Value { |
| | 24199 | // TODO is this a performance issue? maybe we should try the operation without |
| | 24200 | // resorting to BigInt first. |
| | 24201 | var lhs_space: Value.BigIntSpace = undefined; |
| | 24202 | var rhs_space: Value.BigIntSpace = undefined; |
| | 24203 | const target = sema.mod.getTarget(); |
| | 24204 | const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, target, sema.kit(block, src)); |
| | 24205 | const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, target, sema.kit(block, src)); |
| | 24206 | const limbs = try sema.arena.alloc( |
| | 24207 | std.math.big.Limb, |
| | 24208 | std.math.max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1, |
| | 24209 | ); |
| | 24210 | var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined }; |
| | 24211 | result_bigint.sub(lhs_bigint, rhs_bigint); |
| | 24212 | return Value.fromBigInt(sema.arena, result_bigint.toConst()); |
| | 24213 | } |
| | 24214 | |
| | 24215 | /// Supports both (vectors of) floats and ints; handles undefined scalars. |
| | 24216 | fn numberSubWrap( |
| | 24217 | sema: *Sema, |
| | 24218 | block: *Block, |
| | 24219 | src: LazySrcLoc, |
| | 24220 | lhs: Value, |
| | 24221 | rhs: Value, |
| | 24222 | ty: Type, |
| | 24223 | ) !Value { |
| | 24224 | if (ty.zigTypeTag() == .Vector) { |
| | 24225 | const result_data = try sema.arena.alloc(Value, ty.vectorLen()); |
| | 24226 | for (result_data) |*scalar, i| { |
| | 24227 | scalar.* = try sema.numberSubWrapScalar(block, src, lhs.indexVectorlike(i), rhs.indexVectorlike(i), ty.scalarType()); |
| | 24228 | } |
| | 24229 | return Value.Tag.aggregate.create(sema.arena, result_data); |
| | 24230 | } |
| | 24231 | return sema.numberSubWrapScalar(block, src, lhs, rhs, ty); |
| | 24232 | } |
| | 24233 | |
| | 24234 | /// Supports both floats and ints; handles undefined. |
| | 24235 | fn numberSubWrapScalar( |
| | 24236 | sema: *Sema, |
| | 24237 | block: *Block, |
| | 24238 | src: LazySrcLoc, |
| | 24239 | lhs: Value, |
| | 24240 | rhs: Value, |
| | 24241 | ty: Type, |
| | 24242 | ) !Value { |
| | 24243 | if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef); |
| | 24244 | |
| | 24245 | if (ty.zigTypeTag() == .ComptimeInt) { |
| | 24246 | return sema.intSub(block, src, lhs, rhs, ty); |
| | 24247 | } |
| | 24248 | |
| | 24249 | if (ty.isAnyFloat()) { |
| | 24250 | return sema.floatSub(lhs, rhs, ty); |
| | 24251 | } |
| | 24252 | |
| | 24253 | const overflow_result = try sema.intSubWithOverflow(block, src, lhs, rhs, ty); |
| | 24254 | return overflow_result.wrapped_result; |
| | 24255 | } |
| | 24256 | |
| | 24257 | fn floatAdd( |
| | 24258 | sema: *Sema, |
| | 24259 | lhs: Value, |
| | 24260 | rhs: Value, |
| | 24261 | float_type: Type, |
| | 24262 | ) !Value { |
| | 24263 | if (float_type.zigTypeTag() == .Vector) { |
| | 24264 | const result_data = try sema.arena.alloc(Value, float_type.vectorLen()); |
| | 24265 | for (result_data) |*scalar, i| { |
| | 24266 | scalar.* = try sema.floatAddScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), float_type.scalarType()); |
| | 24267 | } |
| | 24268 | return Value.Tag.aggregate.create(sema.arena, result_data); |
| | 24269 | } |
| | 24270 | return sema.floatAddScalar(lhs, rhs, float_type); |
| | 24271 | } |
| | 24272 | |
| | 24273 | fn floatAddScalar( |
| | 24274 | sema: *Sema, |
| | 24275 | lhs: Value, |
| | 24276 | rhs: Value, |
| | 24277 | float_type: Type, |
| | 24278 | ) !Value { |
| | 24279 | const target = sema.mod.getTarget(); |
| | 24280 | switch (float_type.floatBits(target)) { |
| | 24281 | 16 => { |
| | 24282 | const lhs_val = lhs.toFloat(f16); |
| | 24283 | const rhs_val = rhs.toFloat(f16); |
| | 24284 | return Value.Tag.float_16.create(sema.arena, lhs_val + rhs_val); |
| | 24285 | }, |
| | 24286 | 32 => { |
| | 24287 | const lhs_val = lhs.toFloat(f32); |
| | 24288 | const rhs_val = rhs.toFloat(f32); |
| | 24289 | return Value.Tag.float_32.create(sema.arena, lhs_val + rhs_val); |
| | 24290 | }, |
| | 24291 | 64 => { |
| | 24292 | const lhs_val = lhs.toFloat(f64); |
| | 24293 | const rhs_val = rhs.toFloat(f64); |
| | 24294 | return Value.Tag.float_64.create(sema.arena, lhs_val + rhs_val); |
| | 24295 | }, |
| | 24296 | 80 => { |
| | 24297 | const lhs_val = lhs.toFloat(f80); |
| | 24298 | const rhs_val = rhs.toFloat(f80); |
| | 24299 | return Value.Tag.float_80.create(sema.arena, lhs_val + rhs_val); |
| | 24300 | }, |
| | 24301 | 128 => { |
| | 24302 | const lhs_val = lhs.toFloat(f128); |
| | 24303 | const rhs_val = rhs.toFloat(f128); |
| | 24304 | return Value.Tag.float_128.create(sema.arena, lhs_val + rhs_val); |
| | 24305 | }, |
| | 24306 | else => unreachable, |
| | 24307 | } |
| | 24308 | } |
| | 24309 | |
| | 24310 | fn floatSub( |
| | 24311 | sema: *Sema, |
| | 24312 | lhs: Value, |
| | 24313 | rhs: Value, |
| | 24314 | float_type: Type, |
| | 24315 | ) !Value { |
| | 24316 | if (float_type.zigTypeTag() == .Vector) { |
| | 24317 | const result_data = try sema.arena.alloc(Value, float_type.vectorLen()); |
| | 24318 | for (result_data) |*scalar, i| { |
| | 24319 | scalar.* = try sema.floatSubScalar(lhs.indexVectorlike(i), rhs.indexVectorlike(i), float_type.scalarType()); |
| | 24320 | } |
| | 24321 | return Value.Tag.aggregate.create(sema.arena, result_data); |
| | 24322 | } |
| | 24323 | return sema.floatSubScalar(lhs, rhs, float_type); |
| | 24324 | } |
| | 24325 | |
| | 24326 | fn floatSubScalar( |
| | 24327 | sema: *Sema, |
| | 24328 | lhs: Value, |
| | 24329 | rhs: Value, |
| | 24330 | float_type: Type, |
| | 24331 | ) !Value { |
| | 24332 | const target = sema.mod.getTarget(); |
| | 24333 | switch (float_type.floatBits(target)) { |
| | 24334 | 16 => { |
| | 24335 | const lhs_val = lhs.toFloat(f16); |
| | 24336 | const rhs_val = rhs.toFloat(f16); |
| | 24337 | return Value.Tag.float_16.create(sema.arena, lhs_val - rhs_val); |
| | 24338 | }, |
| | 24339 | 32 => { |
| | 24340 | const lhs_val = lhs.toFloat(f32); |
| | 24341 | const rhs_val = rhs.toFloat(f32); |
| | 24342 | return Value.Tag.float_32.create(sema.arena, lhs_val - rhs_val); |
| | 24343 | }, |
| | 24344 | 64 => { |
| | 24345 | const lhs_val = lhs.toFloat(f64); |
| | 24346 | const rhs_val = rhs.toFloat(f64); |
| | 24347 | return Value.Tag.float_64.create(sema.arena, lhs_val - rhs_val); |
| | 24348 | }, |
| | 24349 | 80 => { |
| | 24350 | const lhs_val = lhs.toFloat(f80); |
| | 24351 | const rhs_val = rhs.toFloat(f80); |
| | 24352 | return Value.Tag.float_80.create(sema.arena, lhs_val - rhs_val); |
| | 24353 | }, |
| | 24354 | 128 => { |
| | 24355 | const lhs_val = lhs.toFloat(f128); |
| | 24356 | const rhs_val = rhs.toFloat(f128); |
| | 24357 | return Value.Tag.float_128.create(sema.arena, lhs_val - rhs_val); |
| | 24358 | }, |
| | 24359 | else => unreachable, |
| | 24360 | } |
| | 24361 | } |
| | 24362 | |
| | 24363 | fn intSubWithOverflow( |
| | 24364 | sema: *Sema, |
| | 24365 | block: *Block, |
| | 24366 | src: LazySrcLoc, |
| | 24367 | lhs: Value, |
| | 24368 | rhs: Value, |
| | 24369 | ty: Type, |
| | 24370 | ) !Value.OverflowArithmeticResult { |
| | 24371 | if (ty.zigTypeTag() == .Vector) { |
| | 24372 | const overflowed_data = try sema.arena.alloc(Value, ty.vectorLen()); |
| | 24373 | const result_data = try sema.arena.alloc(Value, ty.vectorLen()); |
| | 24374 | for (result_data) |*scalar, i| { |
| | 24375 | const of_math_result = try sema.intSubWithOverflowScalar(block, src, lhs.indexVectorlike(i), rhs.indexVectorlike(i), ty.scalarType()); |
| | 24376 | overflowed_data[i] = of_math_result.overflowed; |
| | 24377 | scalar.* = of_math_result.wrapped_result; |
| | 24378 | } |
| | 24379 | return Value.OverflowArithmeticResult{ |
| | 24380 | .overflowed = try Value.Tag.aggregate.create(sema.arena, overflowed_data), |
| | 24381 | .wrapped_result = try Value.Tag.aggregate.create(sema.arena, result_data), |
| | 24382 | }; |
| | 24383 | } |
| | 24384 | return sema.intSubWithOverflowScalar(block, src, lhs, rhs, ty); |
| | 24385 | } |
| | 24386 | |
| | 24387 | fn intSubWithOverflowScalar( |
| | 24388 | sema: *Sema, |
| | 24389 | block: *Block, |
| | 24390 | src: LazySrcLoc, |
| | 24391 | lhs: Value, |
| | 24392 | rhs: Value, |
| | 24393 | ty: Type, |
| | 24394 | ) !Value.OverflowArithmeticResult { |
| | 24395 | const target = sema.mod.getTarget(); |
| | 24396 | const info = ty.intInfo(target); |
| | 24397 | |
| | 24398 | var lhs_space: Value.BigIntSpace = undefined; |
| | 24399 | var rhs_space: Value.BigIntSpace = undefined; |
| | 24400 | const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, target, sema.kit(block, src)); |
| | 24401 | const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, target, sema.kit(block, src)); |
| | 24402 | const limbs = try sema.arena.alloc( |
| | 24403 | std.math.big.Limb, |
| | 24404 | std.math.big.int.calcTwosCompLimbCount(info.bits), |
| | 24405 | ); |
| | 24406 | var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined }; |
| | 24407 | const overflowed = result_bigint.subWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits); |
| | 24408 | const wrapped_result = try Value.fromBigInt(sema.arena, result_bigint.toConst()); |
| | 24409 | return Value.OverflowArithmeticResult{ |
| | 24410 | .overflowed = Value.makeBool(overflowed), |
| | 24411 | .wrapped_result = wrapped_result, |
| | 24412 | }; |
| | 24413 | } |
| | 24414 | |
| | 24415 | fn floatToInt( |
| | 24416 | sema: *Sema, |
| | 24417 | block: *Block, |
| | 24418 | src: LazySrcLoc, |
| | 24419 | val: Value, |
| | 24420 | float_ty: Type, |
| | 24421 | int_ty: Type, |
| | 24422 | ) CompileError!Value { |
| | 24423 | if (float_ty.zigTypeTag() == .Vector) { |
| | 24424 | const elem_ty = float_ty.childType(); |
| | 24425 | const result_data = try sema.arena.alloc(Value, float_ty.vectorLen()); |
| | 24426 | for (result_data) |*scalar, i| { |
| | 24427 | scalar.* = try sema.floatToIntScalar(block, src, val.indexVectorlike(i), elem_ty, int_ty.scalarType()); |
| | 24428 | } |
| | 24429 | return Value.Tag.aggregate.create(sema.arena, result_data); |
| | 24430 | } |
| | 24431 | return sema.floatToIntScalar(block, src, val, float_ty, int_ty); |
| | 24432 | } |
| | 24433 | |
| | 24434 | fn floatToIntScalar( |
| | 24435 | sema: *Sema, |
| | 24436 | block: *Block, |
| | 24437 | src: LazySrcLoc, |
| | 24438 | val: Value, |
| | 24439 | float_ty: Type, |
| | 24440 | int_ty: Type, |
| | 24441 | ) CompileError!Value { |
| | 24442 | const Limb = std.math.big.Limb; |
| | 24443 | |
| | 24444 | const float = val.toFloat(f128); |
| | 24445 | if (std.math.isNan(float)) { |
| | 24446 | return sema.fail(block, src, "float value NaN cannot be stored in integer type '{}'", .{ |
| | 24447 | int_ty.fmt(sema.mod), |
| | 24448 | }); |
| | 24449 | } |
| | 24450 | if (std.math.isInf(float)) { |
| | 24451 | return sema.fail(block, src, "float value Inf cannot be stored in integer type '{}'", .{ |
| | 24452 | int_ty.fmt(sema.mod), |
| | 24453 | }); |
| | 24454 | } |
| | 24455 | |
| | 24456 | const is_negative = std.math.signbit(float); |
| | 24457 | const floored = @floor(@fabs(float)); |
| | 24458 | |
| | 24459 | var rational = try std.math.big.Rational.init(sema.arena); |
| | 24460 | defer rational.deinit(); |
| | 24461 | rational.setFloat(f128, floored) catch |err| switch (err) { |
| | 24462 | error.NonFiniteFloat => unreachable, |
| | 24463 | error.OutOfMemory => return error.OutOfMemory, |
| | 24464 | }; |
| | 24465 | |
| | 24466 | // The float is reduced in rational.setFloat, so we assert that denominator is equal to one |
| | 24467 | const big_one = std.math.big.int.Const{ .limbs = &.{1}, .positive = true }; |
| | 24468 | assert(rational.q.toConst().eqAbs(big_one)); |
| | 24469 | |
| | 24470 | const result_limbs = try sema.arena.dupe(Limb, rational.p.toConst().limbs); |
| | 24471 | const result = if (is_negative) |
| | 24472 | try Value.Tag.int_big_negative.create(sema.arena, result_limbs) |
| | 24473 | else |
| | 24474 | try Value.Tag.int_big_positive.create(sema.arena, result_limbs); |
| | 24475 | |
| | 24476 | if (!(try sema.intFitsInType(block, src, result, int_ty))) { |
| | 24477 | return sema.fail(block, src, "float value {} cannot be stored in integer type '{}'", .{ |
| | 24478 | val.fmtValue(float_ty, sema.mod), int_ty.fmt(sema.mod), |
| | 24479 | }); |
| | 24480 | } |
| | 24481 | return result; |
| | 24482 | } |
| | 24483 | |
| | 24484 | /// Asserts the value is an integer, and the destination type is ComptimeInt or Int. |
| | 24485 | /// Vectors are also accepted. Vector results are reduced with AND. |
| | 24486 | fn intFitsInType( |
| | 24487 | sema: *Sema, |
| | 24488 | block: *Block, |
| | 24489 | src: LazySrcLoc, |
| | 24490 | self: Value, |
| | 24491 | ty: Type, |
| | 24492 | ) CompileError!bool { |
| | 24493 | const target = sema.mod.getTarget(); |
| | 24494 | switch (self.tag()) { |
| | 24495 | .zero, |
| | 24496 | .undef, |
| | 24497 | .bool_false, |
| | 24498 | => return true, |
| | 24499 | |
| | 24500 | .one, |
| | 24501 | .bool_true, |
| | 24502 | => switch (ty.zigTypeTag()) { |
| | 24503 | .Int => { |
| | 24504 | const info = ty.intInfo(target); |
| | 24505 | return switch (info.signedness) { |
| | 24506 | .signed => info.bits >= 2, |
| | 24507 | .unsigned => info.bits >= 1, |
| | 24508 | }; |
| | 24509 | }, |
| | 24510 | .ComptimeInt => return true, |
| | 24511 | else => unreachable, |
| | 24512 | }, |
| | 24513 | |
| | 24514 | .lazy_align => { |
| | 24515 | const info = ty.intInfo(target); |
| | 24516 | const max_needed_bits = @as(u16, 16) + @boolToInt(info.signedness == .signed); |
| | 24517 | // If it is u16 or bigger we know the alignment fits without resolving it. |
| | 24518 | if (info.bits >= max_needed_bits) return true; |
| | 24519 | const x = try sema.typeAbiAlignment(block, src, self.castTag(.lazy_align).?.data); |
| | 24520 | if (x == 0) return true; |
| | 24521 | const actual_needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed); |
| | 24522 | return info.bits >= actual_needed_bits; |
| | 24523 | }, |
| | 24524 | .lazy_size => { |
| | 24525 | const info = ty.intInfo(target); |
| | 24526 | const max_needed_bits = @as(u16, 64) + @boolToInt(info.signedness == .signed); |
| | 24527 | // If it is u64 or bigger we know the size fits without resolving it. |
| | 24528 | if (info.bits >= max_needed_bits) return true; |
| | 24529 | const x = try sema.typeAbiSize(block, src, self.castTag(.lazy_size).?.data); |
| | 24530 | if (x == 0) return true; |
| | 24531 | const actual_needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed); |
| | 24532 | return info.bits >= actual_needed_bits; |
| | 24533 | }, |
| | 24534 | |
| | 24535 | .int_u64 => switch (ty.zigTypeTag()) { |
| | 24536 | .Int => { |
| | 24537 | const x = self.castTag(.int_u64).?.data; |
| | 24538 | if (x == 0) return true; |
| | 24539 | const info = ty.intInfo(target); |
| | 24540 | const needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed); |
| | 24541 | return info.bits >= needed_bits; |
| | 24542 | }, |
| | 24543 | .ComptimeInt => return true, |
| | 24544 | else => unreachable, |
| | 24545 | }, |
| | 24546 | .int_i64 => switch (ty.zigTypeTag()) { |
| | 24547 | .Int => { |
| | 24548 | const x = self.castTag(.int_i64).?.data; |
| | 24549 | if (x == 0) return true; |
| | 24550 | const info = ty.intInfo(target); |
| | 24551 | if (info.signedness == .unsigned and x < 0) |
| | 24552 | return false; |
| | 24553 | var buffer: Value.BigIntSpace = undefined; |
| | 24554 | return (try self.toBigIntAdvanced(&buffer, target, sema.kit(block, src))).fitsInTwosComp(info.signedness, info.bits); |
| | 24555 | }, |
| | 24556 | .ComptimeInt => return true, |
| | 24557 | else => unreachable, |
| | 24558 | }, |
| | 24559 | .int_big_positive => switch (ty.zigTypeTag()) { |
| | 24560 | .Int => { |
| | 24561 | const info = ty.intInfo(target); |
| | 24562 | return self.castTag(.int_big_positive).?.asBigInt().fitsInTwosComp(info.signedness, info.bits); |
| | 24563 | }, |
| | 24564 | .ComptimeInt => return true, |
| | 24565 | else => unreachable, |
| | 24566 | }, |
| | 24567 | .int_big_negative => switch (ty.zigTypeTag()) { |
| | 24568 | .Int => { |
| | 24569 | const info = ty.intInfo(target); |
| | 24570 | return self.castTag(.int_big_negative).?.asBigInt().fitsInTwosComp(info.signedness, info.bits); |
| | 24571 | }, |
| | 24572 | .ComptimeInt => return true, |
| | 24573 | else => unreachable, |
| | 24574 | }, |
| | 24575 | |
| | 24576 | .the_only_possible_value => { |
| | 24577 | assert(ty.intInfo(target).bits == 0); |
| | 24578 | return true; |
| | 24579 | }, |
| | 24580 | |
| | 24581 | .decl_ref_mut, |
| | 24582 | .extern_fn, |
| | 24583 | .decl_ref, |
| | 24584 | .function, |
| | 24585 | .variable, |
| | 24586 | => switch (ty.zigTypeTag()) { |
| | 24587 | .Int => { |
| | 24588 | const info = ty.intInfo(target); |
| | 24589 | const ptr_bits = target.cpu.arch.ptrBitWidth(); |
| | 24590 | return switch (info.signedness) { |
| | 24591 | .signed => info.bits > ptr_bits, |
| | 24592 | .unsigned => info.bits >= ptr_bits, |
| | 24593 | }; |
| | 24594 | }, |
| | 24595 | .ComptimeInt => return true, |
| | 24596 | else => unreachable, |
| | 24597 | }, |
| | 24598 | |
| | 24599 | .aggregate => { |
| | 24600 | assert(ty.zigTypeTag() == .Vector); |
| | 24601 | for (self.castTag(.aggregate).?.data) |elem| { |
| | 24602 | if (!(try sema.intFitsInType(block, src, elem, ty.scalarType()))) { |
| | 24603 | return false; |
| | 24604 | } |
| | 24605 | } |
| | 24606 | return true; |
| | 24607 | }, |
| | 24608 | |
| | 24609 | else => unreachable, |
| | 24610 | } |
| | 24611 | } |
| | 24612 | |
| | 24613 | fn intInRange( |
| | 24614 | sema: *Sema, |
| | 24615 | block: *Block, |
| | 24616 | src: LazySrcLoc, |
| | 24617 | tag_ty: Type, |
| | 24618 | int_val: Value, |
| | 24619 | end: usize, |
| | 24620 | ) !bool { |
| | 24621 | if (try int_val.compareWithZeroAdvanced(.lt, sema.kit(block, src))) return false; |
| | 24622 | var end_payload: Value.Payload.U64 = .{ |
| | 24623 | .base = .{ .tag = .int_u64 }, |
| | 24624 | .data = end, |
| | 24625 | }; |
| | 24626 | const end_val = Value.initPayload(&end_payload.base); |
| | 24627 | if (try sema.compare(block, src, int_val, .gte, end_val, tag_ty)) return false; |
| | 24628 | return true; |
| | 24629 | } |
| | 24630 | |
| | 24631 | /// Asserts the type is an enum. |
| | 24632 | fn enumHasInt( |
| | 24633 | sema: *Sema, |
| | 24634 | block: *Block, |
| | 24635 | src: LazySrcLoc, |
| | 24636 | ty: Type, |
| | 24637 | int: Value, |
| | 24638 | ) CompileError!bool { |
| | 24639 | switch (ty.tag()) { |
| | 24640 | .enum_nonexhaustive => return sema.intFitsInType(block, src, int, ty), |
| | 24641 | .enum_full => { |
| | 24642 | const enum_full = ty.castTag(.enum_full).?.data; |
| | 24643 | const tag_ty = enum_full.tag_ty; |
| | 24644 | if (enum_full.values.count() == 0) { |
| | 24645 | return intInRange(sema, block, src, tag_ty, int, enum_full.fields.count()); |
| | 24646 | } else { |
| | 24647 | return enum_full.values.containsContext(int, .{ |
| | 24648 | .ty = tag_ty, |
| | 24649 | .mod = sema.mod, |
| | 24650 | }); |
| | 24651 | } |
| | 24652 | }, |
| | 24653 | .enum_numbered => { |
| | 24654 | const enum_obj = ty.castTag(.enum_numbered).?.data; |
| | 24655 | const tag_ty = enum_obj.tag_ty; |
| | 24656 | if (enum_obj.values.count() == 0) { |
| | 24657 | return intInRange(sema, block, src, tag_ty, int, enum_obj.fields.count()); |
| | 24658 | } else { |
| | 24659 | return enum_obj.values.containsContext(int, .{ |
| | 24660 | .ty = tag_ty, |
| | 24661 | .mod = sema.mod, |
| | 24662 | }); |
| | 24663 | } |
| | 24664 | }, |
| | 24665 | .enum_simple => { |
| | 24666 | const enum_simple = ty.castTag(.enum_simple).?.data; |
| | 24667 | const fields_len = enum_simple.fields.count(); |
| | 24668 | const bits = std.math.log2_int_ceil(usize, fields_len); |
| | 24669 | var buffer: Type.Payload.Bits = .{ |
| | 24670 | .base = .{ .tag = .int_unsigned }, |
| | 24671 | .data = bits, |
| | 24672 | }; |
| | 24673 | const tag_ty = Type.initPayload(&buffer.base); |
| | 24674 | return intInRange(sema, block, src, tag_ty, int, fields_len); |
| | 24675 | }, |
| | 24676 | .atomic_order, |
| | 24677 | .atomic_rmw_op, |
| | 24678 | .calling_convention, |
| | 24679 | .address_space, |
| | 24680 | .float_mode, |
| | 24681 | .reduce_op, |
| | 24682 | .call_options, |
| | 24683 | .prefetch_options, |
| | 24684 | .export_options, |
| | 24685 | .extern_options, |
| | 24686 | => unreachable, |
| | 24687 | |
| | 24688 | else => unreachable, |
| | 24689 | } |
| | 24690 | } |
| | 24691 | |
| | 24692 | fn intAddWithOverflow( |
| | 24693 | sema: *Sema, |
| | 24694 | block: *Block, |
| | 24695 | src: LazySrcLoc, |
| | 24696 | lhs: Value, |
| | 24697 | rhs: Value, |
| | 24698 | ty: Type, |
| | 24699 | ) !Value.OverflowArithmeticResult { |
| | 24700 | if (ty.zigTypeTag() == .Vector) { |
| | 24701 | const overflowed_data = try sema.arena.alloc(Value, ty.vectorLen()); |
| | 24702 | const result_data = try sema.arena.alloc(Value, ty.vectorLen()); |
| | 24703 | for (result_data) |*scalar, i| { |
| | 24704 | const of_math_result = try sema.intAddWithOverflowScalar(block, src, lhs.indexVectorlike(i), rhs.indexVectorlike(i), ty.scalarType()); |
| | 24705 | overflowed_data[i] = of_math_result.overflowed; |
| | 24706 | scalar.* = of_math_result.wrapped_result; |
| | 24707 | } |
| | 24708 | return Value.OverflowArithmeticResult{ |
| | 24709 | .overflowed = try Value.Tag.aggregate.create(sema.arena, overflowed_data), |
| | 24710 | .wrapped_result = try Value.Tag.aggregate.create(sema.arena, result_data), |
| | 24711 | }; |
| | 24712 | } |
| | 24713 | return sema.intAddWithOverflowScalar(block, src, lhs, rhs, ty); |
| | 24714 | } |
| | 24715 | |
| | 24716 | fn intAddWithOverflowScalar( |
| | 24717 | sema: *Sema, |
| | 24718 | block: *Block, |
| | 24719 | src: LazySrcLoc, |
| | 24720 | lhs: Value, |
| | 24721 | rhs: Value, |
| | 24722 | ty: Type, |
| | 24723 | ) !Value.OverflowArithmeticResult { |
| | 24724 | const target = sema.mod.getTarget(); |
| | 24725 | const info = ty.intInfo(target); |
| | 24726 | |
| | 24727 | var lhs_space: Value.BigIntSpace = undefined; |
| | 24728 | var rhs_space: Value.BigIntSpace = undefined; |
| | 24729 | const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, target, sema.kit(block, src)); |
| | 24730 | const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, target, sema.kit(block, src)); |
| | 24731 | const limbs = try sema.arena.alloc( |
| | 24732 | std.math.big.Limb, |
| | 24733 | std.math.big.int.calcTwosCompLimbCount(info.bits), |
| | 24734 | ); |
| | 24735 | var result_bigint = std.math.big.int.Mutable{ .limbs = limbs, .positive = undefined, .len = undefined }; |
| | 24736 | const overflowed = result_bigint.addWrap(lhs_bigint, rhs_bigint, info.signedness, info.bits); |
| | 24737 | const result = try Value.fromBigInt(sema.arena, result_bigint.toConst()); |
| | 24738 | return Value.OverflowArithmeticResult{ |
| | 24739 | .overflowed = Value.makeBool(overflowed), |
| | 24740 | .wrapped_result = result, |
| | 24741 | }; |
| | 24742 | } |
| | 24743 | |
| | 24744 | /// Asserts the values are comparable. Both operands have type `ty`. |
| | 24745 | /// Vector results will be reduced with AND. |
| | 24746 | fn compare( |
| | 24747 | sema: *Sema, |
| | 24748 | block: *Block, |
| | 24749 | src: LazySrcLoc, |
| | 24750 | lhs: Value, |
| | 24751 | op: std.math.CompareOperator, |
| | 24752 | rhs: Value, |
| | 24753 | ty: Type, |
| | 24754 | ) CompileError!bool { |
| | 24755 | if (ty.zigTypeTag() == .Vector) { |
| | 24756 | var i: usize = 0; |
| | 24757 | while (i < ty.vectorLen()) : (i += 1) { |
| | 24758 | if (!(try sema.compareScalar(block, src, lhs.indexVectorlike(i), op, rhs.indexVectorlike(i), ty.scalarType()))) { |
| | 24759 | return false; |
| | 24760 | } |
| | 24761 | } |
| | 24762 | return true; |
| | 24763 | } |
| | 24764 | return sema.compareScalar(block, src, lhs, op, rhs, ty); |
| | 24765 | } |
| | 24766 | |
| | 24767 | /// Asserts the values are comparable. Both operands have type `ty`. |
| | 24768 | fn compareScalar( |
| | 24769 | sema: *Sema, |
| | 24770 | block: *Block, |
| | 24771 | src: LazySrcLoc, |
| | 24772 | lhs: Value, |
| | 24773 | op: std.math.CompareOperator, |
| | 24774 | rhs: Value, |
| | 24775 | ty: Type, |
| | 24776 | ) CompileError!bool { |
| | 24777 | switch (op) { |
| | 24778 | .eq => return sema.valuesEqual(block, src, lhs, rhs, ty), |
| | 24779 | .neq => return !(try sema.valuesEqual(block, src, lhs, rhs, ty)), |
| | 24780 | else => return Value.compareHeteroAdvanced(lhs, op, rhs, sema.mod.getTarget(), sema.kit(block, src)), |
| | 24781 | } |
| | 24782 | } |
| | 24783 | |
| | 24784 | fn valuesEqual( |
| | 24785 | sema: *Sema, |
| | 24786 | block: *Block, |
| | 24787 | src: LazySrcLoc, |
| | 24788 | lhs: Value, |
| | 24789 | rhs: Value, |
| | 24790 | ty: Type, |
| | 24791 | ) CompileError!bool { |
| | 24792 | return Value.eqlAdvanced(lhs, rhs, ty, sema.mod, sema.kit(block, src)); |
| | 24793 | } |
| | 24794 | |
| | 24795 | /// Asserts the values are comparable vectors of type `ty`. |
| | 24796 | pub fn compareVector( |
| | 24797 | sema: *Sema, |
| | 24798 | block: *Block, |
| | 24799 | src: LazySrcLoc, |
| | 24800 | lhs: Value, |
| | 24801 | op: std.math.CompareOperator, |
| | 24802 | rhs: Value, |
| | 24803 | ty: Type, |
| | 24804 | ) !Value { |
| | 24805 | assert(ty.zigTypeTag() == .Vector); |
| | 24806 | const result_data = try sema.arena.alloc(Value, ty.vectorLen()); |
| | 24807 | for (result_data) |*scalar, i| { |
| | 24808 | const res_bool = try sema.compareScalar(block, src, lhs.indexVectorlike(i), op, rhs.indexVectorlike(i), ty.scalarType()); |
| | 24809 | scalar.* = Value.makeBool(res_bool); |
| | 24810 | } |
| | 24811 | return Value.Tag.aggregate.create(sema.arena, result_data); |
| | 24812 | } |