| ... | @@ -14715,51 +14715,64 @@ fn checkNumericType( | ... | @@ -14715,51 +14715,64 @@ fn checkNumericType( |
| 14715 | } | 14715 | } |
| 14716 | } | 14716 | } |
| 14717 | | 14717 | |
| 14718 | fn checkAtomicOperandType( | 14718 | /// Returns the casted pointer. |
| | 14719 | fn checkAtomicPtrOperand( |
| 14719 | sema: *Sema, | 14720 | sema: *Sema, |
| 14720 | block: *Block, | 14721 | block: *Block, |
| 14721 | ty_src: LazySrcLoc, | 14722 | elem_ty: Type, |
| 14722 | ty: Type, | 14723 | elem_ty_src: LazySrcLoc, |
| 14723 | ) CompileError!void { | 14724 | ptr: Air.Inst.Ref, |
| 14724 | var buffer: Type.Payload.Bits = undefined; | 14725 | ptr_src: LazySrcLoc, |
| | 14726 | ptr_const: bool, |
| | 14727 | ) CompileError!Air.Inst.Ref { |
| 14725 | const target = sema.mod.getTarget(); | 14728 | const target = sema.mod.getTarget(); |
| 14726 | const max_atomic_bits = target_util.largestAtomicBits(target); | 14729 | var diag: target_util.AtomicPtrAlignmentDiagnostics = .{}; |
| 14727 | const int_ty = switch (ty.zigTypeTag()) { | 14730 | const alignment = target_util.atomicPtrAlignment(target, elem_ty, &diag) catch |err| switch (err) { |
| 14728 | .Int => ty, | 14731 | error.FloatTooBig => return sema.fail( |
| 14729 | .Enum => ty.intTagType(&buffer), | 14732 | block, |
| 14730 | .Float => { | 14733 | elem_ty_src, |
| 14731 | const bit_count = ty.floatBits(target); | 14734 | "expected {d}-bit float type or smaller; found {d}-bit float type", |
| 14732 | if (bit_count > max_atomic_bits) { | 14735 | .{ diag.max_bits, diag.bits }, |
| 14733 | return sema.fail( | 14736 | ), |
| 14734 | block, | 14737 | error.IntTooBig => return sema.fail( |
| 14735 | ty_src, | 14738 | block, |
| 14736 | "expected {d}-bit float type or smaller; found {d}-bit float type", | 14739 | elem_ty_src, |
| 14737 | .{ max_atomic_bits, bit_count }, | 14740 | "expected {d}-bit integer type or smaller; found {d}-bit integer type", |
| 14738 | ); | 14741 | .{ diag.max_bits, diag.bits }, |
| 14739 | } | 14742 | ), |
| 14740 | return; | 14743 | error.BadType => return sema.fail( |
| 14741 | }, | 14744 | block, |
| 14742 | .Bool => return, // Will be treated as `u8`. | 14745 | elem_ty_src, |
| 14743 | else => { | 14746 | "expected bool, integer, float, enum, or pointer type; found {}", |
| 14744 | if (ty.isPtrAtRuntime()) return; | 14747 | .{elem_ty.fmt(sema.mod)}, |
| | 14748 | ), |
| | 14749 | }; |
| 14745 | | 14750 | |
| 14746 | return sema.fail( | 14751 | var wanted_ptr_data: Type.Payload.Pointer.Data = .{ |
| 14747 | block, | 14752 | .pointee_type = elem_ty, |
| 14748 | ty_src, | 14753 | .@"align" = alignment, |
| 14749 | "expected bool, integer, float, enum, or pointer type; found {}", | 14754 | .@"addrspace" = .generic, |
| 14750 | .{ty.fmt(sema.mod)}, | 14755 | .mutable = !ptr_const, |
| 14751 | ); | 14756 | }; |
| | 14757 | |
| | 14758 | const ptr_ty = sema.typeOf(ptr); |
| | 14759 | const ptr_data = switch (try ptr_ty.zigTypeTagOrPoison()) { |
| | 14760 | .Pointer => ptr_ty.ptrInfo().data, |
| | 14761 | else => { |
| | 14762 | const wanted_ptr_ty = try Type.ptr(sema.arena, sema.mod, wanted_ptr_data); |
| | 14763 | _ = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src); |
| | 14764 | unreachable; |
| 14752 | }, | 14765 | }, |
| 14753 | }; | 14766 | }; |
| 14754 | const bit_count = int_ty.intInfo(target).bits; | 14767 | |
| 14755 | if (bit_count > max_atomic_bits) { | 14768 | wanted_ptr_data.@"addrspace" = ptr_data.@"addrspace"; |
| 14756 | return sema.fail( | 14769 | wanted_ptr_data.@"allowzero" = ptr_data.@"allowzero"; |
| 14757 | block, | 14770 | wanted_ptr_data.@"volatile" = ptr_data.@"volatile"; |
| 14758 | ty_src, | 14771 | |
| 14759 | "expected {d}-bit integer type or smaller; found {d}-bit integer type", | 14772 | const wanted_ptr_ty = try Type.ptr(sema.arena, sema.mod, wanted_ptr_data); |
| 14760 | .{ max_atomic_bits, bit_count }, | 14773 | const casted_ptr = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src); |
| 14761 | ); | 14774 | |
| 14762 | } | 14775 | return casted_ptr; |
| 14763 | } | 14776 | } |
| 14764 | | 14777 | |
| 14765 | fn checkPtrIsNotComptimeMutable( | 14778 | fn checkPtrIsNotComptimeMutable( |
| ... | @@ -15036,10 +15049,8 @@ fn zirCmpxchg( | ... | @@ -15036,10 +15049,8 @@ fn zirCmpxchg( |
| 15036 | const success_order_src: LazySrcLoc = .{ .node_offset_builtin_call_arg4 = inst_data.src_node }; | 15049 | const success_order_src: LazySrcLoc = .{ .node_offset_builtin_call_arg4 = inst_data.src_node }; |
| 15037 | const failure_order_src: LazySrcLoc = .{ .node_offset_builtin_call_arg5 = inst_data.src_node }; | 15050 | const failure_order_src: LazySrcLoc = .{ .node_offset_builtin_call_arg5 = inst_data.src_node }; |
| 15038 | // zig fmt: on | 15051 | // zig fmt: on |
| 15039 | const ptr = sema.resolveInst(extra.ptr); | 15052 | const expected_value = sema.resolveInst(extra.expected_value); |
| 15040 | const ptr_ty = sema.typeOf(ptr); | 15053 | const elem_ty = sema.typeOf(expected_value); |
| 15041 | const elem_ty = ptr_ty.elemType(); | | |
| 15042 | try sema.checkAtomicOperandType(block, elem_ty_src, elem_ty); | | |
| 15043 | if (elem_ty.zigTypeTag() == .Float) { | 15054 | if (elem_ty.zigTypeTag() == .Float) { |
| 15044 | return sema.fail( | 15055 | return sema.fail( |
| 15045 | block, | 15056 | block, |
| ... | @@ -15048,7 +15059,8 @@ fn zirCmpxchg( | ... | @@ -15048,7 +15059,8 @@ fn zirCmpxchg( |
| 15048 | .{elem_ty.fmt(sema.mod)}, | 15059 | .{elem_ty.fmt(sema.mod)}, |
| 15049 | ); | 15060 | ); |
| 15050 | } | 15061 | } |
| 15051 | const expected_value = try sema.coerce(block, elem_ty, sema.resolveInst(extra.expected_value), expected_src); | 15062 | const uncasted_ptr = sema.resolveInst(extra.ptr); |
| | 15063 | const ptr = try sema.checkAtomicPtrOperand(block, elem_ty, elem_ty_src, uncasted_ptr, ptr_src, false); |
| 15052 | const new_value = try sema.coerce(block, elem_ty, sema.resolveInst(extra.new_value), new_value_src); | 15064 | const new_value = try sema.coerce(block, elem_ty, sema.resolveInst(extra.new_value), new_value_src); |
| 15053 | const success_order = try sema.resolveAtomicOrder(block, success_order_src, extra.success_order); | 15065 | const success_order = try sema.resolveAtomicOrder(block, success_order_src, extra.success_order); |
| 15054 | const failure_order = try sema.resolveAtomicOrder(block, failure_order_src, extra.failure_order); | 15066 | const failure_order = try sema.resolveAtomicOrder(block, failure_order_src, extra.failure_order); |
| ... | @@ -15081,6 +15093,7 @@ fn zirCmpxchg( | ... | @@ -15081,6 +15093,7 @@ fn zirCmpxchg( |
| 15081 | // to become undef as well | 15093 | // to become undef as well |
| 15082 | return sema.addConstUndef(result_ty); | 15094 | return sema.addConstUndef(result_ty); |
| 15083 | } | 15095 | } |
| | 15096 | const ptr_ty = sema.typeOf(ptr); |
| 15084 | const stored_val = (try sema.pointerDeref(block, ptr_src, ptr_val, ptr_ty)) orelse break :rs ptr_src; | 15097 | const stored_val = (try sema.pointerDeref(block, ptr_src, ptr_val, ptr_ty)) orelse break :rs ptr_src; |
| 15085 | const result_val = if (stored_val.eql(expected_val, elem_ty, sema.mod)) blk: { | 15098 | const result_val = if (stored_val.eql(expected_val, elem_ty, sema.mod)) blk: { |
| 15086 | try sema.storePtr(block, src, ptr, new_value); | 15099 | try sema.storePtr(block, src, ptr, new_value); |
| ... | @@ -15487,17 +15500,16 @@ fn zirSelect(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -15487,17 +15500,16 @@ fn zirSelect(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 15487 | | 15500 | |
| 15488 | fn zirAtomicLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 15501 | fn zirAtomicLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 15489 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; | 15502 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 15490 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 15503 | const extra = sema.code.extraData(Zir.Inst.AtomicLoad, inst_data.payload_index).data; |
| 15491 | // zig fmt: off | 15504 | // zig fmt: off |
| 15492 | const elem_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; | 15505 | const elem_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 15493 | const ptr_src : LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; | 15506 | const ptr_src : LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; |
| 15494 | const order_src : LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node }; | 15507 | const order_src : LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node }; |
| 15495 | // zig fmt: on | 15508 | // zig fmt: on |
| 15496 | const ptr = sema.resolveInst(extra.lhs); | 15509 | const elem_ty = try sema.resolveType(block, elem_ty_src, extra.elem_type); |
| 15497 | const ptr_ty = sema.typeOf(ptr); | 15510 | const uncasted_ptr = sema.resolveInst(extra.ptr); |
| 15498 | const elem_ty = ptr_ty.elemType(); | 15511 | const ptr = try sema.checkAtomicPtrOperand(block, elem_ty, elem_ty_src, uncasted_ptr, ptr_src, true); |
| 15499 | try sema.checkAtomicOperandType(block, elem_ty_src, elem_ty); | 15512 | const order = try sema.resolveAtomicOrder(block, order_src, extra.ordering); |
| 15500 | const order = try sema.resolveAtomicOrder(block, order_src, extra.rhs); | | |
| 15501 | | 15513 | |
| 15502 | switch (order) { | 15514 | switch (order) { |
| 15503 | .Release, .AcqRel => { | 15515 | .Release, .AcqRel => { |
| ... | @@ -15516,7 +15528,7 @@ fn zirAtomicLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -15516,7 +15528,7 @@ fn zirAtomicLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 15516 | } | 15528 | } |
| 15517 | | 15529 | |
| 15518 | if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| { | 15530 | if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| { |
| 15519 | if (try sema.pointerDeref(block, ptr_src, ptr_val, ptr_ty)) |elem_val| { | 15531 | if (try sema.pointerDeref(block, ptr_src, ptr_val, sema.typeOf(ptr))) |elem_val| { |
| 15520 | return sema.addConstant(elem_ty, elem_val); | 15532 | return sema.addConstant(elem_ty, elem_val); |
| 15521 | } | 15533 | } |
| 15522 | } | 15534 | } |
| ... | @@ -15536,19 +15548,19 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -15536,19 +15548,19 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 15536 | const extra = sema.code.extraData(Zir.Inst.AtomicRmw, inst_data.payload_index).data; | 15548 | const extra = sema.code.extraData(Zir.Inst.AtomicRmw, inst_data.payload_index).data; |
| 15537 | const src = inst_data.src(); | 15549 | const src = inst_data.src(); |
| 15538 | // zig fmt: off | 15550 | // zig fmt: off |
| 15539 | const operand_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; | 15551 | const elem_ty_src : LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 15540 | const ptr_src : LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; | 15552 | const ptr_src : LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; |
| 15541 | const op_src : LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node }; | 15553 | const op_src : LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node }; |
| 15542 | const operand_src : LazySrcLoc = .{ .node_offset_builtin_call_arg3 = inst_data.src_node }; | 15554 | const operand_src : LazySrcLoc = .{ .node_offset_builtin_call_arg3 = inst_data.src_node }; |
| 15543 | const order_src : LazySrcLoc = .{ .node_offset_builtin_call_arg4 = inst_data.src_node }; | 15555 | const order_src : LazySrcLoc = .{ .node_offset_builtin_call_arg4 = inst_data.src_node }; |
| 15544 | // zig fmt: on | 15556 | // zig fmt: on |
| 15545 | const ptr = sema.resolveInst(extra.ptr); | 15557 | const operand = sema.resolveInst(extra.operand); |
| 15546 | const ptr_ty = sema.typeOf(ptr); | 15558 | const elem_ty = sema.typeOf(operand); |
| 15547 | const operand_ty = ptr_ty.elemType(); | 15559 | const uncasted_ptr = sema.resolveInst(extra.ptr); |
| 15548 | try sema.checkAtomicOperandType(block, operand_ty_src, operand_ty); | 15560 | const ptr = try sema.checkAtomicPtrOperand(block, elem_ty, elem_ty_src, uncasted_ptr, ptr_src, false); |
| 15549 | const op = try sema.resolveAtomicRmwOp(block, op_src, extra.operation); | 15561 | const op = try sema.resolveAtomicRmwOp(block, op_src, extra.operation); |
| 15550 | | 15562 | |
| 15551 | switch (operand_ty.zigTypeTag()) { | 15563 | switch (elem_ty.zigTypeTag()) { |
| 15552 | .Enum => if (op != .Xchg) { | 15564 | .Enum => if (op != .Xchg) { |
| 15553 | return sema.fail(block, op_src, "@atomicRmw with enum only allowed with .Xchg", .{}); | 15565 | return sema.fail(block, op_src, "@atomicRmw with enum only allowed with .Xchg", .{}); |
| 15554 | }, | 15566 | }, |
| ... | @@ -15561,7 +15573,6 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -15561,7 +15573,6 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 15561 | }, | 15573 | }, |
| 15562 | else => {}, | 15574 | else => {}, |
| 15563 | } | 15575 | } |
| 15564 | const operand = try sema.coerce(block, operand_ty, sema.resolveInst(extra.operand), operand_src); | | |
| 15565 | const order = try sema.resolveAtomicOrder(block, order_src, extra.ordering); | 15576 | const order = try sema.resolveAtomicOrder(block, order_src, extra.ordering); |
| 15566 | | 15577 | |
| 15567 | if (order == .Unordered) { | 15578 | if (order == .Unordered) { |
| ... | @@ -15569,8 +15580,8 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -15569,8 +15580,8 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 15569 | } | 15580 | } |
| 15570 | | 15581 | |
| 15571 | // special case zero bit types | 15582 | // special case zero bit types |
| 15572 | if (try sema.typeHasOnePossibleValue(block, operand_ty_src, operand_ty)) |val| { | 15583 | if (try sema.typeHasOnePossibleValue(block, elem_ty_src, elem_ty)) |val| { |
| 15573 | return sema.addConstant(operand_ty, val); | 15584 | return sema.addConstant(elem_ty, val); |
| 15574 | } | 15585 | } |
| 15575 | | 15586 | |
| 15576 | const runtime_src = if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| rs: { | 15587 | const runtime_src = if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| rs: { |
| ... | @@ -15581,22 +15592,23 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -15581,22 +15592,23 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 15581 | }; | 15592 | }; |
| 15582 | if (ptr_val.isComptimeMutablePtr()) { | 15593 | if (ptr_val.isComptimeMutablePtr()) { |
| 15583 | const target = sema.mod.getTarget(); | 15594 | const target = sema.mod.getTarget(); |
| | 15595 | const ptr_ty = sema.typeOf(ptr); |
| 15584 | const stored_val = (try sema.pointerDeref(block, ptr_src, ptr_val, ptr_ty)) orelse break :rs ptr_src; | 15596 | const stored_val = (try sema.pointerDeref(block, ptr_src, ptr_val, ptr_ty)) orelse break :rs ptr_src; |
| 15585 | const new_val = switch (op) { | 15597 | const new_val = switch (op) { |
| 15586 | // zig fmt: off | 15598 | // zig fmt: off |
| 15587 | .Xchg => operand_val, | 15599 | .Xchg => operand_val, |
| 15588 | .Add => try stored_val.numberAddWrap(operand_val, operand_ty, sema.arena, target), | 15600 | .Add => try stored_val.numberAddWrap(operand_val, elem_ty, sema.arena, target), |
| 15589 | .Sub => try stored_val.numberSubWrap(operand_val, operand_ty, sema.arena, target), | 15601 | .Sub => try stored_val.numberSubWrap(operand_val, elem_ty, sema.arena, target), |
| 15590 | .And => try stored_val.bitwiseAnd (operand_val, operand_ty, sema.arena, target), | 15602 | .And => try stored_val.bitwiseAnd (operand_val, elem_ty, sema.arena, target), |
| 15591 | .Nand => try stored_val.bitwiseNand (operand_val, operand_ty, sema.arena, target), | 15603 | .Nand => try stored_val.bitwiseNand (operand_val, elem_ty, sema.arena, target), |
| 15592 | .Or => try stored_val.bitwiseOr (operand_val, operand_ty, sema.arena, target), | 15604 | .Or => try stored_val.bitwiseOr (operand_val, elem_ty, sema.arena, target), |
| 15593 | .Xor => try stored_val.bitwiseXor (operand_val, operand_ty, sema.arena, target), | 15605 | .Xor => try stored_val.bitwiseXor (operand_val, elem_ty, sema.arena, target), |
| 15594 | .Max => stored_val.numberMax (operand_val, target), | 15606 | .Max => stored_val.numberMax (operand_val, target), |
| 15595 | .Min => stored_val.numberMin (operand_val, target), | 15607 | .Min => stored_val.numberMin (operand_val, target), |
| 15596 | // zig fmt: on | 15608 | // zig fmt: on |
| 15597 | }; | 15609 | }; |
| 15598 | try sema.storePtrVal(block, src, ptr_val, new_val, operand_ty); | 15610 | try sema.storePtrVal(block, src, ptr_val, new_val, elem_ty); |
| 15599 | return sema.addConstant(operand_ty, stored_val); | 15611 | return sema.addConstant(elem_ty, stored_val); |
| 15600 | } else break :rs ptr_src; | 15612 | } else break :rs ptr_src; |
| 15601 | } else ptr_src; | 15613 | } else ptr_src; |
| 15602 | | 15614 | |
| ... | @@ -15620,15 +15632,15 @@ fn zirAtomicStore(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -15620,15 +15632,15 @@ fn zirAtomicStore(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 15620 | const extra = sema.code.extraData(Zir.Inst.AtomicStore, inst_data.payload_index).data; | 15632 | const extra = sema.code.extraData(Zir.Inst.AtomicStore, inst_data.payload_index).data; |
| 15621 | const src = inst_data.src(); | 15633 | const src = inst_data.src(); |
| 15622 | // zig fmt: off | 15634 | // zig fmt: off |
| 15623 | const operand_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; | 15635 | const elem_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 15624 | const ptr_src : LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; | 15636 | const ptr_src : LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; |
| 15625 | const operand_src : LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node }; | 15637 | const operand_src : LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node }; |
| 15626 | const order_src : LazySrcLoc = .{ .node_offset_builtin_call_arg3 = inst_data.src_node }; | 15638 | const order_src : LazySrcLoc = .{ .node_offset_builtin_call_arg3 = inst_data.src_node }; |
| 15627 | // zig fmt: on | 15639 | // zig fmt: on |
| 15628 | const ptr = sema.resolveInst(extra.ptr); | 15640 | const operand = sema.resolveInst(extra.operand); |
| 15629 | const operand_ty = sema.typeOf(ptr).elemType(); | 15641 | const elem_ty = sema.typeOf(operand); |
| 15630 | try sema.checkAtomicOperandType(block, operand_ty_src, operand_ty); | 15642 | const uncasted_ptr = sema.resolveInst(extra.ptr); |
| 15631 | const operand = try sema.coerce(block, operand_ty, sema.resolveInst(extra.operand), operand_src); | 15643 | const ptr = try sema.checkAtomicPtrOperand(block, elem_ty, elem_ty_src, uncasted_ptr, ptr_src, false); |
| 15632 | const order = try sema.resolveAtomicOrder(block, order_src, extra.ordering); | 15644 | const order = try sema.resolveAtomicOrder(block, order_src, extra.ordering); |
| 15633 | | 15645 | |
| 15634 | const air_tag: Air.Inst.Tag = switch (order) { | 15646 | const air_tag: Air.Inst.Tag = switch (order) { |