| ... | @@ -11092,17 +11092,17 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r | ... | @@ -11092,17 +11092,17 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r |
| 11092 | const special_prong_src: LazySrcLoc = .{ .node_offset_switch_special_prong = src_node_offset }; | 11092 | const special_prong_src: LazySrcLoc = .{ .node_offset_switch_special_prong = src_node_offset }; |
| 11093 | const extra = sema.code.extraData(Zir.Inst.SwitchBlock, inst_data.payload_index); | 11093 | const extra = sema.code.extraData(Zir.Inst.SwitchBlock, inst_data.payload_index); |
| 11094 | | 11094 | |
| 11095 | const raw_operand: struct { val: Air.Inst.Ref, ptr: Air.Inst.Ref } = blk: { | 11095 | const raw_operand_val: Air.Inst.Ref, const raw_operand_ptr: Air.Inst.Ref = blk: { |
| 11096 | const maybe_ptr = try sema.resolveInst(extra.data.operand); | 11096 | const maybe_ptr = try sema.resolveInst(extra.data.operand); |
| 11097 | if (operand_is_ref) { | 11097 | if (operand_is_ref) { |
| 11098 | const val = try sema.analyzeLoad(block, src, maybe_ptr, operand_src); | 11098 | const val = try sema.analyzeLoad(block, src, maybe_ptr, operand_src); |
| 11099 | break :blk .{ .val = val, .ptr = maybe_ptr }; | 11099 | break :blk .{ val, maybe_ptr }; |
| 11100 | } else { | 11100 | } else { |
| 11101 | break :blk .{ .val = maybe_ptr, .ptr = undefined }; | 11101 | break :blk .{ maybe_ptr, undefined }; |
| 11102 | } | 11102 | } |
| 11103 | }; | 11103 | }; |
| 11104 | | 11104 | |
| 11105 | const operand = try sema.switchCond(block, operand_src, raw_operand.val); | 11105 | const operand = try sema.switchCond(block, operand_src, raw_operand_val); |
| 11106 | | 11106 | |
| 11107 | // AstGen guarantees that the instruction immediately preceding | 11107 | // AstGen guarantees that the instruction immediately preceding |
| 11108 | // switch_block(_ref) is a dbg_stmt | 11108 | // switch_block(_ref) is a dbg_stmt |
| ... | @@ -11160,7 +11160,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r | ... | @@ -11160,7 +11160,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r |
| 11160 | }, | 11160 | }, |
| 11161 | }; | 11161 | }; |
| 11162 | | 11162 | |
| 11163 | const maybe_union_ty = sema.typeOf(raw_operand.val); | 11163 | const maybe_union_ty = sema.typeOf(raw_operand_val); |
| 11164 | const union_originally = maybe_union_ty.zigTypeTag(mod) == .Union; | 11164 | const union_originally = maybe_union_ty.zigTypeTag(mod) == .Union; |
| 11165 | | 11165 | |
| 11166 | // Duplicate checking variables later also used for `inline else`. | 11166 | // Duplicate checking variables later also used for `inline else`. |
| ... | @@ -11711,8 +11711,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r | ... | @@ -11711,8 +11711,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r |
| 11711 | const spa: SwitchProngAnalysis = .{ | 11711 | const spa: SwitchProngAnalysis = .{ |
| 11712 | .sema = sema, | 11712 | .sema = sema, |
| 11713 | .parent_block = block, | 11713 | .parent_block = block, |
| 11714 | .operand = raw_operand.val, | 11714 | .operand = raw_operand_val, |
| 11715 | .operand_ptr = raw_operand.ptr, | 11715 | .operand_ptr = raw_operand_ptr, |
| 11716 | .cond = operand, | 11716 | .cond = operand, |
| 11717 | .else_error_ty = else_error_ty, | 11717 | .else_error_ty = else_error_ty, |
| 11718 | .switch_block_inst = inst, | 11718 | .switch_block_inst = inst, |
| ... | @@ -15500,11 +15500,7 @@ fn analyzeArithmetic( | ... | @@ -15500,11 +15500,7 @@ fn analyzeArithmetic( |
| 15500 | | 15500 | |
| 15501 | const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(casted_lhs); | 15501 | const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(casted_lhs); |
| 15502 | const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(casted_rhs); | 15502 | const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(casted_rhs); |
| 15503 | const rs: struct { | 15503 | const runtime_src: LazySrcLoc, const air_tag: Air.Inst.Tag, const air_tag_safe: Air.Inst.Tag = rs: { |
| 15504 | src: LazySrcLoc, | | |
| 15505 | air_tag: Air.Inst.Tag, | | |
| 15506 | air_tag_safe: Air.Inst.Tag, | | |
| 15507 | } = rs: { | | |
| 15508 | switch (zir_tag) { | 15504 | switch (zir_tag) { |
| 15509 | .add, .add_unsafe => { | 15505 | .add, .add_unsafe => { |
| 15510 | // For integers:intAddSat | 15506 | // For integers:intAddSat |
| ... | @@ -15551,8 +15547,8 @@ fn analyzeArithmetic( | ... | @@ -15551,8 +15547,8 @@ fn analyzeArithmetic( |
| 15551 | } else { | 15547 | } else { |
| 15552 | return Air.internedToRef((try Value.floatAdd(lhs_val, rhs_val, resolved_type, sema.arena, mod)).toIntern()); | 15548 | return Air.internedToRef((try Value.floatAdd(lhs_val, rhs_val, resolved_type, sema.arena, mod)).toIntern()); |
| 15553 | } | 15549 | } |
| 15554 | } else break :rs .{ .src = rhs_src, .air_tag = air_tag, .air_tag_safe = .add_safe }; | 15550 | } else break :rs .{ rhs_src, air_tag, .add_safe }; |
| 15555 | } else break :rs .{ .src = lhs_src, .air_tag = air_tag, .air_tag_safe = .add_safe }; | 15551 | } else break :rs .{ lhs_src, air_tag, .add_safe }; |
| 15556 | }, | 15552 | }, |
| 15557 | .addwrap => { | 15553 | .addwrap => { |
| 15558 | // Integers only; floats are checked above. | 15554 | // Integers only; floats are checked above. |
| ... | @@ -15572,8 +15568,8 @@ fn analyzeArithmetic( | ... | @@ -15572,8 +15568,8 @@ fn analyzeArithmetic( |
| 15572 | } | 15568 | } |
| 15573 | if (maybe_lhs_val) |lhs_val| { | 15569 | if (maybe_lhs_val) |lhs_val| { |
| 15574 | return Air.internedToRef((try sema.numberAddWrapScalar(lhs_val, rhs_val, resolved_type)).toIntern()); | 15570 | return Air.internedToRef((try sema.numberAddWrapScalar(lhs_val, rhs_val, resolved_type)).toIntern()); |
| 15575 | } else break :rs .{ .src = lhs_src, .air_tag = .add_wrap, .air_tag_safe = .add_wrap }; | 15571 | } else break :rs .{ lhs_src, .add_wrap, .add_wrap }; |
| 15576 | } else break :rs .{ .src = rhs_src, .air_tag = .add_wrap, .air_tag_safe = .add_wrap }; | 15572 | } else break :rs .{ rhs_src, .add_wrap, .add_wrap }; |
| 15577 | }, | 15573 | }, |
| 15578 | .add_sat => { | 15574 | .add_sat => { |
| 15579 | // Integers only; floats are checked above. | 15575 | // Integers only; floats are checked above. |
| ... | @@ -15599,14 +15595,14 @@ fn analyzeArithmetic( | ... | @@ -15599,14 +15595,14 @@ fn analyzeArithmetic( |
| 15599 | | 15595 | |
| 15600 | return Air.internedToRef(val.toIntern()); | 15596 | return Air.internedToRef(val.toIntern()); |
| 15601 | } else break :rs .{ | 15597 | } else break :rs .{ |
| 15602 | .src = lhs_src, | 15598 | lhs_src, |
| 15603 | .air_tag = .add_sat, | 15599 | .add_sat, |
| 15604 | .air_tag_safe = .add_sat, | 15600 | .add_sat, |
| 15605 | }; | 15601 | }; |
| 15606 | } else break :rs .{ | 15602 | } else break :rs .{ |
| 15607 | .src = rhs_src, | 15603 | rhs_src, |
| 15608 | .air_tag = .add_sat, | 15604 | .add_sat, |
| 15609 | .air_tag_safe = .add_sat, | 15605 | .add_sat, |
| 15610 | }; | 15606 | }; |
| 15611 | }, | 15607 | }, |
| 15612 | .sub => { | 15608 | .sub => { |
| ... | @@ -15649,8 +15645,8 @@ fn analyzeArithmetic( | ... | @@ -15649,8 +15645,8 @@ fn analyzeArithmetic( |
| 15649 | } else { | 15645 | } else { |
| 15650 | return Air.internedToRef((try Value.floatSub(lhs_val, rhs_val, resolved_type, sema.arena, mod)).toIntern()); | 15646 | return Air.internedToRef((try Value.floatSub(lhs_val, rhs_val, resolved_type, sema.arena, mod)).toIntern()); |
| 15651 | } | 15647 | } |
| 15652 | } else break :rs .{ .src = rhs_src, .air_tag = air_tag, .air_tag_safe = .sub_safe }; | 15648 | } else break :rs .{ rhs_src, air_tag, .sub_safe }; |
| 15653 | } else break :rs .{ .src = lhs_src, .air_tag = air_tag, .air_tag_safe = .sub_safe }; | 15649 | } else break :rs .{ lhs_src, air_tag, .sub_safe }; |
| 15654 | }, | 15650 | }, |
| 15655 | .subwrap => { | 15651 | .subwrap => { |
| 15656 | // Integers only; floats are checked above. | 15652 | // Integers only; floats are checked above. |
| ... | @@ -15670,8 +15666,8 @@ fn analyzeArithmetic( | ... | @@ -15670,8 +15666,8 @@ fn analyzeArithmetic( |
| 15670 | } | 15666 | } |
| 15671 | if (maybe_rhs_val) |rhs_val| { | 15667 | if (maybe_rhs_val) |rhs_val| { |
| 15672 | return Air.internedToRef((try sema.numberSubWrapScalar(lhs_val, rhs_val, resolved_type)).toIntern()); | 15668 | return Air.internedToRef((try sema.numberSubWrapScalar(lhs_val, rhs_val, resolved_type)).toIntern()); |
| 15673 | } else break :rs .{ .src = rhs_src, .air_tag = .sub_wrap, .air_tag_safe = .sub_wrap }; | 15669 | } else break :rs .{ rhs_src, .sub_wrap, .sub_wrap }; |
| 15674 | } else break :rs .{ .src = lhs_src, .air_tag = .sub_wrap, .air_tag_safe = .sub_wrap }; | 15670 | } else break :rs .{ lhs_src, .sub_wrap, .sub_wrap }; |
| 15675 | }, | 15671 | }, |
| 15676 | .sub_sat => { | 15672 | .sub_sat => { |
| 15677 | // Integers only; floats are checked above. | 15673 | // Integers only; floats are checked above. |
| ... | @@ -15696,8 +15692,8 @@ fn analyzeArithmetic( | ... | @@ -15696,8 +15692,8 @@ fn analyzeArithmetic( |
| 15696 | try lhs_val.intSubSat(rhs_val, resolved_type, sema.arena, mod); | 15692 | try lhs_val.intSubSat(rhs_val, resolved_type, sema.arena, mod); |
| 15697 | | 15693 | |
| 15698 | return Air.internedToRef(val.toIntern()); | 15694 | return Air.internedToRef(val.toIntern()); |
| 15699 | } else break :rs .{ .src = rhs_src, .air_tag = .sub_sat, .air_tag_safe = .sub_sat }; | 15695 | } else break :rs .{ rhs_src, .sub_sat, .sub_sat }; |
| 15700 | } else break :rs .{ .src = lhs_src, .air_tag = .sub_sat, .air_tag_safe = .sub_sat }; | 15696 | } else break :rs .{ lhs_src, .sub_sat, .sub_sat }; |
| 15701 | }, | 15697 | }, |
| 15702 | .mul => { | 15698 | .mul => { |
| 15703 | // For integers: | 15699 | // For integers: |
| ... | @@ -15789,8 +15785,8 @@ fn analyzeArithmetic( | ... | @@ -15789,8 +15785,8 @@ fn analyzeArithmetic( |
| 15789 | } else { | 15785 | } else { |
| 15790 | return Air.internedToRef((try lhs_val.floatMul(rhs_val, resolved_type, sema.arena, mod)).toIntern()); | 15786 | return Air.internedToRef((try lhs_val.floatMul(rhs_val, resolved_type, sema.arena, mod)).toIntern()); |
| 15791 | } | 15787 | } |
| 15792 | } else break :rs .{ .src = lhs_src, .air_tag = air_tag, .air_tag_safe = .mul_safe }; | 15788 | } else break :rs .{ lhs_src, air_tag, .mul_safe }; |
| 15793 | } else break :rs .{ .src = rhs_src, .air_tag = air_tag, .air_tag_safe = .mul_safe }; | 15789 | } else break :rs .{ rhs_src, air_tag, .mul_safe }; |
| 15794 | }, | 15790 | }, |
| 15795 | .mulwrap => { | 15791 | .mulwrap => { |
| 15796 | // Integers only; floats are handled above. | 15792 | // Integers only; floats are handled above. |
| ... | @@ -15834,8 +15830,8 @@ fn analyzeArithmetic( | ... | @@ -15834,8 +15830,8 @@ fn analyzeArithmetic( |
| 15834 | return mod.undefRef(resolved_type); | 15830 | return mod.undefRef(resolved_type); |
| 15835 | } | 15831 | } |
| 15836 | return Air.internedToRef((try lhs_val.numberMulWrap(rhs_val, resolved_type, sema.arena, mod)).toIntern()); | 15832 | return Air.internedToRef((try lhs_val.numberMulWrap(rhs_val, resolved_type, sema.arena, mod)).toIntern()); |
| 15837 | } else break :rs .{ .src = lhs_src, .air_tag = .mul_wrap, .air_tag_safe = .mul_wrap }; | 15833 | } else break :rs .{ lhs_src, .mul_wrap, .mul_wrap }; |
| 15838 | } else break :rs .{ .src = rhs_src, .air_tag = .mul_wrap, .air_tag_safe = .mul_wrap }; | 15834 | } else break :rs .{ rhs_src, .mul_wrap, .mul_wrap }; |
| 15839 | }, | 15835 | }, |
| 15840 | .mul_sat => { | 15836 | .mul_sat => { |
| 15841 | // Integers only; floats are checked above. | 15837 | // Integers only; floats are checked above. |
| ... | @@ -15885,20 +15881,20 @@ fn analyzeArithmetic( | ... | @@ -15885,20 +15881,20 @@ fn analyzeArithmetic( |
| 15885 | try lhs_val.intMulSat(rhs_val, resolved_type, sema.arena, mod); | 15881 | try lhs_val.intMulSat(rhs_val, resolved_type, sema.arena, mod); |
| 15886 | | 15882 | |
| 15887 | return Air.internedToRef(val.toIntern()); | 15883 | return Air.internedToRef(val.toIntern()); |
| 15888 | } else break :rs .{ .src = lhs_src, .air_tag = .mul_sat, .air_tag_safe = .mul_sat }; | 15884 | } else break :rs .{ lhs_src, .mul_sat, .mul_sat }; |
| 15889 | } else break :rs .{ .src = rhs_src, .air_tag = .mul_sat, .air_tag_safe = .mul_sat }; | 15885 | } else break :rs .{ rhs_src, .mul_sat, .mul_sat }; |
| 15890 | }, | 15886 | }, |
| 15891 | else => unreachable, | 15887 | else => unreachable, |
| 15892 | } | 15888 | } |
| 15893 | }; | 15889 | }; |
| 15894 | | 15890 | |
| 15895 | try sema.requireRuntimeBlock(block, src, rs.src); | 15891 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 15896 | if (block.wantSafety() and want_safety and scalar_tag == .Int) { | 15892 | if (block.wantSafety() and want_safety and scalar_tag == .Int) { |
| 15897 | if (mod.backendSupportsFeature(.safety_checked_instructions)) { | 15893 | if (mod.backendSupportsFeature(.safety_checked_instructions)) { |
| 15898 | _ = try sema.preparePanicId(block, .integer_overflow); | 15894 | _ = try sema.preparePanicId(block, .integer_overflow); |
| 15899 | return block.addBinOp(rs.air_tag_safe, casted_lhs, casted_rhs); | 15895 | return block.addBinOp(air_tag_safe, casted_lhs, casted_rhs); |
| 15900 | } else { | 15896 | } else { |
| 15901 | const maybe_op_ov: ?Air.Inst.Tag = switch (rs.air_tag) { | 15897 | const maybe_op_ov: ?Air.Inst.Tag = switch (air_tag) { |
| 15902 | .add => .add_with_overflow, | 15898 | .add => .add_with_overflow, |
| 15903 | .sub => .sub_with_overflow, | 15899 | .sub => .sub_with_overflow, |
| 15904 | .mul => .mul_with_overflow, | 15900 | .mul => .mul_with_overflow, |
| ... | @@ -15935,7 +15931,7 @@ fn analyzeArithmetic( | ... | @@ -15935,7 +15931,7 @@ fn analyzeArithmetic( |
| 15935 | } | 15931 | } |
| 15936 | } | 15932 | } |
| 15937 | } | 15933 | } |
| 15938 | return block.addBinOp(rs.air_tag, casted_lhs, casted_rhs); | 15934 | return block.addBinOp(air_tag, casted_lhs, casted_rhs); |
| 15939 | } | 15935 | } |
| 15940 | | 15936 | |
| 15941 | fn analyzePtrArithmetic( | 15937 | fn analyzePtrArithmetic( |
| ... | @@ -32345,16 +32341,10 @@ fn compareIntsOnlyPossibleResult( | ... | @@ -32345,16 +32341,10 @@ fn compareIntsOnlyPossibleResult( |
| 32345 | | 32341 | |
| 32346 | // For any other comparison, we need to know if the LHS value is | 32342 | // For any other comparison, we need to know if the LHS value is |
| 32347 | // equal to the maximum or minimum possible value of the RHS type. | 32343 | // equal to the maximum or minimum possible value of the RHS type. |
| 32348 | const edge: struct { min: bool, max: bool } = edge: { | 32344 | const is_min, const is_max = edge: { |
| 32349 | if (is_zero and rhs_info.signedness == .unsigned) break :edge .{ | 32345 | if (is_zero and rhs_info.signedness == .unsigned) break :edge .{ true, false }; |
| 32350 | .min = true, | | |
| 32351 | .max = false, | | |
| 32352 | }; | | |
| 32353 | | 32346 | |
| 32354 | if (req_bits != rhs_info.bits) break :edge .{ | 32347 | if (req_bits != rhs_info.bits) break :edge .{ false, false }; |
| 32355 | .min = false, | | |
| 32356 | .max = false, | | |
| 32357 | }; | | |
| 32358 | | 32348 | |
| 32359 | const ty = try mod.intType( | 32349 | const ty = try mod.intType( |
| 32360 | if (is_negative) .signed else .unsigned, | 32350 | if (is_negative) .signed else .unsigned, |
| ... | @@ -32363,24 +32353,18 @@ fn compareIntsOnlyPossibleResult( | ... | @@ -32363,24 +32353,18 @@ fn compareIntsOnlyPossibleResult( |
| 32363 | const pop_count = lhs_val.popCount(ty, mod); | 32353 | const pop_count = lhs_val.popCount(ty, mod); |
| 32364 | | 32354 | |
| 32365 | if (is_negative) { | 32355 | if (is_negative) { |
| 32366 | break :edge .{ | 32356 | break :edge .{ pop_count == 1, false }; |
| 32367 | .min = pop_count == 1, | | |
| 32368 | .max = false, | | |
| 32369 | }; | | |
| 32370 | } else { | 32357 | } else { |
| 32371 | break :edge .{ | 32358 | break :edge .{ false, pop_count == req_bits - sign_adj }; |
| 32372 | .min = false, | | |
| 32373 | .max = pop_count == req_bits - sign_adj, | | |
| 32374 | }; | | |
| 32375 | } | 32359 | } |
| 32376 | }; | 32360 | }; |
| 32377 | | 32361 | |
| 32378 | assert(fits); | 32362 | assert(fits); |
| 32379 | return switch (op) { | 32363 | return switch (op) { |
| 32380 | .lt => if (edge.max) false else null, | 32364 | .lt => if (is_max) false else null, |
| 32381 | .lte => if (edge.min) true else null, | 32365 | .lte => if (is_min) true else null, |
| 32382 | .gt => if (edge.min) false else null, | 32366 | .gt => if (is_min) false else null, |
| 32383 | .gte => if (edge.max) true else null, | 32367 | .gte => if (is_max) true else null, |
| 32384 | .eq, .neq => unreachable, | 32368 | .eq, .neq => unreachable, |
| 32385 | }; | 32369 | }; |
| 32386 | } | 32370 | } |
| ... | @@ -32617,7 +32601,7 @@ const PeerResolveStrategy = enum { | ... | @@ -32617,7 +32601,7 @@ const PeerResolveStrategy = enum { |
| 32617 | either, | 32601 | either, |
| 32618 | }; | 32602 | }; |
| 32619 | | 32603 | |
| 32620 | const res: struct { ReasonMethod, PeerResolveStrategy } = switch (s0) { | 32604 | const reason_method: ReasonMethod, const strat: PeerResolveStrategy = switch (s0) { |
| 32621 | .unknown => .{ .all_s1, s1 }, | 32605 | .unknown => .{ .all_s1, s1 }, |
| 32622 | .error_set => switch (s1) { | 32606 | .error_set => switch (s1) { |
| 32623 | .error_set => .{ .either, .error_set }, | 32607 | .error_set => .{ .either, .error_set }, |
| ... | @@ -32685,7 +32669,7 @@ const PeerResolveStrategy = enum { | ... | @@ -32685,7 +32669,7 @@ const PeerResolveStrategy = enum { |
| 32685 | .exact => .{ .all_s0, .exact }, | 32669 | .exact => .{ .all_s0, .exact }, |
| 32686 | }; | 32670 | }; |
| 32687 | | 32671 | |
| 32688 | switch (res[0]) { | 32672 | switch (reason_method) { |
| 32689 | .all_s0 => { | 32673 | .all_s0 => { |
| 32690 | if (!s0_is_a) { | 32674 | if (!s0_is_a) { |
| 32691 | reason_peer.* = b_peer_idx; | 32675 | reason_peer.* = b_peer_idx; |
| ... | @@ -32702,7 +32686,7 @@ const PeerResolveStrategy = enum { | ... | @@ -32702,7 +32686,7 @@ const PeerResolveStrategy = enum { |
| 32702 | }, | 32686 | }, |
| 32703 | } | 32687 | } |
| 32704 | | 32688 | |
| 32705 | return res[1]; | 32689 | return strat; |
| 32706 | } | 32690 | } |
| 32707 | | 32691 | |
| 32708 | fn select(ty: Type, mod: *Module) PeerResolveStrategy { | 32692 | fn select(ty: Type, mod: *Module) PeerResolveStrategy { |