authorgravatar for paul.verigo@gmail.comPavel Verigo <paul.verigo@gmail.com> 2026-08-21 00:44:06+02:00
committergravatar for paul.verigo@gmail.comPavel Verigo <paul.verigo@gmail.com> 2026-09-17 00:04:51+02:00
log5ec1668eb4cee3ce3069f6ff7b2e3af0d52f43a6
tree3bf79bb99c9056b7ca4c0175d2fd4d5b4d01886e
parent39512c3e5547b411294369c8eec8093045f74d64

wasm: remove reuseOperand


1 files changed, 41 insertions(+), 59 deletions(-)

src/codegen/wasm/CodeGen.zig+41-59
...@@ -421,6 +421,20 @@ fn resolveValue(cg: *CodeGen, val: Value) InnerError!WValue {...@@ -421,6 +421,20 @@ fn resolveValue(cg: *CodeGen, val: Value) InnerError!WValue {
421/// NOTE: if result == .stack, it will be stored in .local421/// NOTE: if result == .stack, it will be stored in .local
422fn finishAir(cg: *CodeGen, inst: Air.Inst.Index, result: WValue, operands: []const Air.Inst.Ref) InnerError!void {422fn finishAir(cg: *CodeGen, inst: Air.Inst.Index, result: WValue, operands: []const Air.Inst.Ref) InnerError!void {
423 assert(operands.len <= Air.Liveness.bpi - 1);423 assert(operands.len <= Air.Liveness.bpi - 1);
424
425 var final_result = result;
426 const aliased_operand: ?*WValue = if (result == .local) aliased: {
427 for (operands) |operand| {
428 if (operand.toIndex() == null) continue;
429 const resolved_operand = cg.getResolvedInst(operand);
430 if (resolved_operand.* != .local or resolved_operand.local.value != result.local.value) continue;
431
432 resolved_operand.local.references += 1;
433 break :aliased resolved_operand;
434 }
435 break :aliased null;
436 } else null;
437
424 var tomb_bits = cg.liveness.getTombBits(inst);438 var tomb_bits = cg.liveness.getTombBits(inst);
425 for (operands) |operand| {439 for (operands) |operand| {
426 const dies = @as(u1, @truncate(tomb_bits)) != 0;440 const dies = @as(u1, @truncate(tomb_bits)) != 0;
...@@ -428,7 +442,8 @@ fn finishAir(cg: *CodeGen, inst: Air.Inst.Index, result: WValue, operands: []con...@@ -428,7 +442,8 @@ fn finishAir(cg: *CodeGen, inst: Air.Inst.Index, result: WValue, operands: []con
428 if (!dies) continue;442 if (!dies) continue;
429 processDeath(cg, operand);443 processDeath(cg, operand);
430 }444 }
431 try cg.finishAirResult(inst, result);445 if (aliased_operand) |operand| final_result.local.references = operand.local.references;
446 try cg.finishAirResult(inst, final_result);
432}447}
433448
434fn finishAirResult(cg: *CodeGen, inst: Air.Inst.Index, result: WValue) InnerError!void {449fn finishAirResult(cg: *CodeGen, inst: Air.Inst.Index, result: WValue) InnerError!void {
...@@ -478,7 +493,7 @@ fn processDeath(cg: *CodeGen, ref: Air.Inst.Ref) void {...@@ -478,7 +493,7 @@ fn processDeath(cg: *CodeGen, ref: Air.Inst.Ref) void {
478 return; // function arguments can never be re-used493 return; // function arguments can never be re-used
479 }494 }
480 log.debug("Decreasing reference for ref: %{d}, using local '{d}'", .{ @backingInt(ref.toIndex().?), value.local.value });495 log.debug("Decreasing reference for ref: %{d}, using local '{d}'", .{ @backingInt(ref.toIndex().?), value.local.value });
481 value.local.references -= 1; // if this panics, a call to `reuseOperand` was forgotten by the developer496 value.local.references -= 1;
482 if (value.local.references == 0) {497 if (value.local.references == 0) {
483 value.free(cg);498 value.free(cg);
484 }499 }
...@@ -631,7 +646,7 @@ fn genBlockType(ty: Type, zcu: *const Zcu, target: *const std.Target) std.wasm.B...@@ -631,7 +646,7 @@ fn genBlockType(ty: Type, zcu: *const Zcu, target: *const std.Target) std.wasm.B
631/// Writes the bytecode depending on the given `WValue` in `val`646/// Writes the bytecode depending on the given `WValue` in `val`
632fn emitWValue(cg: *CodeGen, value: WValue) InnerError!void {647fn emitWValue(cg: *CodeGen, value: WValue) InnerError!void {
633 switch (value) {648 switch (value) {
634 .dead => unreachable, // reference to free'd `WValue` (missing reuseOperand?)649 .dead => unreachable, // reference to free'd `WValue`
635 .none, .stack => {}, // no-op650 .none, .stack => {}, // no-op
636 .local => |idx| try cg.addLocal(.local_get, idx.value),651 .local => |idx| try cg.addLocal(.local_get, idx.value),
637 .imm32 => |val| try cg.addImm32(val),652 .imm32 => |val| try cg.addImm32(val),
...@@ -699,23 +714,6 @@ fn emitWValue(cg: *CodeGen, value: WValue) InnerError!void {...@@ -699,23 +714,6 @@ fn emitWValue(cg: *CodeGen, value: WValue) InnerError!void {
699 }714 }
700}715}
701716
702/// If given a local or stack-offset, increases the reference count by 1.
703/// The old `WValue` found at instruction `ref` is then replaced by the
704/// modified `WValue` and returned. When given a non-local or non-stack-offset,
705/// returns the given `operand` itfunc instead.
706fn reuseOperand(cg: *CodeGen, ref: Air.Inst.Ref, operand: WValue) WValue {
707 if (operand != .local and operand != .stack_offset) return operand;
708 var new_value = operand;
709 switch (new_value) {
710 .local => |*local| local.references += 1,
711 .stack_offset => |*stack_offset| stack_offset.references += 1,
712 else => unreachable,
713 }
714 const old_value = cg.getResolvedInst(ref);
715 old_value.* = new_value;
716 return new_value;
717}
718
719/// From a reference, returns its resolved `WValue`.717/// From a reference, returns its resolved `WValue`.
720/// It's illegal to provide a `Air.Inst.Ref` that hasn't been resolved yet.718/// It's illegal to provide a `Air.Inst.Ref` that hasn't been resolved yet.
721fn getResolvedInst(cg: *CodeGen, ref: Air.Inst.Ref) *WValue {719fn getResolvedInst(cg: *CodeGen, ref: Air.Inst.Ref) *WValue {
...@@ -1598,17 +1596,7 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -1598,17 +1596,7 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
1598 const src_int_ty: IntType = .fromType(cg, src_ty);1596 const src_int_ty: IntType = .fromType(cg, src_ty);
1599 const dest_int_ty: IntType = .fromType(cg, dest_ty);1597 const dest_int_ty: IntType = .fromType(cg, dest_ty);
16001598
1601 const src_bits = src_int_ty.bits;1599 const result = try cg.intCast(dest_int_ty, src_int_ty, operand);
1602 const dest_bits = dest_int_ty.bits;
1603
1604 const same_class: bool = (src_bits <= 32 and dest_bits <= 32) or
1605 (src_bits >= 33 and src_bits <= 64 and dest_bits >= 33 and dest_bits <= 64) or
1606 (src_bits >= 65 and src_bits <= 128 and dest_bits >= 65 and dest_bits <= 128);
1607
1608 const result = if (same_class)
1609 cg.reuseOperand(ty_op.operand, operand)
1610 else
1611 try cg.intCast(dest_int_ty, src_int_ty, operand);
16121600
1613 try cg.finishAir(inst, result, &.{ty_op.operand});1601 try cg.finishAir(inst, result, &.{ty_op.operand});
1614 },1602 },
...@@ -1625,12 +1613,7 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -1625,12 +1613,7 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
16251613
1626 const src_int_ty: IntType = .fromType(cg, src_ty);1614 const src_int_ty: IntType = .fromType(cg, src_ty);
1627 const dest_int_ty: IntType = .fromType(cg, dest_ty);1615 const dest_int_ty: IntType = .fromType(cg, dest_ty);
16281616 const result = try cg.intTrunc(dest_int_ty, src_int_ty, operand);
1629 const result = if (src_int_ty.bits == dest_int_ty.bits)
1630 cg.reuseOperand(ty_op.operand, operand)
1631 else blk: {
1632 break :blk try cg.intTrunc(dest_int_ty, src_int_ty, operand);
1633 };
16341617
1635 try cg.finishAir(inst, result, &.{ty_op.operand});1618 try cg.finishAir(inst, result, &.{ty_op.operand});
1636 },1619 },
...@@ -4259,6 +4242,7 @@ fn intCast(cg: *CodeGen, dest_ty: IntType, src_ty: IntType, operand: WValue) Inn...@@ -4259,6 +4242,7 @@ fn intCast(cg: *CodeGen, dest_ty: IntType, src_ty: IntType, operand: WValue) Inn
4259}4242}
42604243
4261fn intTrunc(cg: *CodeGen, dest_ty: IntType, src_ty: IntType, operand: WValue) InnerError!WValue {4244fn intTrunc(cg: *CodeGen, dest_ty: IntType, src_ty: IntType, operand: WValue) InnerError!WValue {
4245 assert(src_ty.bits > dest_ty.bits);
4262 var result = try cg.intCast(dest_ty, src_ty, operand);4246 var result = try cg.intCast(dest_ty, src_ty, operand);
42634247
4264 const dest_wasm_bits = cg.intBackingBits(dest_ty.bits);4248 const dest_wasm_bits = cg.intBackingBits(dest_ty.bits);
...@@ -5584,8 +5568,7 @@ fn airNopCast(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5584,8 +5568,7 @@ fn airNopCast(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5584 assert(operand_ty.abiAlignment(zcu) == dest_ty.abiAlignment(zcu));5568 assert(operand_ty.abiAlignment(zcu) == dest_ty.abiAlignment(zcu));
55855569
5586 const operand = try cg.resolveInst(ty_op.operand);5570 const operand = try cg.resolveInst(ty_op.operand);
5587 const result = cg.reuseOperand(ty_op.operand, operand);5571 return cg.finishAir(inst, operand, &.{ty_op.operand});
5588 return cg.finishAir(inst, result, &.{ty_op.operand});
5589}5572}
55905573
5591fn airIntFromPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {5574fn airIntFromPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
...@@ -5601,7 +5584,7 @@ fn airIntFromPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5601,7 +5584,7 @@ fn airIntFromPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5601 const operand = try cg.resolveInst(ty_op.operand);5584 const operand = try cg.resolveInst(ty_op.operand);
5602 const result = switch (operand) {5585 const result = switch (operand) {
5603 .stack_offset => try cg.buildPointerOffset(operand, 0, .new),5586 .stack_offset => try cg.buildPointerOffset(operand, 0, .new),
5604 else => cg.reuseOperand(ty_op.operand, operand),5587 else => operand,
5605 };5588 };
5606 return cg.finishAir(inst, result, &.{ty_op.operand});5589 return cg.finishAir(inst, result, &.{ty_op.operand});
5607}5590}
...@@ -5627,7 +5610,7 @@ fn airBitcast(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5627,7 +5610,7 @@ fn airBitcast(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5627 const dest_ty = cg.typeOfIndex(inst);5610 const dest_ty = cg.typeOfIndex(inst);
5628 const src_ty = cg.typeOf(ty_op.operand);5611 const src_ty = cg.typeOf(ty_op.operand);
56295612
5630 const result = (try cg.bitcast(dest_ty, src_ty, operand)) orelse cg.reuseOperand(ty_op.operand, operand);5613 const result = try cg.bitcast(dest_ty, src_ty, operand);
56315614
5632 return cg.finishAir(inst, result, &.{ty_op.operand});5615 return cg.finishAir(inst, result, &.{ty_op.operand});
5633}5616}
...@@ -5654,8 +5637,8 @@ fn bitcastClass(cg: *CodeGen, ty: Type) BitcastClass {...@@ -5654,8 +5637,8 @@ fn bitcastClass(cg: *CodeGen, ty: Type) BitcastClass {
5654 };5637 };
5655}5638}
56565639
5657fn bitcast(cg: *CodeGen, dest_ty: Type, src_ty: Type, operand: WValue) InnerError!?WValue {5640fn bitcast(cg: *CodeGen, dest_ty: Type, src_ty: Type, operand: WValue) InnerError!WValue {
5658 if (dest_ty.eql(src_ty)) return null;5641 if (dest_ty.eql(src_ty)) return operand;
56595642
5660 const zcu = cg.pt.zcu;5643 const zcu = cg.pt.zcu;
5661 const src_class = cg.bitcastClass(src_ty);5644 const src_class = cg.bitcastClass(src_ty);
...@@ -5674,7 +5657,7 @@ fn bitcast(cg: *CodeGen, dest_ty: Type, src_ty: Type, operand: WValue) InnerErro...@@ -5674,7 +5657,7 @@ fn bitcast(cg: *CodeGen, dest_ty: Type, src_ty: Type, operand: WValue) InnerErro
56745657
5675 if (src_by_ref and dest_by_ref) {5658 if (src_by_ref and dest_by_ref) {
5676 if (needs_wrapping) return try cg.intWrap(dest_class.int, operand);5659 if (needs_wrapping) return try cg.intWrap(dest_class.int, operand);
5677 return null;5660 return operand;
5678 }5661 }
56795662
5680 if (dest_by_ref) {5663 if (dest_by_ref) {
...@@ -5708,7 +5691,7 @@ fn bitcast(cg: *CodeGen, dest_ty: Type, src_ty: Type, operand: WValue) InnerErro...@@ -5708,7 +5691,7 @@ fn bitcast(cg: *CodeGen, dest_ty: Type, src_ty: Type, operand: WValue) InnerErro
57085691
5709 switch (dest_class) {5692 switch (dest_class) {
5710 .float => |float_ty| switch (float_ty) {5693 .float => |float_ty| switch (float_ty) {
5711 .f16 => return null,5694 .f16 => return operand,
5712 .f32 => {5695 .f32 => {
5713 try cg.emitWValue(operand);5696 try cg.emitWValue(operand);
5714 try cg.addTag(.f32_reinterpret_i32);5697 try cg.addTag(.f32_reinterpret_i32);
...@@ -5729,7 +5712,7 @@ fn bitcast(cg: *CodeGen, dest_ty: Type, src_ty: Type, operand: WValue) InnerErro...@@ -5729,7 +5712,7 @@ fn bitcast(cg: *CodeGen, dest_ty: Type, src_ty: Type, operand: WValue) InnerErro
5729 return try cg.intWrap(dest_class.int, operand);5712 return try cg.intWrap(dest_class.int, operand);
5730 }5713 }
57315714
5732 return null;5715 return operand;
5733}5716}
57345717
5735fn airStructFieldPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {5718fn airStructFieldPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
...@@ -5740,7 +5723,7 @@ fn airStructFieldPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5740,7 +5723,7 @@ fn airStructFieldPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5740 const struct_ptr = try cg.resolveInst(extra.data.struct_operand);5723 const struct_ptr = try cg.resolveInst(extra.data.struct_operand);
5741 const struct_ptr_ty = cg.typeOf(extra.data.struct_operand);5724 const struct_ptr_ty = cg.typeOf(extra.data.struct_operand);
5742 const struct_ty = struct_ptr_ty.childType(zcu);5725 const struct_ty = struct_ptr_ty.childType(zcu);
5743 const result = try cg.structFieldPtr(inst, extra.data.struct_operand, struct_ptr, struct_ptr_ty, struct_ty, extra.data.field_index);5726 const result = try cg.structFieldPtr(inst, struct_ptr, struct_ptr_ty, struct_ty, extra.data.field_index);
5744 return cg.finishAir(inst, result, &.{extra.data.struct_operand});5727 return cg.finishAir(inst, result, &.{extra.data.struct_operand});
5745}5728}
57465729
...@@ -5751,14 +5734,13 @@ fn airStructFieldPtrIndex(cg: *CodeGen, inst: Air.Inst.Index, index: u32) InnerE...@@ -5751,14 +5734,13 @@ fn airStructFieldPtrIndex(cg: *CodeGen, inst: Air.Inst.Index, index: u32) InnerE
5751 const struct_ptr_ty = cg.typeOf(ty_op.operand);5734 const struct_ptr_ty = cg.typeOf(ty_op.operand);
5752 const struct_ty = struct_ptr_ty.childType(zcu);5735 const struct_ty = struct_ptr_ty.childType(zcu);
57535736
5754 const result = try cg.structFieldPtr(inst, ty_op.operand, struct_ptr, struct_ptr_ty, struct_ty, index);5737 const result = try cg.structFieldPtr(inst, struct_ptr, struct_ptr_ty, struct_ty, index);
5755 return cg.finishAir(inst, result, &.{ty_op.operand});5738 return cg.finishAir(inst, result, &.{ty_op.operand});
5756}5739}
57575740
5758fn structFieldPtr(5741fn structFieldPtr(
5759 cg: *CodeGen,5742 cg: *CodeGen,
5760 inst: Air.Inst.Index,5743 inst: Air.Inst.Index,
5761 ref: Air.Inst.Ref,
5762 struct_ptr: WValue,5744 struct_ptr: WValue,
5763 struct_ptr_ty: Type,5745 struct_ptr_ty: Type,
5764 struct_ty: Type,5746 struct_ty: Type,
...@@ -5785,7 +5767,7 @@ fn structFieldPtr(...@@ -5785,7 +5767,7 @@ fn structFieldPtr(
5785 };5767 };
5786 // save a load and store when we can simply reuse the operand5768 // save a load and store when we can simply reuse the operand
5787 if (offset == 0) {5769 if (offset == 0) {
5788 return cg.reuseOperand(ref, struct_ptr);5770 return struct_ptr;
5789 }5771 }
5790 switch (struct_ptr) {5772 switch (struct_ptr) {
5791 .stack_offset => |stack_offset| {5773 .stack_offset => |stack_offset| {
...@@ -6092,7 +6074,7 @@ fn airUnwrapErrUnionPayload(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool)...@@ -6092,7 +6074,7 @@ fn airUnwrapErrUnionPayload(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool)
6092 const result: WValue = result: {6074 const result: WValue = result: {
6093 if (!payload_ty.hasRuntimeBits(zcu)) {6075 if (!payload_ty.hasRuntimeBits(zcu)) {
6094 if (op_is_ptr) {6076 if (op_is_ptr) {
6095 break :result cg.reuseOperand(ty_op.operand, operand);6077 break :result operand;
6096 } else {6078 } else {
6097 break :result .none;6079 break :result .none;
6098 }6080 }
...@@ -6131,7 +6113,7 @@ fn airUnwrapErrUnionError(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) I...@@ -6131,7 +6113,7 @@ fn airUnwrapErrUnionError(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) I
6131 break :result try cg.load(operand, Type.anyerror, err_offset);6113 break :result try cg.load(operand, Type.anyerror, err_offset);
6132 } else {6114 } else {
6133 assert(!payload_ty.hasRuntimeBits(zcu));6115 assert(!payload_ty.hasRuntimeBits(zcu));
6134 break :result cg.reuseOperand(ty_op.operand, operand);6116 break :result operand;
6135 }6117 }
6136 };6118 };
6137 return cg.finishAir(inst, result, &.{ty_op.operand});6119 return cg.finishAir(inst, result, &.{ty_op.operand});
...@@ -6147,7 +6129,7 @@ fn airWrapErrUnionPayload(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6147,7 +6129,7 @@ fn airWrapErrUnionPayload(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6147 const pl_ty = cg.typeOf(ty_op.operand);6129 const pl_ty = cg.typeOf(ty_op.operand);
6148 const result = result: {6130 const result = result: {
6149 if (!pl_ty.hasRuntimeBits(zcu)) {6131 if (!pl_ty.hasRuntimeBits(zcu)) {
6150 break :result cg.reuseOperand(ty_op.operand, operand);6132 break :result operand;
6151 }6133 }
61526134
6153 const err_union = try cg.allocStack(err_ty);6135 const err_union = try cg.allocStack(err_ty);
...@@ -6177,7 +6159,7 @@ fn airWrapErrUnionErr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6177,7 +6159,7 @@ fn airWrapErrUnionErr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
61776159
6178 const result = result: {6160 const result = result: {
6179 if (!pl_ty.hasRuntimeBits(zcu)) {6161 if (!pl_ty.hasRuntimeBits(zcu)) {
6180 break :result cg.reuseOperand(ty_op.operand, operand);6162 break :result operand;
6181 }6163 }
61826164
6183 const err_union = try cg.allocStack(err_ty);6165 const err_union = try cg.allocStack(err_ty);
...@@ -6257,7 +6239,7 @@ fn airOptionalPayload(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6257,7 +6239,7 @@ fn airOptionalPayload(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
62576239
6258 const result = result: {6240 const result = result: {
6259 const operand = try cg.resolveInst(ty_op.operand);6241 const operand = try cg.resolveInst(ty_op.operand);
6260 if (opt_ty.optionalReprIsPayload(zcu)) break :result cg.reuseOperand(ty_op.operand, operand);6242 if (opt_ty.optionalReprIsPayload(zcu)) break :result operand;
62616243
6262 if (isByRef(payload_ty, zcu, cg.target)) {6244 if (isByRef(payload_ty, zcu, cg.target)) {
6263 break :result try cg.buildPointerOffset(operand, 0, .new);6245 break :result try cg.buildPointerOffset(operand, 0, .new);
...@@ -6277,7 +6259,7 @@ fn airOptionalPayloadPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6277,7 +6259,7 @@ fn airOptionalPayloadPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6277 const result = result: {6259 const result = result: {
6278 const payload_ty = opt_ty.optionalChild(zcu);6260 const payload_ty = opt_ty.optionalChild(zcu);
6279 if (!payload_ty.hasRuntimeBits(zcu) or opt_ty.optionalReprIsPayload(zcu)) {6261 if (!payload_ty.hasRuntimeBits(zcu) or opt_ty.optionalReprIsPayload(zcu)) {
6280 break :result cg.reuseOperand(ty_op.operand, operand);6262 break :result operand;
6281 }6263 }
62826264
6283 break :result try cg.buildPointerOffset(operand, 0, .new);6265 break :result try cg.buildPointerOffset(operand, 0, .new);
...@@ -6327,7 +6309,7 @@ fn airWrapOptional(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6327,7 +6309,7 @@ fn airWrapOptional(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6327 const operand = try cg.resolveInst(ty_op.operand);6309 const operand = try cg.resolveInst(ty_op.operand);
6328 const op_ty = cg.typeOfIndex(inst);6310 const op_ty = cg.typeOfIndex(inst);
6329 if (op_ty.optionalReprIsPayload(zcu)) {6311 if (op_ty.optionalReprIsPayload(zcu)) {
6330 break :result cg.reuseOperand(ty_op.operand, operand);6312 break :result operand;
6331 }6313 }
6332 const offset = std.math.cast(u32, payload_ty.abiSize(zcu)) orelse {6314 const offset = std.math.cast(u32, payload_ty.abiSize(zcu)) orelse {
6333 return cg.fail("Optional type {f} too big to fit into stack frame", .{op_ty.fmt(pt)});6315 return cg.fail("Optional type {f} too big to fit into stack frame", .{op_ty.fmt(pt)});
...@@ -7146,7 +7128,7 @@ fn airErrUnionPayloadPtrSet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void...@@ -7146,7 +7128,7 @@ fn airErrUnionPayloadPtrSet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void
71467128
7147 const result = result: {7129 const result = result: {
7148 if (!payload_ty.hasRuntimeBits(zcu)) {7130 if (!payload_ty.hasRuntimeBits(zcu)) {
7149 break :result cg.reuseOperand(ty_op.operand, operand);7131 break :result operand;
7150 }7132 }
71517133
7152 break :result try cg.buildPointerOffset(operand, @as(u32, @intCast(errUnionPayloadOffset(payload_ty, zcu))), .new);7134 break :result try cg.buildPointerOffset(operand, @as(u32, @intCast(errUnionPayloadOffset(payload_ty, zcu))), .new);
...@@ -7182,7 +7164,7 @@ fn airFieldParentPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7182,7 +7164,7 @@ fn airFieldParentPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7182 try cg.addTag(.i32_sub);7164 try cg.addTag(.i32_sub);
7183 try cg.addLocal(.local_set, base.local.value);7165 try cg.addLocal(.local_set, base.local.value);
7184 break :result base;7166 break :result base;
7185 } else cg.reuseOperand(extra.field_ptr, field_ptr);7167 } else field_ptr;
71867168
7187 return cg.finishAir(inst, result, &.{extra.field_ptr});7169 return cg.finishAir(inst, result, &.{extra.field_ptr});
7188}7170}