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