Commit 31706dc31a

Pavel Verigo <paul.verigo@gmail.com>
2024-07-05 20:25:39
stage2-wasm: finishAir handle .stack result
By allowing finishAir to handle .stack results, we simplify a lot of code in air*** functions, which try to handle this case. Also this changes will result in optimization, if one of operands is dead after instruction its place could be reused by result. The only downside to this change is that finishAir now can return error, though it handled by returning finishAir result, because it always needs to be final in air*** functions. Additionally I migrated WValue{ to .{ inside CodeGen.zig.
1 parent 6eb76f9
Changed files (1)
src
arch
src/arch/wasm/CodeGen.zig
@@ -793,7 +793,7 @@ fn resolveInst(func: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue {
     const val = (try func.air.value(ref, pt)).?;
     const ty = func.typeOf(ref);
     if (!ty.hasRuntimeBitsIgnoreComptime(pt) and !ty.isInt(mod) and !ty.isError(mod)) {
-        gop.value_ptr.* = WValue{ .none = {} };
+        gop.value_ptr.* = .none;
         return gop.value_ptr.*;
     }
 
@@ -803,16 +803,17 @@ fn resolveInst(func: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue {
     //
     // In the other cases, we will simply lower the constant to a value that fits
     // into a single local (such as a pointer, integer, bool, etc).
-    const result = if (isByRef(ty, pt)) blk: {
-        const sym_index = try func.bin_file.lowerUnnamedConst(pt, val, func.decl_index);
-        break :blk WValue{ .memory = sym_index };
-    } else try func.lowerConstant(val, ty);
+    const result: WValue = if (isByRef(ty, pt))
+        .{ .memory = try func.bin_file.lowerUnnamedConst(pt, val, func.decl_index) }
+    else
+        try func.lowerConstant(val, ty);
 
     gop.value_ptr.* = result;
     return result;
 }
 
-fn finishAir(func: *CodeGen, inst: Air.Inst.Index, result: WValue, operands: []const Air.Inst.Ref) void {
+/// NOTE: if result == .stack, it will be stored in .local
+fn finishAir(func: *CodeGen, inst: Air.Inst.Index, result: WValue, operands: []const Air.Inst.Ref) InnerError!void {
     assert(operands.len <= Liveness.bpi - 1);
     var tomb_bits = func.liveness.getTombBits(inst);
     for (operands) |operand| {
@@ -824,9 +825,12 @@ fn finishAir(func: *CodeGen, inst: Air.Inst.Index, result: WValue, operands: []c
 
     // results of `none` can never be referenced.
     if (result != .none) {
-        assert(result != .stack); // it's illegal to store a stack value as we cannot track its position
+        const trackable_result = if (result != .stack)
+            result
+        else
+            try result.toLocal(func, func.typeOfIndex(inst));
         const branch = func.currentBranch();
-        branch.values.putAssumeCapacityNoClobber(inst.toRef(), result);
+        branch.values.putAssumeCapacityNoClobber(inst.toRef(), trackable_result);
     }
 
     if (std.debug.runtime_safety) {
@@ -1105,30 +1109,18 @@ fn getResolvedInst(func: *CodeGen, ref: Air.Inst.Ref) *WValue {
 fn allocLocal(func: *CodeGen, ty: Type) InnerError!WValue {
     const pt = func.pt;
     const valtype = typeToValtype(ty, pt);
-    switch (valtype) {
-        .i32 => if (func.free_locals_i32.popOrNull()) |index| {
-            log.debug("reusing local ({d}) of type {}", .{ index, valtype });
-            return WValue{ .local = .{ .value = index, .references = 1 } };
-        },
-        .i64 => if (func.free_locals_i64.popOrNull()) |index| {
-            log.debug("reusing local ({d}) of type {}", .{ index, valtype });
-            return WValue{ .local = .{ .value = index, .references = 1 } };
-        },
-        .f32 => if (func.free_locals_f32.popOrNull()) |index| {
-            log.debug("reusing local ({d}) of type {}", .{ index, valtype });
-            return WValue{ .local = .{ .value = index, .references = 1 } };
-        },
-        .f64 => if (func.free_locals_f64.popOrNull()) |index| {
-            log.debug("reusing local ({d}) of type {}", .{ index, valtype });
-            return WValue{ .local = .{ .value = index, .references = 1 } };
-        },
-        .v128 => if (func.free_locals_v128.popOrNull()) |index| {
-            log.debug("reusing local ({d}) of type {}", .{ index, valtype });
-            return WValue{ .local = .{ .value = index, .references = 1 } };
-        },
+    const index_or_null = switch (valtype) {
+        .i32 => func.free_locals_i32.popOrNull(),
+        .i64 => func.free_locals_i64.popOrNull(),
+        .f32 => func.free_locals_f32.popOrNull(),
+        .f64 => func.free_locals_f64.popOrNull(),
+        .v128 => func.free_locals_v128.popOrNull(),
+    };
+    if (index_or_null) |index| {
+        log.debug("reusing local ({d}) of type {}", .{ index, valtype });
+        return .{ .local = .{ .value = index, .references = 1 } };
     }
     log.debug("new local of type {}", .{valtype});
-    // no local was free to be re-used, so allocate a new local instead
     return func.ensureAllocLocal(ty);
 }
 
@@ -1139,7 +1131,7 @@ fn ensureAllocLocal(func: *CodeGen, ty: Type) InnerError!WValue {
     try func.locals.append(func.gpa, genValtype(ty, pt));
     const initial_index = func.local_index;
     func.local_index += 1;
-    return WValue{ .local = .{ .value = initial_index, .references = 1 } };
+    return .{ .local = .{ .value = initial_index, .references = 1 } };
 }
 
 /// Generates a `wasm.Type` from a given function type.
@@ -1539,7 +1531,7 @@ fn allocStack(func: *CodeGen, ty: Type) !WValue {
     const offset: u32 = @intCast(abi_align.forward(func.stack_size));
     defer func.stack_size = offset + abi_size;
 
-    return WValue{ .stack_offset = .{ .value = offset, .references = 1 } };
+    return .{ .stack_offset = .{ .value = offset, .references = 1 } };
 }
 
 /// From a given AIR instruction generates a pointer to the stack where
@@ -1571,7 +1563,7 @@ fn allocStackPtr(func: *CodeGen, inst: Air.Inst.Index) !WValue {
     const offset: u32 = @intCast(abi_alignment.forward(func.stack_size));
     defer func.stack_size = offset + abi_size;
 
-    return WValue{ .stack_offset = .{ .value = offset, .references = 1 } };
+    return .{ .stack_offset = .{ .value = offset, .references = 1 } };
 }
 
 /// From given zig bitsize, returns the wasm bitsize
@@ -2135,7 +2127,7 @@ fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     try func.restoreStackPointer();
     try func.addTag(.@"return");
 
-    func.finishAir(inst, .none, &.{un_op});
+    return func.finishAir(inst, .none, &.{un_op});
 }
 
 fn airRetPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -2156,7 +2148,7 @@ fn airRetPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
         break :result try func.allocStackPtr(inst);
     };
 
-    func.finishAir(inst, result, &.{});
+    return func.finishAir(inst, result, &.{});
 }
 
 fn airRetLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -2234,11 +2226,11 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
         return func.fail("Expected a function, but instead found '{s}'", .{@tagName(ip.indexToKey(func_val.toIntern()))});
     };
 
-    const sret = if (first_param_sret) blk: {
+    const sret: WValue = if (first_param_sret) blk: {
         const sret_local = try func.allocStack(ret_ty);
         try func.lowerToStack(sret_local);
         break :blk sret_local;
-    } else WValue{ .none = {} };
+    } else .none;
 
     for (args) |arg| {
         const arg_val = try func.resolveInst(arg);
@@ -2268,10 +2260,10 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
 
     const result_value = result_value: {
         if (!ret_ty.hasRuntimeBitsIgnoreComptime(pt) and !ret_ty.isError(mod)) {
-            break :result_value WValue{ .none = {} };
+            break :result_value .none;
         } else if (ret_ty.isNoReturn(mod)) {
             try func.addTag(.@"unreachable");
-            break :result_value WValue{ .none = {} };
+            break :result_value .none;
         } else if (first_param_sret) {
             break :result_value sret;
             // TODO: Make this less fragile and optimize
@@ -2297,7 +2289,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
 
 fn airAlloc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     const value = try func.allocStackPtr(inst);
-    func.finishAir(inst, value, &.{});
+    return func.finishAir(inst, value, &.{});
 }
 
 fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void {
@@ -2330,18 +2322,18 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void
         var mask = @as(u64, @intCast((@as(u65, 1) << @as(u7, @intCast(ty.bitSize(pt)))) - 1));
         mask <<= @as(u6, @intCast(ptr_info.packed_offset.bit_offset));
         mask ^= ~@as(u64, 0);
-        const shift_val = if (ptr_info.packed_offset.host_size <= 4)
-            WValue{ .imm32 = ptr_info.packed_offset.bit_offset }
+        const shift_val: WValue = if (ptr_info.packed_offset.host_size <= 4)
+            .{ .imm32 = ptr_info.packed_offset.bit_offset }
         else
-            WValue{ .imm64 = ptr_info.packed_offset.bit_offset };
-        const mask_val = if (ptr_info.packed_offset.host_size <= 4)
-            WValue{ .imm32 = @as(u32, @truncate(mask)) }
+            .{ .imm64 = ptr_info.packed_offset.bit_offset };
+        const mask_val: WValue = if (ptr_info.packed_offset.host_size <= 4)
+            .{ .imm32 = @as(u32, @truncate(mask)) }
         else
-            WValue{ .imm64 = mask };
-        const wrap_mask_val = if (ptr_info.packed_offset.host_size <= 4)
-            WValue{ .imm32 = @truncate(~@as(u64, 0) >> @intCast(64 - ty.bitSize(pt))) }
+            .{ .imm64 = mask };
+        const wrap_mask_val: WValue = if (ptr_info.packed_offset.host_size <= 4)
+            .{ .imm32 = @truncate(~@as(u64, 0) >> @intCast(64 - ty.bitSize(pt))) }
         else
-            WValue{ .imm64 = ~@as(u64, 0) >> @intCast(64 - ty.bitSize(pt)) };
+            .{ .imm64 = ~@as(u64, 0) >> @intCast(64 - ty.bitSize(pt)) };
 
         try func.emitWValue(lhs);
         const loaded = try func.load(lhs, int_elem_ty, 0);
@@ -2356,7 +2348,7 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void
         try func.store(.stack, result, int_elem_ty, lhs.offset());
     }
 
-    func.finishAir(inst, .none, &.{ bin_op.lhs, bin_op.rhs });
+    return func.finishAir(inst, .none, &.{ bin_op.lhs, bin_op.rhs });
 }
 
 fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerError!void {
@@ -2418,23 +2410,23 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE
                 // lower it to the stack so we do not have to store rhs into a local first
                 try func.emitWValue(lhs);
                 const ptr_local = try func.load(rhs, Type.usize, 0);
-                try func.store(.{ .stack = {} }, ptr_local, Type.usize, 0 + lhs.offset());
+                try func.store(.stack, ptr_local, Type.usize, 0 + lhs.offset());
 
                 // retrieve length from rhs, and store that alongside lhs as well
                 try func.emitWValue(lhs);
                 const len_local = try func.load(rhs, Type.usize, func.ptrSize());
-                try func.store(.{ .stack = {} }, len_local, Type.usize, func.ptrSize() + lhs.offset());
+                try func.store(.stack, len_local, Type.usize, func.ptrSize() + lhs.offset());
                 return;
             }
         },
         .Int, .Enum, .Float => if (abi_size > 8 and abi_size <= 16) {
             try func.emitWValue(lhs);
             const lsb = try func.load(rhs, Type.u64, 0);
-            try func.store(.{ .stack = {} }, lsb, Type.u64, 0 + lhs.offset());
+            try func.store(.stack, lsb, Type.u64, 0 + lhs.offset());
 
             try func.emitWValue(lhs);
             const msb = try func.load(rhs, Type.u64, 8);
-            try func.store(.{ .stack = {} }, msb, Type.u64, 8 + lhs.offset());
+            try func.store(.stack, msb, Type.u64, 8 + lhs.offset());
             return;
         } else if (abi_size > 16) {
             try func.memcpy(lhs, rhs, .{ .imm32 = @as(u32, @intCast(ty.abiSize(pt))) });
@@ -2487,27 +2479,24 @@ fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
         }
 
         if (ptr_info.packed_offset.host_size == 0) {
-            const stack_loaded = try func.load(operand, ty, 0);
-            break :result try stack_loaded.toLocal(func, ty);
+            break :result try func.load(operand, ty, 0);
         }
 
         // at this point we have a non-natural alignment, we must
         // shift the value to obtain the correct bit.
         const int_elem_ty = try pt.intType(.unsigned, ptr_info.packed_offset.host_size * 8);
-        const shift_val = if (ptr_info.packed_offset.host_size <= 4)
-            WValue{ .imm32 = ptr_info.packed_offset.bit_offset }
+        const shift_val: WValue = if (ptr_info.packed_offset.host_size <= 4)
+            .{ .imm32 = ptr_info.packed_offset.bit_offset }
         else if (ptr_info.packed_offset.host_size <= 8)
-            WValue{ .imm64 = ptr_info.packed_offset.bit_offset }
+            .{ .imm64 = ptr_info.packed_offset.bit_offset }
         else
             return func.fail("TODO: airLoad where ptr to bitfield exceeds 64 bits", .{});
 
         const stack_loaded = try func.load(operand, int_elem_ty, 0);
         const shifted = try func.binOp(stack_loaded, shift_val, int_elem_ty, .shr);
-        const result = try func.trunc(shifted, ty, int_elem_ty);
-        // const wrapped = try func.wrapOperand(shifted, ty);
-        break :result try result.toLocal(func, ty);
+        break :result try func.trunc(shifted, ty, int_elem_ty);
     };
-    func.finishAir(inst, result, &.{ty_op.operand});
+    return func.finishAir(inst, result, &.{ty_op.operand});
 }
 
 /// Loads an operand from the linear memory section.
@@ -2528,7 +2517,7 @@ fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValu
             @intCast(ty.abiAlignment(pt).toByteUnits().?),
         });
         try func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } });
-        return WValue{ .stack = {} };
+        return .stack;
     }
 
     const abi_size: u8 = @intCast(ty.abiSize(pt));
@@ -2547,7 +2536,7 @@ fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValu
         },
     );
 
-    return WValue{ .stack = {} };
+    return .stack;
 }
 
 fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -2596,7 +2585,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
         else => {},
     }
 
-    func.finishAir(inst, arg, &.{});
+    return func.finishAir(inst, arg, &.{});
 }
 
 fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
@@ -2613,25 +2602,21 @@ fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
     // case we first coerce the operands to the same type before performing the operation.
     // For big integers we can ignore this as we will call into compiler-rt which handles this.
     const result = switch (op) {
-        .shr, .shl => res: {
+        .shr, .shl => result: {
             const lhs_wasm_bits = toWasmBits(@intCast(lhs_ty.bitSize(pt))) orelse {
                 return func.fail("TODO: implement '{s}' for types larger than 128 bits", .{@tagName(op)});
             };
             const rhs_wasm_bits = toWasmBits(@intCast(rhs_ty.bitSize(pt))).?;
-            const new_rhs = if (lhs_wasm_bits != rhs_wasm_bits and lhs_wasm_bits != 128) blk: {
-                const tmp = try func.intcast(rhs, rhs_ty, lhs_ty);
-                break :blk try tmp.toLocal(func, lhs_ty);
-            } else rhs;
-            const stack_result = try func.binOp(lhs, new_rhs, lhs_ty, op);
-            break :res try stack_result.toLocal(func, lhs_ty);
-        },
-        else => res: {
-            const stack_result = try func.binOp(lhs, rhs, lhs_ty, op);
-            break :res try stack_result.toLocal(func, lhs_ty);
+            const new_rhs = if (lhs_wasm_bits != rhs_wasm_bits and lhs_wasm_bits != 128)
+                try (try func.intcast(rhs, rhs_ty, lhs_ty)).toLocal(func, lhs_ty)
+            else
+                rhs;
+            break :result try func.binOp(lhs, new_rhs, lhs_ty, op);
         },
+        else => try func.binOp(lhs, rhs, lhs_ty, op),
     };
 
-    func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
+    return func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
 }
 
 /// Performs a binary operation on the given `WValue`'s
@@ -2667,7 +2652,7 @@ fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!
 
     try func.addTag(Mir.Inst.Tag.fromOpcode(opcode));
 
-    return WValue{ .stack = {} };
+    return .stack;
 }
 
 fn binOpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!WValue {
@@ -2839,6 +2824,7 @@ fn airAbs(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
                     try func.addTag(.i32_xor);
                     try func.emitWValue(tmp);
                     try func.addTag(.i32_sub);
+                    return func.finishAir(inst, .stack, &.{ty_op.operand});
                 },
                 64 => {
                     try func.emitWValue(operand);
@@ -2854,6 +2840,7 @@ fn airAbs(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
                     try func.addTag(.i64_xor);
                     try func.emitWValue(tmp);
                     try func.addTag(.i64_sub);
+                    return func.finishAir(inst, .stack, &.{ty_op.operand});
                 },
                 128 => {
                     const mask = try func.allocStack(Type.u128);
@@ -2874,18 +2861,14 @@ fn airAbs(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
                     const a = try func.binOpBigInt(operand, mask, Type.u128, .xor);
                     const b = try func.binOpBigInt(a, mask, Type.u128, .sub);
 
-                    func.finishAir(inst, b, &.{ty_op.operand});
-                    return;
+                    return func.finishAir(inst, b, &.{ty_op.operand});
                 },
                 else => unreachable,
             }
-
-            const result = try (WValue{ .stack = {} }).toLocal(func, ty);
-            func.finishAir(inst, result, &.{ty_op.operand});
         },
         .Float => {
-            const result = try (try func.floatOp(.fabs, ty, &.{operand})).toLocal(func, ty);
-            func.finishAir(inst, result, &.{ty_op.operand});
+            const result = try func.floatOp(.fabs, ty, &.{operand});
+            return func.finishAir(inst, result, &.{ty_op.operand});
         },
         else => unreachable,
     }
@@ -2896,8 +2879,8 @@ fn airUnaryFloatOp(func: *CodeGen, inst: Air.Inst.Index, op: FloatOp) InnerError
     const operand = try func.resolveInst(un_op);
     const ty = func.typeOf(un_op);
 
-    const result = try (try func.floatOp(op, ty, &.{operand})).toLocal(func, ty);
-    func.finishAir(inst, result, &.{un_op});
+    const result = try func.floatOp(op, ty, &.{operand});
+    return func.finishAir(inst, result, &.{un_op});
 }
 
 fn floatOp(func: *CodeGen, float_op: FloatOp, ty: Type, args: []const WValue) InnerError!WValue {
@@ -3027,22 +3010,18 @@ fn airWrapBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
     // case we first coerce the operands to the same type before performing the operation.
     // For big integers we can ignore this as we will call into compiler-rt which handles this.
     const result = switch (op) {
-        .shr, .shl => res: {
+        .shr, .shl => result: {
             const lhs_wasm_bits = toWasmBits(@intCast(lhs_ty.bitSize(pt))) orelse {
                 return func.fail("TODO: implement '{s}' for types larger than 128 bits", .{@tagName(op)});
             };
             const rhs_wasm_bits = toWasmBits(@intCast(rhs_ty.bitSize(pt))).?;
-            const new_rhs = if (lhs_wasm_bits != rhs_wasm_bits and lhs_wasm_bits != 128) blk: {
-                const tmp = try func.intcast(rhs, rhs_ty, lhs_ty);
-                break :blk try tmp.toLocal(func, lhs_ty);
-            } else rhs;
-            const stack_result = try func.wrapBinOp(lhs, new_rhs, lhs_ty, op);
-            break :res try stack_result.toLocal(func, lhs_ty);
-        },
-        else => res: {
-            const stack_result = try func.wrapBinOp(lhs, rhs, lhs_ty, op);
-            break :res try stack_result.toLocal(func, lhs_ty);
+            const new_rhs = if (lhs_wasm_bits != rhs_wasm_bits and lhs_wasm_bits != 128)
+                try (try func.intcast(rhs, rhs_ty, lhs_ty)).toLocal(func, lhs_ty)
+            else
+                rhs;
+            break :result try func.wrapBinOp(lhs, new_rhs, lhs_ty, op);
         },
+        else => try func.wrapBinOp(lhs, rhs, lhs_ty, op),
     };
 
     return func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
@@ -3187,7 +3166,7 @@ fn lowerAnonDeclRef(
 
     const is_fn_body = ty.zigTypeTag(mod) == .Fn;
     if (!is_fn_body and !ty.hasRuntimeBitsIgnoreComptime(pt)) {
-        return WValue{ .imm32 = 0xaaaaaaaa };
+        return .{ .imm32 = 0xaaaaaaaa };
     }
 
     const decl_align = mod.intern_pool.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment;
@@ -3202,10 +3181,10 @@ fn lowerAnonDeclRef(
     const target_atom_index = func.bin_file.zigObjectPtr().?.anon_decls.get(decl_val).?;
     const target_sym_index = @intFromEnum(func.bin_file.getAtom(target_atom_index).sym_index);
     if (is_fn_body) {
-        return WValue{ .function_index = target_sym_index };
+        return .{ .function_index = target_sym_index };
     } else if (offset == 0) {
-        return WValue{ .memory = target_sym_index };
-    } else return WValue{ .memory_offset = .{ .pointer = target_sym_index, .offset = offset } };
+        return .{ .memory = target_sym_index };
+    } else return .{ .memory_offset = .{ .pointer = target_sym_index, .offset = offset } };
 }
 
 fn lowerDeclRefValue(func: *CodeGen, decl_index: InternPool.DeclIndex, offset: u32) InnerError!WValue {
@@ -3226,7 +3205,7 @@ fn lowerDeclRefValue(func: *CodeGen, decl_index: InternPool.DeclIndex, offset: u
     }
     const decl_ty = decl.typeOf(mod);
     if (decl_ty.zigTypeTag(mod) != .Fn and !decl_ty.hasRuntimeBitsIgnoreComptime(pt)) {
-        return WValue{ .imm32 = 0xaaaaaaaa };
+        return .{ .imm32 = 0xaaaaaaaa };
     }
 
     const atom_index = try func.bin_file.getOrCreateAtomForDecl(pt, decl_index);
@@ -3234,10 +3213,10 @@ fn lowerDeclRefValue(func: *CodeGen, decl_index: InternPool.DeclIndex, offset: u
 
     const target_sym_index = @intFromEnum(atom.sym_index);
     if (decl_ty.zigTypeTag(mod) == .Fn) {
-        return WValue{ .function_index = target_sym_index };
+        return .{ .function_index = target_sym_index };
     } else if (offset == 0) {
-        return WValue{ .memory = target_sym_index };
-    } else return WValue{ .memory_offset = .{ .pointer = target_sym_index, .offset = offset } };
+        return .{ .memory = target_sym_index };
+    } else return .{ .memory_offset = .{ .pointer = target_sym_index, .offset = offset } };
 }
 
 /// Asserts that `isByRef` returns `false` for `ty`.
@@ -3276,7 +3255,7 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
             .@"unreachable",
             .generic_poison,
             => unreachable, // non-runtime values
-            .false, .true => return WValue{ .imm32 = switch (simple_value) {
+            .false, .true => return .{ .imm32 = switch (simple_value) {
                 .false => 0,
                 .true => 1,
                 else => unreachable,
@@ -3292,20 +3271,20 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
             const int_info = ty.intInfo(mod);
             switch (int_info.signedness) {
                 .signed => switch (int_info.bits) {
-                    0...32 => return WValue{ .imm32 = @bitCast(@as(i32, @intCast(val.toSignedInt(pt)))) },
-                    33...64 => return WValue{ .imm64 = @bitCast(val.toSignedInt(pt)) },
+                    0...32 => return .{ .imm32 = @bitCast(@as(i32, @intCast(val.toSignedInt(pt)))) },
+                    33...64 => return .{ .imm64 = @bitCast(val.toSignedInt(pt)) },
                     else => unreachable,
                 },
                 .unsigned => switch (int_info.bits) {
-                    0...32 => return WValue{ .imm32 = @intCast(val.toUnsignedInt(pt)) },
-                    33...64 => return WValue{ .imm64 = val.toUnsignedInt(pt) },
+                    0...32 => return .{ .imm32 = @intCast(val.toUnsignedInt(pt)) },
+                    33...64 => return .{ .imm64 = val.toUnsignedInt(pt) },
                     else => unreachable,
                 },
             }
         },
         .err => |err| {
             const int = try pt.getErrorValue(err.name);
-            return WValue{ .imm32 = int };
+            return .{ .imm32 = int };
         },
         .error_union => |error_union| {
             const err_int_ty = try pt.errorIntType();
@@ -3335,9 +3314,9 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
             return func.lowerConstant(Value.fromInterned(enum_tag.int), Type.fromInterned(int_tag_ty));
         },
         .float => |float| switch (float.storage) {
-            .f16 => |f16_val| return WValue{ .imm32 = @as(u16, @bitCast(f16_val)) },
-            .f32 => |f32_val| return WValue{ .float32 = f32_val },
-            .f64 => |f64_val| return WValue{ .float64 = f64_val },
+            .f16 => |f16_val| return .{ .imm32 = @as(u16, @bitCast(f16_val)) },
+            .f32 => |f32_val| return .{ .float32 = f32_val },
+            .f64 => |f64_val| return .{ .float64 = f64_val },
             else => unreachable,
         },
         .slice => |slice| {
@@ -3357,10 +3336,10 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
             if (val.optionalValue(mod)) |payload| {
                 return func.lowerConstant(payload, pl_ty);
             } else {
-                return WValue{ .imm32 = 0 };
+                return .{ .imm32 = 0 };
             }
         } else {
-            return WValue{ .imm32 = @intFromBool(!val.isNull(mod)) };
+            return .{ .imm32 = @intFromBool(!val.isNull(mod)) };
         },
         .aggregate => switch (ip.indexToKey(ty.ip_index)) {
             .array_type => return func.fail("Wasm TODO: LowerConstant for {}", .{ty.fmt(pt)}),
@@ -3406,7 +3385,7 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
 fn storeSimdImmd(func: *CodeGen, value: [16]u8) !WValue {
     const index = @as(u32, @intCast(func.simd_immediates.items.len));
     try func.simd_immediates.append(func.gpa, value);
-    return WValue{ .imm128 = index };
+    return .{ .imm128 = index };
 }
 
 fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {
@@ -3414,21 +3393,21 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {
     const mod = pt.zcu;
     const ip = &mod.intern_pool;
     switch (ty.zigTypeTag(mod)) {
-        .Bool, .ErrorSet => return WValue{ .imm32 = 0xaaaaaaaa },
+        .Bool, .ErrorSet => return .{ .imm32 = 0xaaaaaaaa },
         .Int, .Enum => switch (ty.intInfo(mod).bits) {
-            0...32 => return WValue{ .imm32 = 0xaaaaaaaa },
-            33...64 => return WValue{ .imm64 = 0xaaaaaaaaaaaaaaaa },
+            0...32 => return .{ .imm32 = 0xaaaaaaaa },
+            33...64 => return .{ .imm64 = 0xaaaaaaaaaaaaaaaa },
             else => unreachable,
         },
         .Float => switch (ty.floatBits(func.target)) {
-            16 => return WValue{ .imm32 = 0xaaaaaaaa },
-            32 => return WValue{ .float32 = @as(f32, @bitCast(@as(u32, 0xaaaaaaaa))) },
-            64 => return WValue{ .float64 = @as(f64, @bitCast(@as(u64, 0xaaaaaaaaaaaaaaaa))) },
+            16 => return .{ .imm32 = 0xaaaaaaaa },
+            32 => return .{ .float32 = @as(f32, @bitCast(@as(u32, 0xaaaaaaaa))) },
+            64 => return .{ .float64 = @as(f64, @bitCast(@as(u64, 0xaaaaaaaaaaaaaaaa))) },
             else => unreachable,
         },
         .Pointer => switch (func.arch()) {
-            .wasm32 => return WValue{ .imm32 = 0xaaaaaaaa },
-            .wasm64 => return WValue{ .imm64 = 0xaaaaaaaaaaaaaaaa },
+            .wasm32 => return .{ .imm32 = 0xaaaaaaaa },
+            .wasm64 => return .{ .imm64 = 0xaaaaaaaaaaaaaaaa },
             else => unreachable,
         },
         .Optional => {
@@ -3436,10 +3415,10 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {
             if (ty.optionalReprIsPayload(mod)) {
                 return func.emitUndefined(pl_ty);
             }
-            return WValue{ .imm32 = 0xaaaaaaaa };
+            return .{ .imm32 = 0xaaaaaaaa };
         },
         .ErrorUnion => {
-            return WValue{ .imm32 = 0xaaaaaaaa };
+            return .{ .imm32 = 0xaaaaaaaa };
         },
         .Struct => {
             const packed_struct = mod.typeToPackedStruct(ty).?;
@@ -3501,7 +3480,7 @@ fn lowerBlock(func: *CodeGen, inst: Air.Inst.Index, block_ty: Type, body: []cons
     const block_result: WValue = if (wasm_block_ty != wasm.block_empty) blk: {
         const ty: Type = if (isByRef(block_ty, pt)) Type.u32 else block_ty;
         break :blk try func.ensureAllocLocal(ty); // make sure it's a clean local as it may never get overwritten
-    } else WValue.none;
+    } else .none;
 
     try func.startBlock(.block, wasm.block_empty);
     // Here we set the current block idx, so breaks know the depth to jump
@@ -3517,7 +3496,7 @@ fn lowerBlock(func: *CodeGen, inst: Air.Inst.Index, block_ty: Type, body: []cons
     const liveness = func.liveness.getBlock(inst);
     try func.currentBranch().values.ensureUnusedCapacity(func.gpa, liveness.deaths.len);
 
-    func.finishAir(inst, block_result, &.{});
+    return func.finishAir(inst, block_result, &.{});
 }
 
 /// appends a new wasm block to the code section and increases the `block_depth` by 1
@@ -3549,7 +3528,7 @@ fn airLoop(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     try func.addLabel(.br, 0);
     try func.endBlock();
 
-    func.finishAir(inst, .none, &.{});
+    return func.finishAir(inst, .none, &.{});
 }
 
 fn airCondBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -3593,7 +3572,7 @@ fn airCondBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
         try func.genBody(then_body);
     }
 
-    func.finishAir(inst, .none, &.{});
+    return func.finishAir(inst, .none, &.{});
 }
 
 fn airCmp(func: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) InnerError!void {
@@ -3602,8 +3581,8 @@ fn airCmp(func: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) In
     const lhs = try func.resolveInst(bin_op.lhs);
     const rhs = try func.resolveInst(bin_op.rhs);
     const operand_ty = func.typeOf(bin_op.lhs);
-    const result = try (try func.cmp(lhs, rhs, operand_ty, op)).toLocal(func, Type.u32); // comparison result is always 32 bits
-    func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
+    const result = try func.cmp(lhs, rhs, operand_ty, op);
+    return func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
 }
 
 /// Compares two operands.
@@ -3654,7 +3633,7 @@ fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareO
     });
     try func.addTag(Mir.Inst.Tag.fromOpcode(opcode));
 
-    return WValue{ .stack = {} };
+    return .stack;
 }
 
 /// Compares two floats.
@@ -3694,7 +3673,7 @@ fn cmpFloat(func: *CodeGen, ty: Type, lhs: WValue, rhs: WValue, cmp_op: std.math
             }) catch unreachable;
 
             const result = try func.callIntrinsic(fn_name, &.{ ty.ip_index, ty.ip_index }, Type.bool, &.{ lhs, rhs });
-            return func.cmp(result, WValue{ .imm32 = 0 }, Type.i32, cmp_op);
+            return func.cmp(result, .{ .imm32 = 0 }, Type.i32, cmp_op);
         },
         else => unreachable,
     }
@@ -3709,7 +3688,7 @@ fn airCmpLtErrorsLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
     const operand = try func.resolveInst(un_op);
     const sym_index = try func.bin_file.getGlobalSymbol("__zig_errors_len", null);
-    const errors_len = WValue{ .memory = @intFromEnum(sym_index) };
+    const errors_len = .{ .memory = @intFromEnum(sym_index) };
 
     try func.emitWValue(operand);
     const pt = func.pt;
@@ -3717,7 +3696,7 @@ fn airCmpLtErrorsLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     const errors_len_val = try func.load(errors_len, err_int_ty, 0);
     const result = try func.cmp(.stack, errors_len_val, err_int_ty, .lt);
 
-    return func.finishAir(inst, try result.toLocal(func, Type.bool), &.{un_op});
+    return func.finishAir(inst, result, &.{un_op});
 }
 
 fn airBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -3740,7 +3719,7 @@ fn airBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     const idx: u32 = func.block_depth - block.label;
     try func.addLabel(.br, idx);
 
-    func.finishAir(inst, .none, &.{br.operand});
+    return func.finishAir(inst, .none, &.{br.operand});
 }
 
 fn airNot(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -3772,7 +3751,7 @@ fn airNot(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
                         .signed => ~@as(u32, 0),
                     });
                     try func.addTag(.i32_xor);
-                    break :result try @as(WValue, .stack).toLocal(func, operand_ty);
+                    break :result .stack;
                 },
                 64 => {
                     try func.emitWValue(operand);
@@ -3781,7 +3760,7 @@ fn airNot(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
                         .signed => ~@as(u64, 0),
                     });
                     try func.addTag(.i64_xor);
-                    break :result try @as(WValue, .stack).toLocal(func, operand_ty);
+                    break :result .stack;
                 },
                 128 => {
                     const ptr = try func.allocStack(operand_ty);
@@ -3807,24 +3786,24 @@ fn airNot(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
             }
         }
     };
-    func.finishAir(inst, result, &.{ty_op.operand});
+    return func.finishAir(inst, result, &.{ty_op.operand});
 }
 
 fn airTrap(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     try func.addTag(.@"unreachable");
-    func.finishAir(inst, .none, &.{});
+    return func.finishAir(inst, .none, &.{});
 }
 
 fn airBreakpoint(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     // unsupported by wasm itfunc. Can be implemented once we support DWARF
     // for wasm
     try func.addTag(.@"unreachable");
-    func.finishAir(inst, .none, &.{});
+    return func.finishAir(inst, .none, &.{});
 }
 
 fn airUnreachable(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     try func.addTag(.@"unreachable");
-    func.finishAir(inst, .none, &.{});
+    return func.finishAir(inst, .none, &.{});
 }
 
 fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -3841,35 +3820,34 @@ fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
 
     const result = result: {
         if (given_ty.isAnyFloat() or wanted_ty.isAnyFloat()) {
-            const bitcast_result = try func.bitcast(wanted_ty, given_ty, operand);
-            break :result try bitcast_result.toLocal(func, wanted_ty);
+            break :result try func.bitcast(wanted_ty, given_ty, operand);
         }
 
         if (isByRef(given_ty, pt) and !isByRef(wanted_ty, pt)) {
             const loaded_memory = try func.load(operand, wanted_ty, 0);
             if (needs_wrapping) {
-                break :result try (try func.wrapOperand(loaded_memory, wanted_ty)).toLocal(func, wanted_ty);
+                break :result try func.wrapOperand(loaded_memory, wanted_ty);
             } else {
-                break :result try loaded_memory.toLocal(func, wanted_ty);
+                break :result loaded_memory;
             }
         }
         if (!isByRef(given_ty, pt) and isByRef(wanted_ty, pt)) {
             const stack_memory = try func.allocStack(wanted_ty);
             try func.store(stack_memory, operand, given_ty, 0);
             if (needs_wrapping) {
-                break :result try (try func.wrapOperand(stack_memory, wanted_ty)).toLocal(func, wanted_ty);
+                break :result try func.wrapOperand(stack_memory, wanted_ty);
             } else {
                 break :result stack_memory;
             }
         }
 
         if (needs_wrapping) {
-            break :result try (try func.wrapOperand(operand, wanted_ty)).toLocal(func, wanted_ty);
+            break :result try func.wrapOperand(operand, wanted_ty);
         }
 
         break :result func.reuseOperand(ty_op.operand, operand);
     };
-    func.finishAir(inst, result, &.{ty_op.operand});
+    return func.finishAir(inst, result, &.{ty_op.operand});
 }
 
 fn bitcast(func: *CodeGen, wanted_ty: Type, given_ty: Type, operand: WValue) InnerError!WValue {
@@ -3888,7 +3866,7 @@ fn bitcast(func: *CodeGen, wanted_ty: Type, given_ty: Type, operand: WValue) Inn
     });
     try func.emitWValue(operand);
     try func.addTag(Mir.Inst.Tag.fromOpcode(opcode));
-    return WValue{ .stack = {} };
+    return .stack;
 }
 
 fn airStructFieldPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -3901,7 +3879,7 @@ fn airStructFieldPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     const struct_ptr_ty = func.typeOf(extra.data.struct_operand);
     const struct_ty = struct_ptr_ty.childType(mod);
     const result = try func.structFieldPtr(inst, extra.data.struct_operand, struct_ptr, struct_ptr_ty, struct_ty, extra.data.field_index);
-    func.finishAir(inst, result, &.{extra.data.struct_operand});
+    return func.finishAir(inst, result, &.{extra.data.struct_operand});
 }
 
 fn airStructFieldPtrIndex(func: *CodeGen, inst: Air.Inst.Index, index: u32) InnerError!void {
@@ -3913,7 +3891,7 @@ fn airStructFieldPtrIndex(func: *CodeGen, inst: Air.Inst.Index, index: u32) Inne
     const struct_ty = struct_ptr_ty.childType(mod);
 
     const result = try func.structFieldPtr(inst, ty_op.operand, struct_ptr, struct_ptr_ty, struct_ty, index);
-    func.finishAir(inst, result, &.{ty_op.operand});
+    return func.finishAir(inst, result, &.{ty_op.operand});
 }
 
 fn structFieldPtr(
@@ -3950,7 +3928,7 @@ fn structFieldPtr(
     }
     switch (struct_ptr) {
         .stack_offset => |stack_offset| {
-            return WValue{ .stack_offset = .{ .value = stack_offset.value + @as(u32, @intCast(offset)), .references = 1 } };
+            return .{ .stack_offset = .{ .value = stack_offset.value + @as(u32, @intCast(offset)), .references = 1 } };
         },
         else => return func.buildPointerOffset(struct_ptr, offset, .new),
     }
@@ -3969,7 +3947,7 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     const field_ty = struct_ty.structFieldType(field_index, mod);
     if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) return func.finishAir(inst, .none, &.{struct_field.struct_operand});
 
-    const result = switch (struct_ty.containerLayout(mod)) {
+    const result: WValue = switch (struct_ty.containerLayout(mod)) {
         .@"packed" => switch (struct_ty.zigTypeTag(mod)) {
             .Struct => result: {
                 const packed_struct = mod.typeToPackedStruct(struct_ty).?;
@@ -3978,10 +3956,10 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
                 const wasm_bits = toWasmBits(backing_ty.intInfo(mod).bits) orelse {
                     return func.fail("TODO: airStructFieldVal for packed structs larger than 128 bits", .{});
                 };
-                const const_wvalue = if (wasm_bits == 32)
-                    WValue{ .imm32 = offset }
+                const const_wvalue: WValue = if (wasm_bits == 32)
+                    .{ .imm32 = offset }
                 else if (wasm_bits == 64)
-                    WValue{ .imm64 = offset }
+                    .{ .imm64 = offset }
                 else
                     return func.fail("TODO: airStructFieldVal for packed structs larger than 64 bits", .{});
 
@@ -3994,25 +3972,21 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
                 if (field_ty.zigTypeTag(mod) == .Float) {
                     const int_type = try pt.intType(.unsigned, @as(u16, @intCast(field_ty.bitSize(pt))));
                     const truncated = try func.trunc(shifted_value, int_type, backing_ty);
-                    const bitcasted = try func.bitcast(field_ty, int_type, truncated);
-                    break :result try bitcasted.toLocal(func, field_ty);
+                    break :result try func.bitcast(field_ty, int_type, truncated);
                 } else if (field_ty.isPtrAtRuntime(mod) and packed_struct.field_types.len == 1) {
                     // In this case we do not have to perform any transformations,
                     // we can simply reuse the operand.
                     break :result func.reuseOperand(struct_field.struct_operand, operand);
                 } else if (field_ty.isPtrAtRuntime(mod)) {
                     const int_type = try pt.intType(.unsigned, @as(u16, @intCast(field_ty.bitSize(pt))));
-                    const truncated = try func.trunc(shifted_value, int_type, backing_ty);
-                    break :result try truncated.toLocal(func, field_ty);
+                    break :result try func.trunc(shifted_value, int_type, backing_ty);
                 }
-                const truncated = try func.trunc(shifted_value, field_ty, backing_ty);
-                break :result try truncated.toLocal(func, field_ty);
+                break :result try func.trunc(shifted_value, field_ty, backing_ty);
             },
             .Union => result: {
                 if (isByRef(struct_ty, pt)) {
                     if (!isByRef(field_ty, pt)) {
-                        const val = try func.load(operand, field_ty, 0);
-                        break :result try val.toLocal(func, field_ty);
+                        break :result try func.load(operand, field_ty, 0);
                     } else {
                         const new_stack_val = try func.allocStack(field_ty);
                         try func.store(new_stack_val, operand, field_ty, 0);
@@ -4024,15 +3998,12 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
                 if (field_ty.zigTypeTag(mod) == .Float) {
                     const int_type = try pt.intType(.unsigned, @as(u16, @intCast(field_ty.bitSize(pt))));
                     const truncated = try func.trunc(operand, int_type, union_int_type);
-                    const bitcasted = try func.bitcast(field_ty, int_type, truncated);
-                    break :result try bitcasted.toLocal(func, field_ty);
+                    break :result try func.bitcast(field_ty, int_type, truncated);
                 } else if (field_ty.isPtrAtRuntime(mod)) {
                     const int_type = try pt.intType(.unsigned, @as(u16, @intCast(field_ty.bitSize(pt))));
-                    const truncated = try func.trunc(operand, int_type, union_int_type);
-                    break :result try truncated.toLocal(func, field_ty);
+                    break :result try func.trunc(operand, int_type, union_int_type);
                 }
-                const truncated = try func.trunc(operand, field_ty, union_int_type);
-                break :result try truncated.toLocal(func, field_ty);
+                break :result try func.trunc(operand, field_ty, union_int_type);
             },
             else => unreachable,
         },
@@ -4043,17 +4014,16 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
             if (isByRef(field_ty, pt)) {
                 switch (operand) {
                     .stack_offset => |stack_offset| {
-                        break :result WValue{ .stack_offset = .{ .value = stack_offset.value + offset, .references = 1 } };
+                        break :result .{ .stack_offset = .{ .value = stack_offset.value + offset, .references = 1 } };
                     },
                     else => break :result try func.buildPointerOffset(operand, offset, .new),
                 }
             }
-            const field = try func.load(operand, field_ty, offset);
-            break :result try field.toLocal(func, field_ty);
+            break :result try func.load(operand, field_ty, offset);
         },
     };
 
-    func.finishAir(inst, result, &.{struct_field.struct_operand});
+    return func.finishAir(inst, result, &.{struct_field.struct_operand});
 }
 
 fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -4234,7 +4204,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
         try func.genBody(else_body);
         try func.endBlock();
     }
-    func.finishAir(inst, .none, &.{});
+    return func.finishAir(inst, .none, &.{});
 }
 
 fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerError!void {
@@ -4245,11 +4215,11 @@ fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerErro
     const err_union_ty = func.typeOf(un_op);
     const pl_ty = err_union_ty.errorUnionPayload(mod);
 
-    const result = result: {
+    const result: WValue = result: {
         if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
             switch (opcode) {
-                .i32_ne => break :result WValue{ .imm32 = 0 },
-                .i32_eq => break :result WValue{ .imm32 = 1 },
+                .i32_ne => break :result .{ .imm32 = 0 },
+                .i32_eq => break :result .{ .imm32 = 1 },
                 else => unreachable,
             }
         }
@@ -4265,12 +4235,9 @@ fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerErro
         // Compare the error value with '0'
         try func.addImm32(0);
         try func.addTag(Mir.Inst.Tag.fromOpcode(opcode));
-
-        const is_err_tmp = try func.allocLocal(Type.i32);
-        try func.addLabel(.local_set, is_err_tmp.local.value);
-        break :result is_err_tmp;
+        break :result .stack;
     };
-    func.finishAir(inst, result, &.{un_op});
+    return func.finishAir(inst, result, &.{un_op});
 }
 
 fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!void {
@@ -4283,12 +4250,12 @@ fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: boo
     const err_ty = if (op_is_ptr) op_ty.childType(mod) else op_ty;
     const payload_ty = err_ty.errorUnionPayload(mod);
 
-    const result = result: {
+    const result: WValue = result: {
         if (!payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
             if (op_is_ptr) {
                 break :result func.reuseOperand(ty_op.operand, operand);
             }
-            break :result WValue{ .none = {} };
+            break :result .none;
         }
 
         const pl_offset = @as(u32, @intCast(errUnionPayloadOffset(payload_ty, pt)));
@@ -4296,10 +4263,9 @@ fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: boo
             break :result try func.buildPointerOffset(operand, pl_offset, .new);
         }
 
-        const payload = try func.load(operand, payload_ty, pl_offset);
-        break :result try payload.toLocal(func, payload_ty);
+        break :result try func.load(operand, payload_ty, pl_offset);
     };
-    func.finishAir(inst, result, &.{ty_op.operand});
+    return func.finishAir(inst, result, &.{ty_op.operand});
 }
 
 fn airUnwrapErrUnionError(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!void {
@@ -4312,19 +4278,18 @@ fn airUnwrapErrUnionError(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool)
     const err_ty = if (op_is_ptr) op_ty.childType(mod) else op_ty;
     const payload_ty = err_ty.errorUnionPayload(mod);
 
-    const result = result: {
+    const result: WValue = result: {
         if (err_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
-            break :result WValue{ .imm32 = 0 };
+            break :result .{ .imm32 = 0 };
         }
 
         if (op_is_ptr or !payload_ty.hasRuntimeBitsIgnoreComptime(pt)) {
             break :result func.reuseOperand(ty_op.operand, operand);
         }
 
-        const error_val = try func.load(operand, Type.anyerror, @intCast(errUnionErrorOffset(payload_ty, pt)));
-        break :result try error_val.toLocal(func, Type.anyerror);
+        break :result try func.load(operand, Type.anyerror, @intCast(errUnionErrorOffset(payload_ty, pt)));
     };
-    func.finishAir(inst, result, &.{ty_op.operand});
+    return func.finishAir(inst, result, &.{ty_op.operand});
 }
 
 fn airWrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -4354,7 +4319,7 @@ fn airWrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void
         });
         break :result err_union;
     };
-    func.finishAir(inst, result, &.{ty_op.operand});
+    return func.finishAir(inst, result, &.{ty_op.operand});
 }
 
 fn airWrapErrUnionErr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -4382,7 +4347,7 @@ fn airWrapErrUnionErr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
 
         break :result err_union;
     };
-    func.finishAir(inst, result, &.{ty_op.operand});
+    return func.finishAir(inst, result, &.{ty_op.operand});
 }
 
 fn airIntcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -4405,9 +4370,9 @@ fn airIntcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     const result = if (op_bits == wanted_bits)
         func.reuseOperand(ty_op.operand, operand)
     else
-        try (try func.intcast(operand, operand_ty, ty)).toLocal(func, ty);
+        try func.intcast(operand, operand_ty, ty);
 
-    func.finishAir(inst, result, &.{});
+    return func.finishAir(inst, result, &.{});
 }
 
 /// Upcasts or downcasts an integer based on the given and wanted types,
@@ -4472,9 +4437,8 @@ fn airIsNull(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode, op_kind:
 
     const op_ty = func.typeOf(un_op);
     const optional_ty = if (op_kind == .ptr) op_ty.childType(mod) else op_ty;
-    const is_null = try func.isNull(operand, optional_ty, opcode);
-    const result = try is_null.toLocal(func, optional_ty);
-    func.finishAir(inst, result, &.{un_op});
+    const result = try func.isNull(operand, optional_ty, opcode);
+    return func.finishAir(inst, result, &.{un_op});
 }
 
 /// For a given type and operand, checks if it's considered `null`.
@@ -4505,7 +4469,7 @@ fn isNull(func: *CodeGen, operand: WValue, optional_ty: Type, opcode: wasm.Opcod
     try func.addImm32(0);
     try func.addTag(Mir.Inst.Tag.fromOpcode(opcode));
 
-    return WValue{ .stack = {} };
+    return .stack;
 }
 
 fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -4526,10 +4490,9 @@ fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
             break :result try func.buildPointerOffset(operand, 0, .new);
         }
 
-        const payload = try func.load(operand, payload_ty, 0);
-        break :result try payload.toLocal(func, payload_ty);
+        break :result try func.load(operand, payload_ty, 0);
     };
-    func.finishAir(inst, result, &.{ty_op.operand});
+    return func.finishAir(inst, result, &.{ty_op.operand});
 }
 
 fn airOptionalPayloadPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -4547,7 +4510,7 @@ fn airOptionalPayloadPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
 
         break :result try func.buildPointerOffset(operand, 0, .new);
     };
-    func.finishAir(inst, result, &.{ty_op.operand});
+    return func.finishAir(inst, result, &.{ty_op.operand});
 }
 
 fn airOptionalPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -4612,7 +4575,7 @@ fn airWrapOptional(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
         break :result result_ptr;
     };
 
-    func.finishAir(inst, result, &.{ty_op.operand});
+    return func.finishAir(inst, result, &.{ty_op.operand});
 }
 
 fn airSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -4627,14 +4590,14 @@ fn airSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     try func.store(slice, lhs, Type.usize, 0);
     try func.store(slice, rhs, Type.usize, func.ptrSize());
 
-    func.finishAir(inst, slice, &.{ bin_op.lhs, bin_op.rhs });
+    return func.finishAir(inst, slice, &.{ bin_op.lhs, bin_op.rhs });
 }
 
 fn airSliceLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
 
     const operand = try func.resolveInst(ty_op.operand);
-    func.finishAir(inst, try func.sliceLen(operand), &.{ty_op.operand});
+    return func.finishAir(inst, try func.sliceLen(operand), &.{ty_op.operand});
 }
 
 fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -4657,15 +4620,12 @@ fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     try func.addTag(.i32_mul);
     try func.addTag(.i32_add);
 
-    const result_ptr = try func.allocLocal(Type.usize);
-    try func.addLabel(.local_set, result_ptr.local.value);
-
-    const result = if (!isByRef(elem_ty, pt)) result: {
-        const elem_val = try func.load(result_ptr, elem_ty, 0);
-        break :result try elem_val.toLocal(func, elem_ty);
-    } else result_ptr;
+    const elem_result = if (isByRef(elem_ty, pt))
+        .stack
+    else
+        try func.load(.stack, elem_ty, 0);
 
-    func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
+    return func.finishAir(inst, elem_result, &.{ bin_op.lhs, bin_op.rhs });
 }
 
 fn airSliceElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -4688,15 +4648,13 @@ fn airSliceElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     try func.addTag(.i32_mul);
     try func.addTag(.i32_add);
 
-    const result = try func.allocLocal(Type.i32);
-    try func.addLabel(.local_set, result.local.value);
-    func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
+    return func.finishAir(inst, .stack, &.{ bin_op.lhs, bin_op.rhs });
 }
 
 fn airSlicePtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
     const operand = try func.resolveInst(ty_op.operand);
-    func.finishAir(inst, try func.slicePtr(operand), &.{ty_op.operand});
+    return func.finishAir(inst, try func.slicePtr(operand), &.{ty_op.operand});
 }
 
 fn slicePtr(func: *CodeGen, operand: WValue) InnerError!WValue {
@@ -4717,7 +4675,7 @@ fn airTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     const op_ty = func.typeOf(ty_op.operand);
 
     const result = try func.trunc(operand, wanted_ty, op_ty);
-    func.finishAir(inst, try result.toLocal(func, wanted_ty), &.{ty_op.operand});
+    return func.finishAir(inst, result, &.{ty_op.operand});
 }
 
 /// Truncates a given operand to a given type, discarding any overflown bits.
@@ -4743,7 +4701,7 @@ fn airIntFromBool(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     const operand = try func.resolveInst(un_op);
     const result = func.reuseOperand(un_op, operand);
 
-    func.finishAir(inst, result, &.{un_op});
+    return func.finishAir(inst, result, &.{un_op});
 }
 
 fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -4764,10 +4722,10 @@ fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     }
 
     // store the length of the array in the slice
-    const len = WValue{ .imm32 = @as(u32, @intCast(array_ty.arrayLen(mod))) };
-    try func.store(slice_local, len, Type.usize, func.ptrSize());
+    const array_len: u32 = @intCast(array_ty.arrayLen(mod));
+    try func.store(slice_local, .{ .imm32 = array_len }, Type.usize, func.ptrSize());
 
-    func.finishAir(inst, slice_local, &.{ty_op.operand});
+    return func.finishAir(inst, slice_local, &.{ty_op.operand});
 }
 
 fn airIntFromPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -4783,7 +4741,7 @@ fn airIntFromPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
         .stack_offset => try func.buildPointerOffset(operand, 0, .new),
         else => func.reuseOperand(un_op, operand),
     };
-    func.finishAir(inst, result, &.{un_op});
+    return func.finishAir(inst, result, &.{un_op});
 }
 
 fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -4810,18 +4768,12 @@ fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     try func.addTag(.i32_mul);
     try func.addTag(.i32_add);
 
-    const elem_result = val: {
-        var result = try func.allocLocal(Type.usize);
-        try func.addLabel(.local_set, result.local.value);
-        if (isByRef(elem_ty, pt)) {
-            break :val result;
-        }
-        defer result.free(func); // only free if it's not returned like above
+    const elem_result = if (isByRef(elem_ty, pt))
+        .stack
+    else
+        try func.load(.stack, elem_ty, 0);
 
-        const elem_val = try func.load(result, elem_ty, 0);
-        break :val try elem_val.toLocal(func, elem_ty);
-    };
-    func.finishAir(inst, elem_result, &.{ bin_op.lhs, bin_op.rhs });
+    return func.finishAir(inst, elem_result, &.{ bin_op.lhs, bin_op.rhs });
 }
 
 fn airPtrElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -4850,9 +4802,7 @@ fn airPtrElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     try func.addTag(.i32_mul);
     try func.addTag(.i32_add);
 
-    const result = try func.allocLocal(Type.i32);
-    try func.addLabel(.local_set, result.local.value);
-    func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
+    return func.finishAir(inst, .stack, &.{ bin_op.lhs, bin_op.rhs });
 }
 
 fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
@@ -4879,9 +4829,7 @@ fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
     try func.addTag(Mir.Inst.Tag.fromOpcode(mul_opcode));
     try func.addTag(Mir.Inst.Tag.fromOpcode(bin_opcode));
 
-    const result = try func.allocLocal(Type.usize);
-    try func.addLabel(.local_set, result.local.value);
-    func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
+    return func.finishAir(inst, .stack, &.{ bin_op.lhs, bin_op.rhs });
 }
 
 fn airMemset(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void {
@@ -4911,7 +4859,7 @@ fn airMemset(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void
     const dst_ptr = try func.sliceOrArrayPtr(ptr, ptr_ty);
     try func.memset(elem_ty, dst_ptr, len, value);
 
-    func.finishAir(inst, .none, &.{ bin_op.lhs, bin_op.rhs });
+    return func.finishAir(inst, .none, &.{ bin_op.lhs, bin_op.rhs });
 }
 
 /// Sets a region of memory at `ptr` to the value of `value`
@@ -4932,9 +4880,9 @@ fn memset(func: *CodeGen, elem_ty: Type, ptr: WValue, len: WValue, value: WValue
         return;
     }
 
-    const final_len = switch (len) {
-        .imm32 => |val| WValue{ .imm32 = val * abi_size },
-        .imm64 => |val| WValue{ .imm64 = val * abi_size },
+    const final_len: WValue = switch (len) {
+        .imm32 => |val| .{ .imm32 = val * abi_size },
+        .imm64 => |val| .{ .imm64 = val * abi_size },
         else => if (abi_size != 1) blk: {
             const new_len = try func.ensureAllocLocal(Type.usize);
             try func.emitWValue(len);
@@ -5045,7 +4993,7 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
                 try func.mir_extra.appendSlice(func.gpa, &operands);
                 try func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } });
 
-                return func.finishAir(inst, try WValue.toLocal(.stack, func, elem_ty), &.{ bin_op.lhs, bin_op.rhs });
+                return func.finishAir(inst, .stack, &.{ bin_op.lhs, bin_op.rhs });
             },
             else => {
                 const stack_vec = try func.allocStack(array_ty);
@@ -5061,20 +5009,12 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
         }
     }
 
-    const elem_result = val: {
-        var result = try func.allocLocal(Type.usize);
-        try func.addLabel(.local_set, result.local.value);
-
-        if (isByRef(elem_ty, pt)) {
-            break :val result;
-        }
-        defer result.free(func); // only free if no longer needed and not returned like above
-
-        const elem_val = try func.load(result, elem_ty, 0);
-        break :val try elem_val.toLocal(func, elem_ty);
-    };
+    const elem_result = if (isByRef(elem_ty, pt))
+        .stack
+    else
+        try func.load(.stack, elem_ty, 0);
 
-    func.finishAir(inst, elem_result, &.{ bin_op.lhs, bin_op.rhs });
+    return func.finishAir(inst, elem_result, &.{ bin_op.lhs, bin_op.rhs });
 }
 
 fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -5106,7 +5046,7 @@ fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
             target_util.compilerRtIntAbbrev(dest_bitsize),
         }) catch unreachable;
 
-        const result = try (try func.callIntrinsic(fn_name, &.{op_ty.ip_index}, dest_ty, &.{operand})).toLocal(func, dest_ty);
+        const result = try func.callIntrinsic(fn_name, &.{op_ty.ip_index}, dest_ty, &.{operand});
         return func.finishAir(inst, result, &.{ty_op.operand});
     }
 
@@ -5118,9 +5058,8 @@ fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
         .signedness = dest_info.signedness,
     });
     try func.addTag(Mir.Inst.Tag.fromOpcode(op));
-    const wrapped = try func.wrapOperand(.{ .stack = {} }, dest_ty);
-    const result = try wrapped.toLocal(func, dest_ty);
-    func.finishAir(inst, result, &.{ty_op.operand});
+    const result = try func.wrapOperand(.stack, dest_ty);
+    return func.finishAir(inst, result, &.{ty_op.operand});
 }
 
 fn airFloatFromInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -5152,7 +5091,7 @@ fn airFloatFromInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
             target_util.compilerRtFloatAbbrev(dest_bits),
         }) catch unreachable;
 
-        const result = try (try func.callIntrinsic(fn_name, &.{op_ty.ip_index}, dest_ty, &.{operand})).toLocal(func, dest_ty);
+        const result = try func.callIntrinsic(fn_name, &.{op_ty.ip_index}, dest_ty, &.{operand});
         return func.finishAir(inst, result, &.{ty_op.operand});
     }
 
@@ -5165,9 +5104,7 @@ fn airFloatFromInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     });
     try func.addTag(Mir.Inst.Tag.fromOpcode(op));
 
-    const result = try func.allocLocal(dest_ty);
-    try func.addLabel(.local_set, result.local.value);
-    func.finishAir(inst, result, &.{ty_op.operand});
+    return func.finishAir(inst, .stack, &.{ty_op.operand});
 }
 
 fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -5191,7 +5128,6 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
                     64 => std.wasm.simdOpcode(.v128_load64_splat),
                     else => break :blk, // Cannot make use of simd-instructions
                 };
-                const result = try func.allocLocal(ty);
                 try func.emitWValue(operand);
                 // TODO: Add helper functions for simd opcodes
                 const extra_index = @as(u32, @intCast(func.mir_extra.items.len));
@@ -5202,8 +5138,7 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
                     @intCast(elem_ty.abiAlignment(pt).toByteUnits().?),
                 });
                 try func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } });
-                try func.addLabel(.local_set, result.local.value);
-                return func.finishAir(inst, result, &.{ty_op.operand});
+                return func.finishAir(inst, .stack, &.{ty_op.operand});
             },
             .local => {
                 const opcode = switch (elem_ty.bitSize(pt)) {
@@ -5213,13 +5148,11 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
                     64 => if (elem_ty.isInt(mod)) std.wasm.simdOpcode(.i64x2_splat) else std.wasm.simdOpcode(.f64x2_splat),
                     else => break :blk, // Cannot make use of simd-instructions
                 };
-                const result = try func.allocLocal(ty);
                 try func.emitWValue(operand);
                 const extra_index = @as(u32, @intCast(func.mir_extra.items.len));
                 try func.mir_extra.append(func.gpa, opcode);
                 try func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } });
-                try func.addLabel(.local_set, result.local.value);
-                return func.finishAir(inst, result, &.{ty_op.operand});
+                return func.finishAir(inst, .stack, &.{ty_op.operand});
             },
             else => unreachable,
         }
@@ -5308,7 +5241,7 @@ fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
         try func.mir_extra.appendSlice(func.gpa, &operands);
         try func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } });
 
-        return func.finishAir(inst, try WValue.toLocal(.stack, func, inst_ty), &.{ extra.a, extra.b });
+        return func.finishAir(inst, .stack, &.{ extra.a, extra.b });
     }
 }
 
@@ -5392,10 +5325,10 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
                         const field_ty = Type.fromInterned(field_types.get(ip)[elem_index]);
                         if (!field_ty.hasRuntimeBitsIgnoreComptime(pt)) continue;
 
-                        const shift_val = if (backing_type.bitSize(pt) <= 32)
-                            WValue{ .imm32 = current_bit }
+                        const shift_val: WValue = if (backing_type.bitSize(pt) <= 32)
+                            .{ .imm32 = current_bit }
                         else
-                            WValue{ .imm64 = current_bit };
+                            .{ .imm64 = current_bit };
 
                         const value = try func.resolveInst(elem);
                         const value_bit_size: u16 = @intCast(field_ty.bitSize(pt));
@@ -5473,7 +5406,7 @@ fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
         };
         if (layout.payload_size == 0) {
             if (layout.tag_size == 0) {
-                break :result WValue{ .none = {} };
+                break :result .none;
             }
             assert(!isByRef(union_ty, pt));
             break :result tag_int;
@@ -5511,15 +5444,12 @@ fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
             if (field_ty.zigTypeTag(mod) == .Float) {
                 const int_type = try pt.intType(.unsigned, @intCast(field_ty.bitSize(pt)));
                 const bitcasted = try func.bitcast(field_ty, int_type, operand);
-                const casted = try func.trunc(bitcasted, int_type, union_int_type);
-                break :result try casted.toLocal(func, field_ty);
+                break :result try func.trunc(bitcasted, int_type, union_int_type);
             } else if (field_ty.isPtrAtRuntime(mod)) {
                 const int_type = try pt.intType(.unsigned, @intCast(field_ty.bitSize(pt)));
-                const casted = try func.intcast(operand, int_type, union_int_type);
-                break :result try casted.toLocal(func, field_ty);
+                break :result try func.intcast(operand, int_type, union_int_type);
             }
-            const casted = try func.intcast(operand, field_ty, union_int_type);
-            break :result try casted.toLocal(func, field_ty);
+            break :result try func.intcast(operand, field_ty, union_int_type);
         }
     };
 
@@ -5528,27 +5458,23 @@ fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
 
 fn airPrefetch(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     const prefetch = func.air.instructions.items(.data)[@intFromEnum(inst)].prefetch;
-    func.finishAir(inst, .none, &.{prefetch.ptr});
+    return func.finishAir(inst, .none, &.{prefetch.ptr});
 }
 
 fn airWasmMemorySize(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
 
-    const result = try func.allocLocal(func.typeOfIndex(inst));
     try func.addLabel(.memory_size, pl_op.payload);
-    try func.addLabel(.local_set, result.local.value);
-    func.finishAir(inst, result, &.{pl_op.operand});
+    return func.finishAir(inst, .stack, &.{pl_op.operand});
 }
 
 fn airWasmMemoryGrow(func: *CodeGen, inst: Air.Inst.Index) !void {
     const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
 
     const operand = try func.resolveInst(pl_op.operand);
-    const result = try func.allocLocal(func.typeOfIndex(inst));
     try func.emitWValue(operand);
     try func.addLabel(.memory_grow, pl_op.payload);
-    try func.addLabel(.local_set, result.local.value);
-    func.finishAir(inst, result, &.{pl_op.operand});
+    return func.finishAir(inst, .stack, &.{pl_op.operand});
 }
 
 fn cmpOptionals(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std.math.CompareOperator) InnerError!WValue {
@@ -5582,7 +5508,7 @@ fn cmpOptionals(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op:
     try func.emitWValue(result);
     try func.addImm32(0);
     try func.addTag(if (op == .eq) .i32_ne else .i32_eq);
-    return WValue{ .stack = {} };
+    return .stack;
 }
 
 /// Compares big integers by checking both its high bits and low bits.
@@ -5628,7 +5554,7 @@ fn cmpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std
         },
     }
 
-    return WValue{ .stack = {} };
+    return .stack;
 }
 
 fn airSetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -5653,7 +5579,7 @@ fn airSetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
         break :blk @intCast(layout.payload_size);
     } else 0;
     try func.store(union_ptr, new_tag, tag_ty, offset);
-    func.finishAir(inst, .none, &.{ bin_op.lhs, bin_op.rhs });
+    return func.finishAir(inst, .none, &.{ bin_op.lhs, bin_op.rhs });
 }
 
 fn airGetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -5668,12 +5594,12 @@ fn airGetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     const operand = try func.resolveInst(ty_op.operand);
     // when the tag alignment is smaller than the payload, the field will be stored
     // after the payload.
-    const offset: u32 = if (layout.tag_align.compare(.lt, layout.payload_align)) blk: {
-        break :blk @intCast(layout.payload_size);
-    } else 0;
-    const tag = try func.load(operand, tag_ty, offset);
-    const result = try tag.toLocal(func, tag_ty);
-    func.finishAir(inst, result, &.{ty_op.operand});
+    const offset: u32 = if (layout.tag_align.compare(.lt, layout.payload_align))
+        @intCast(layout.payload_size)
+    else
+        0;
+    const result = try func.load(operand, tag_ty, offset);
+    return func.finishAir(inst, result, &.{ty_op.operand});
 }
 
 fn airFpext(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -5681,9 +5607,8 @@ fn airFpext(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
 
     const dest_ty = func.typeOfIndex(inst);
     const operand = try func.resolveInst(ty_op.operand);
-    const extended = try func.fpext(operand, func.typeOf(ty_op.operand), dest_ty);
-    const result = try extended.toLocal(func, dest_ty);
-    func.finishAir(inst, result, &.{ty_op.operand});
+    const result = try func.fpext(operand, func.typeOf(ty_op.operand), dest_ty);
+    return func.finishAir(inst, result, &.{ty_op.operand});
 }
 
 /// Extends a float from a given `Type` to a larger wanted `Type`
@@ -5695,7 +5620,7 @@ fn fpext(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerError!
     if (wanted_bits == 64 and given_bits == 32) {
         try func.emitWValue(operand);
         try func.addTag(.f64_promote_f32);
-        return WValue{ .stack = {} };
+        return .stack;
     } else if (given_bits == 16 and wanted_bits <= 64) {
         // call __extendhfsf2(f16) f32
         const f32_result = try func.callIntrinsic(
@@ -5709,7 +5634,7 @@ fn fpext(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerError!
         if (wanted_bits == 64) {
             try func.addTag(.f64_promote_f32);
         }
-        return WValue{ .stack = {} };
+        return .stack;
     }
 
     var fn_name_buf: [13]u8 = undefined;
@@ -5726,9 +5651,8 @@ fn airFptrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
 
     const dest_ty = func.typeOfIndex(inst);
     const operand = try func.resolveInst(ty_op.operand);
-    const truncated = try func.fptrunc(operand, func.typeOf(ty_op.operand), dest_ty);
-    const result = try truncated.toLocal(func, dest_ty);
-    func.finishAir(inst, result, &.{ty_op.operand});
+    const result = try func.fptrunc(operand, func.typeOf(ty_op.operand), dest_ty);
+    return func.finishAir(inst, result, &.{ty_op.operand});
 }
 
 /// Truncates a float from a given `Type` to its wanted `Type`
@@ -5740,12 +5664,12 @@ fn fptrunc(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerErro
     if (wanted_bits == 32 and given_bits == 64) {
         try func.emitWValue(operand);
         try func.addTag(.f32_demote_f64);
-        return WValue{ .stack = {} };
+        return .stack;
     } else if (wanted_bits == 16 and given_bits <= 64) {
         const op: WValue = if (given_bits == 64) blk: {
             try func.emitWValue(operand);
             try func.addTag(.f32_demote_f64);
-            break :blk WValue{ .stack = {} };
+            break :blk .stack;
         } else operand;
 
         // call __truncsfhf2(f32) f16
@@ -5785,7 +5709,7 @@ fn airErrUnionPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi
 
         break :result try func.buildPointerOffset(operand, @as(u32, @intCast(errUnionPayloadOffset(payload_ty, pt))), .new);
     };
-    func.finishAir(inst, result, &.{ty_op.operand});
+    return func.finishAir(inst, result, &.{ty_op.operand});
 }
 
 fn airFieldParentPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -5807,7 +5731,7 @@ fn airFieldParentPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
         break :result base;
     } else func.reuseOperand(extra.field_ptr, field_ptr);
 
-    func.finishAir(inst, result, &.{extra.field_ptr});
+    return func.finishAir(inst, result, &.{extra.field_ptr});
 }
 
 fn sliceOrArrayPtr(func: *CodeGen, ptr: WValue, ptr_ty: Type) InnerError!WValue {
@@ -5849,12 +5773,12 @@ fn airMemcpy(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     const src_ptr = try func.sliceOrArrayPtr(src, src_ty);
     try func.memcpy(dst_ptr, src_ptr, len);
 
-    func.finishAir(inst, .none, &.{ bin_op.lhs, bin_op.rhs });
+    return func.finishAir(inst, .none, &.{ bin_op.lhs, bin_op.rhs });
 }
 
 fn airRetAddr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     // TODO: Implement this properly once stack serialization is solved
-    func.finishAir(inst, switch (func.arch()) {
+    return func.finishAir(inst, switch (func.arch()) {
         .wasm32 => .{ .imm32 = 0 },
         .wasm64 => .{ .imm64 = 0 },
         else => unreachable,
@@ -5868,7 +5792,6 @@ fn airPopcount(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
 
     const operand = try func.resolveInst(ty_op.operand);
     const op_ty = func.typeOf(ty_op.operand);
-    const result_ty = func.typeOfIndex(inst);
 
     if (op_ty.zigTypeTag(mod) == .Vector) {
         return func.fail("TODO: Implement @popCount for vectors", .{});
@@ -5911,9 +5834,7 @@ fn airPopcount(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
         else => unreachable,
     }
 
-    const result = try func.allocLocal(result_ty);
-    try func.addLabel(.local_set, result.local.value);
-    func.finishAir(inst, result, &.{ty_op.operand});
+    return func.finishAir(inst, .stack, &.{ty_op.operand});
 }
 
 fn airBitReverse(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -5942,12 +5863,11 @@ fn airBitReverse(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
                 Type.u32,
                 &.{operand},
             );
-            const reversed = if (bits == 32)
+            const result = if (bits == 32)
                 intrin_ret
             else
                 try func.binOp(intrin_ret, .{ .imm32 = 32 - bits }, ty, .shr);
-            const result = try reversed.toLocal(func, ty);
-            func.finishAir(inst, result, &.{ty_op.operand});
+            return func.finishAir(inst, result, &.{ty_op.operand});
         },
         64 => {
             const intrin_ret = try func.callIntrinsic(
@@ -5956,12 +5876,11 @@ fn airBitReverse(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
                 Type.u64,
                 &.{operand},
             );
-            const reversed = if (bits == 64)
+            const result = if (bits == 64)
                 intrin_ret
             else
                 try func.binOp(intrin_ret, .{ .imm64 = 64 - bits }, ty, .shr);
-            const result = try reversed.toLocal(func, ty);
-            func.finishAir(inst, result, &.{ty_op.operand});
+            return func.finishAir(inst, result, &.{ty_op.operand});
         },
         128 => {
             const result = try func.allocStack(ty);
@@ -6008,7 +5927,7 @@ fn airBitReverse(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
                 try func.addTag(.i64_or);
                 try func.store(.stack, .stack, Type.u64, result.offset());
             }
-            func.finishAir(inst, result, &.{ty_op.operand});
+            return func.finishAir(inst, result, &.{ty_op.operand});
         },
         else => unreachable,
     }
@@ -6051,16 +5970,14 @@ fn airErrorName(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
         else => unreachable,
     }
 
-    const result_ptr = try func.allocLocal(Type.usize);
-    try func.addLabel(.local_set, result_ptr.local.value);
-    func.finishAir(inst, result_ptr, &.{un_op});
+    return func.finishAir(inst, .stack, &.{un_op});
 }
 
 fn airPtrSliceFieldPtr(func: *CodeGen, inst: Air.Inst.Index, offset: u32) InnerError!void {
     const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
     const slice_ptr = try func.resolveInst(ty_op.operand);
     const result = try func.buildPointerOffset(slice_ptr, offset, .new);
-    func.finishAir(inst, result, &.{ty_op.operand});
+    return func.finishAir(inst, result, &.{ty_op.operand});
 }
 
 fn airAddSubWithOverflow(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
@@ -6089,9 +6006,9 @@ fn airAddSubWithOverflow(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerErro
         return func.finishAir(inst, result, &.{ extra.lhs, extra.rhs });
     }
 
-    const zero = switch (wasm_bits) {
-        32 => WValue{ .imm32 = 0 },
-        64 => WValue{ .imm64 = 0 },
+    const zero: WValue = switch (wasm_bits) {
+        32 => .{ .imm32 = 0 },
+        64 => .{ .imm64 = 0 },
         else => unreachable,
     };
 
@@ -6121,7 +6038,7 @@ fn airAddSubWithOverflow(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerErro
     const offset = @as(u32, @intCast(lhs_ty.abiSize(pt)));
     try func.store(result_ptr, overflow_local, Type.u1, offset);
 
-    func.finishAir(inst, result_ptr, &.{ extra.lhs, extra.rhs });
+    return func.finishAir(inst, result_ptr, &.{ extra.lhs, extra.rhs });
 }
 
 fn addSubWithOverflowBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, result_ty: Type, op: Op) InnerError!WValue {
@@ -6177,7 +6094,7 @@ fn addSubWithOverflowBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type,
         _ = try func.cmp(tmp_op, lhs_low_bit, Type.u64, .eq);
         try func.addTag(.select);
 
-        break :blk WValue{ .stack = {} };
+        break :blk .stack;
     };
     var overflow_local = try overflow_bit.toLocal(func, Type.u1);
     defer overflow_local.free(func);
@@ -6228,7 +6145,7 @@ fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     const overflow_bit = blk: {
         try func.emitWValue(lhs);
         const shr = try func.binOp(result, rhs_final, lhs_ty, .shr);
-        break :blk try func.cmp(.{ .stack = {} }, shr, lhs_ty, .neq);
+        break :blk try func.cmp(.stack, shr, lhs_ty, .neq);
     };
     var overflow_local = try overflow_bit.toLocal(func, Type.u1);
     defer overflow_local.free(func);
@@ -6238,7 +6155,7 @@ fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     const offset = @as(u32, @intCast(lhs_ty.abiSize(pt)));
     try func.store(result_ptr, overflow_local, Type.u1, offset);
 
-    func.finishAir(inst, result_ptr, &.{ extra.lhs, extra.rhs });
+    return func.finishAir(inst, result_ptr, &.{ extra.lhs, extra.rhs });
 }
 
 fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -6265,9 +6182,9 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
         return func.fail("TODO: Implement `@mulWithOverflow` for integer bitsize: {d}", .{int_info.bits});
     };
 
-    const zero = switch (wasm_bits) {
-        32 => WValue{ .imm32 = 0 },
-        64, 128 => WValue{ .imm64 = 0 },
+    const zero: WValue = switch (wasm_bits) {
+        32 => .{ .imm32 = 0 },
+        64, 128 => .{ .imm64 = 0 },
         else => unreachable,
     };
 
@@ -6303,10 +6220,10 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     } else if (wasm_bits == 32) blk: {
         var bin_op = try (try func.binOp(lhs, rhs, lhs_ty, .mul)).toLocal(func, lhs_ty);
         defer bin_op.free(func);
-        const shift_imm = if (wasm_bits == 32)
-            WValue{ .imm32 = int_info.bits }
+        const shift_imm: WValue = if (wasm_bits == 32)
+            .{ .imm32 = int_info.bits }
         else
-            WValue{ .imm64 = int_info.bits };
+            .{ .imm64 = int_info.bits };
         const shr = try func.binOp(bin_op, shift_imm, lhs_ty, .shr);
         _ = try func.cmp(shr, zero, lhs_ty, .neq);
         try func.addLabel(.local_set, overflow_bit.local.value);
@@ -6412,7 +6329,7 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     const offset = @as(u32, @intCast(lhs_ty.abiSize(pt)));
     try func.store(result_ptr, overflow_bit, Type.u1, offset);
 
-    func.finishAir(inst, result_ptr, &.{ extra.lhs, extra.rhs });
+    return func.finishAir(inst, result_ptr, &.{ extra.lhs, extra.rhs });
 }
 
 fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
@@ -6454,11 +6371,7 @@ fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
         try func.addTag(.select);
     }
 
-    // store result in local
-    const result_ty = if (isByRef(ty, pt)) Type.u32 else ty;
-    const result = try func.allocLocal(result_ty);
-    try func.addLabel(.local_set, result.local.value);
-    func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
+    return func.finishAir(inst, .stack, &.{ bin_op.lhs, bin_op.rhs });
 }
 
 fn airMulAdd(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -6487,13 +6400,13 @@ fn airMulAdd(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
             Type.f32,
             &.{ rhs_ext, lhs_ext, addend_ext },
         );
-        break :fl_result try (try func.fptrunc(result, Type.f32, ty)).toLocal(func, ty);
+        break :fl_result try func.fptrunc(result, Type.f32, ty);
     } else result: {
         const mul_result = try func.binOp(lhs, rhs, ty, .mul);
-        break :result try (try func.binOp(mul_result, addend, ty, .add)).toLocal(func, ty);
+        break :result try func.binOp(mul_result, addend, ty, .add);
     };
 
-    func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs, pl_op.operand });
+    return func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs, pl_op.operand });
 }
 
 fn airClz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -6502,7 +6415,6 @@ fn airClz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
 
     const ty = func.typeOf(ty_op.operand);
-    const result_ty = func.typeOfIndex(inst);
     if (ty.zigTypeTag(mod) == .Vector) {
         return func.fail("TODO: `@clz` for vectors", .{});
     }
@@ -6545,9 +6457,7 @@ fn airClz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
         try func.addTag(.i32_sub);
     }
 
-    const result = try func.allocLocal(result_ty);
-    try func.addLabel(.local_set, result.local.value);
-    func.finishAir(inst, result, &.{ty_op.operand});
+    return func.finishAir(inst, .stack, &.{ty_op.operand});
 }
 
 fn airCtz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -6556,7 +6466,6 @@ fn airCtz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
 
     const ty = func.typeOf(ty_op.operand);
-    const result_ty = func.typeOfIndex(inst);
 
     if (ty.zigTypeTag(mod) == .Vector) {
         return func.fail("TODO: `@ctz` for vectors", .{});
@@ -6611,9 +6520,7 @@ fn airCtz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
         else => unreachable,
     }
 
-    const result = try func.allocLocal(result_ty);
-    try func.addLabel(.local_set, result.local.value);
-    func.finishAir(inst, result, &.{ty_op.operand});
+    return func.finishAir(inst, .stack, &.{ty_op.operand});
 }
 
 fn airDbgStmt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -6626,7 +6533,7 @@ fn airDbgStmt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
             .column = dbg_stmt.column,
         }),
     } });
-    func.finishAir(inst, .none, &.{});
+    return func.finishAir(inst, .none, &.{});
 }
 
 fn airDbgInlineBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -6659,7 +6566,7 @@ fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) InnerError!void
     };
     try func.debug_output.dwarf.genVarDbgInfo(name, ty, mod.funcOwnerDeclIndex(func.func_index), is_ptr, loc);
 
-    func.finishAir(inst, .none, &.{});
+    return func.finishAir(inst, .none, &.{});
 }
 
 fn airTry(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -6669,7 +6576,7 @@ fn airTry(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     const body: []const Air.Inst.Index = @ptrCast(func.air.extra[extra.end..][0..extra.data.body_len]);
     const err_union_ty = func.typeOf(pl_op.operand);
     const result = try lowerTry(func, inst, err_union, body, err_union_ty, false);
-    func.finishAir(inst, result, &.{pl_op.operand});
+    return func.finishAir(inst, result, &.{pl_op.operand});
 }
 
 fn airTryPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -6681,7 +6588,7 @@ fn airTryPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     const body: []const Air.Inst.Index = @ptrCast(func.air.extra[extra.end..][0..extra.data.body_len]);
     const err_union_ty = func.typeOf(extra.data.ptr).childType(mod);
     const result = try lowerTry(func, inst, err_union_ptr, body, err_union_ty, true);
-    func.finishAir(inst, result, &.{extra.data.ptr});
+    return func.finishAir(inst, result, &.{extra.data.ptr});
 }
 
 fn lowerTry(
@@ -6730,7 +6637,7 @@ fn lowerTry(
 
     // if we reach here it means error was not set, and we want the payload
     if (!pl_has_bits) {
-        return WValue{ .none = {} };
+        return .none;
     }
 
     const pl_offset: u32 = @intCast(errUnionPayloadOffset(pl_ty, pt));
@@ -6771,12 +6678,10 @@ fn airByteSwap(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
                     Type.u32,
                     &.{operand},
                 );
-                const swapped = if (int_info.bits == 32)
+                break :result if (int_info.bits == 32)
                     intrin_ret
                 else
                     try func.binOp(intrin_ret, .{ .imm32 = 32 - int_info.bits }, ty, .shr);
-
-                break :result try swapped.toLocal(func, ty);
             },
             64 => {
                 const intrin_ret = try func.callIntrinsic(
@@ -6785,17 +6690,15 @@ fn airByteSwap(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
                     Type.u64,
                     &.{operand},
                 );
-                const swapped = if (int_info.bits == 64)
+                break :result if (int_info.bits == 64)
                     intrin_ret
                 else
                     try func.binOp(intrin_ret, .{ .imm64 = 64 - int_info.bits }, ty, .shr);
-
-                break :result try swapped.toLocal(func, ty);
             },
             else => return func.fail("TODO: @byteSwap for integers with bitsize {d}", .{int_info.bits}),
         }
     };
-    func.finishAir(inst, result, &.{ty_op.operand});
+    return func.finishAir(inst, result, &.{ty_op.operand});
 }
 
 fn airDiv(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -6805,8 +6708,8 @@ fn airDiv(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     const lhs = try func.resolveInst(bin_op.lhs);
     const rhs = try func.resolveInst(bin_op.rhs);
 
-    const result = try (try func.binOp(lhs, rhs, ty, .div)).toLocal(func, ty);
-    func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
+    const result = try func.binOp(lhs, rhs, ty, .div);
+    return func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
 }
 
 fn airDivTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -6816,10 +6719,10 @@ fn airDivTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     const lhs = try func.resolveInst(bin_op.lhs);
     const rhs = try func.resolveInst(bin_op.rhs);
 
-    const div_result = try (try func.binOp(lhs, rhs, ty, .div)).toLocal(func, ty);
+    const div_result = try func.binOp(lhs, rhs, ty, .div);
 
     if (ty.isAnyFloat()) {
-        const trunc_result = try (try func.floatOp(.trunc, ty, &.{div_result})).toLocal(func, ty);
+        const trunc_result = try func.floatOp(.trunc, ty, &.{div_result});
         return func.finishAir(inst, trunc_result, &.{ bin_op.lhs, bin_op.rhs });
     }
 
@@ -6847,9 +6750,9 @@ fn airDivFloor(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
             return func.fail("TODO: `@divFloor` for signed integers larger than 64 bits ({d} bits requested)", .{int_bits});
         }
 
-        const zero = switch (wasm_bits) {
-            32 => WValue{ .imm32 = 0 },
-            64 => WValue{ .imm64 = 0 },
+        const zero: WValue = switch (wasm_bits) {
+            32 => .{ .imm32 = 0 },
+            64 => .{ .imm64 = 0 },
             else => unreachable,
         };
 
@@ -6895,7 +6798,7 @@ fn airDivFloor(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
         // TODO: Should we be zeroing the high bits here or should we be ignoring the high bits
         // when performing comparisons?
         if (int_bits != wasm_bits) {
-            _ = try func.wrapOperand(.{ .stack = {} }, ty);
+            _ = try func.wrapOperand(.stack, ty);
         }
     } else {
         const float_bits = ty.floatBits(func.target);
@@ -6923,13 +6826,11 @@ fn airDivFloor(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
         }
 
         if (is_f16) {
-            _ = try func.fptrunc(.{ .stack = {} }, Type.f32, Type.f16);
+            _ = try func.fptrunc(.stack, Type.f32, Type.f16);
         }
     }
 
-    const result = try func.allocLocal(ty);
-    try func.addLabel(.local_set, result.local.value);
-    func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
+    return func.finishAir(inst, .stack, &.{ bin_op.lhs, bin_op.rhs });
 }
 
 fn airRem(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -6941,8 +6842,7 @@ fn airRem(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
 
     const result = try func.binOp(lhs, rhs, ty, .rem);
 
-    const return_local = try result.toLocal(func, ty);
-    func.finishAir(inst, return_local, &.{ bin_op.lhs, bin_op.rhs });
+    return func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
 }
 
 /// Remainder after floor division, defined by:
@@ -6979,9 +6879,7 @@ fn airMod(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
         return func.fail("TODO: implement `@mod` on floating point types for {}", .{func.target.cpu.arch});
     }
 
-    const result = try func.allocLocal(ty);
-    try func.addLabel(.local_set, result.local.value);
-    func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
+    return func.finishAir(inst, .stack, &.{ bin_op.lhs, bin_op.rhs });
 }
 
 fn airSatBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
@@ -7011,9 +6909,9 @@ fn airSatBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
     defer bin_result.free(func);
     if (wasm_bits != int_info.bits and op == .add) {
         const val: u64 = @as(u64, @intCast((@as(u65, 1) << @as(u7, @intCast(int_info.bits))) - 1));
-        const imm_val = switch (wasm_bits) {
-            32 => WValue{ .imm32 = @intCast(val) },
-            64 => WValue{ .imm64 = val },
+        const imm_val: WValue = switch (wasm_bits) {
+            32 => .{ .imm32 = @intCast(val) },
+            64 => .{ .imm64 = val },
             else => unreachable,
         };
 
@@ -7031,9 +6929,7 @@ fn airSatBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
     }
 
     try func.addTag(.select);
-    const result = try func.allocLocal(ty);
-    try func.addLabel(.local_set, result.local.value);
-    return func.finishAir(inst, result, &.{ bin_op.lhs, bin_op.rhs });
+    return func.finishAir(inst, .stack, &.{ bin_op.lhs, bin_op.rhs });
 }
 
 fn signedSat(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!WValue {
@@ -7046,14 +6942,14 @@ fn signedSat(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerEr
 
     const max_val: u64 = @as(u64, @intCast((@as(u65, 1) << @as(u7, @intCast(int_info.bits - 1))) - 1));
     const min_val: i64 = (-@as(i64, @intCast(@as(u63, @intCast(max_val))))) - 1;
-    const max_wvalue = switch (wasm_bits) {
-        32 => WValue{ .imm32 = @as(u32, @truncate(max_val)) },
-        64 => WValue{ .imm64 = max_val },
+    const max_wvalue: WValue = switch (wasm_bits) {
+        32 => .{ .imm32 = @truncate(max_val) },
+        64 => .{ .imm64 = max_val },
         else => unreachable,
     };
-    const min_wvalue = switch (wasm_bits) {
-        32 => WValue{ .imm32 = @as(u32, @bitCast(@as(i32, @truncate(min_val)))) },
-        64 => WValue{ .imm64 = @as(u64, @bitCast(min_val)) },
+    const min_wvalue: WValue = switch (wasm_bits) {
+        32 => .{ .imm32 = @bitCast(@as(i32, @truncate(min_val))) },
+        64 => .{ .imm64 = @bitCast(min_val) },
         else => unreachable,
     };
 
@@ -7073,9 +6969,9 @@ fn signedSat(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerEr
         try func.addLabel(.local_set, bin_result.local.value); // re-use local
         return (try func.wrapOperand(bin_result, ty)).toLocal(func, ty);
     } else {
-        const zero = switch (wasm_bits) {
-            32 => WValue{ .imm32 = 0 },
-            64 => WValue{ .imm64 = 0 },
+        const zero: WValue = switch (wasm_bits) {
+            32 => .{ .imm32 = 0 },
+            64 => .{ .imm64 = 0 },
             else => unreachable,
         };
         try func.emitWValue(max_wvalue);
@@ -7110,7 +7006,7 @@ fn airShlSat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     const wasm_bits = toWasmBits(int_info.bits).?;
     const result = try func.allocLocal(ty);
 
-    if (wasm_bits == int_info.bits) outer_blk: {
+    if (wasm_bits == int_info.bits) {
         var shl = try (try func.binOp(lhs, rhs, ty, .shl)).toLocal(func, ty);
         defer shl.free(func);
         var shr = try (try func.binOp(shl, rhs, ty, .shr)).toLocal(func, ty);
@@ -7143,12 +7039,11 @@ fn airShlSat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
         _ = try func.cmp(lhs, shr, ty, .neq);
         try func.addTag(.select);
         try func.addLabel(.local_set, result.local.value);
-        break :outer_blk;
     } else {
         const shift_size = wasm_bits - int_info.bits;
-        const shift_value = switch (wasm_bits) {
-            32 => WValue{ .imm32 = shift_size },
-            64 => WValue{ .imm64 = shift_size },
+        const shift_value: WValue = switch (wasm_bits) {
+            32 => .{ .imm32 = shift_size },
+            64 => .{ .imm64 = shift_size },
             else => unreachable,
         };
         const ext_ty = try pt.intType(int_info.signedness, wasm_bits);
@@ -7232,7 +7127,7 @@ fn callIntrinsic(
         const sret_local = try func.allocStack(return_type);
         try func.lowerToStack(sret_local);
         break :blk sret_local;
-    } else WValue{ .none = {} };
+    } else .none;
 
     // Lower all arguments to the stack before we call our function
     for (args, 0..) |arg, arg_i| {
@@ -7245,14 +7140,14 @@ fn callIntrinsic(
     try func.addLabel(.call, @intFromEnum(symbol_index));
 
     if (!return_type.hasRuntimeBitsIgnoreComptime(pt)) {
-        return WValue.none;
+        return .none;
     } else if (return_type.isNoReturn(mod)) {
         try func.addTag(.@"unreachable");
-        return WValue.none;
+        return .none;
     } else if (want_sret_param) {
         return sret;
     } else {
-        return WValue{ .stack = {} };
+        return .stack;
     }
 }
 
@@ -7571,7 +7466,7 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
         break :val ptr_val;
     };
 
-    const result_ptr = if (isByRef(result_ty, pt)) val: {
+    const result = if (isByRef(result_ty, pt)) val: {
         try func.emitWValue(cmp_result);
         try func.addImm32(~@as(u32, 0));
         try func.addTag(.i32_xor);
@@ -7587,10 +7482,10 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
         try func.emitWValue(ptr_val);
         try func.emitWValue(cmp_result);
         try func.addTag(.select);
-        break :val try WValue.toLocal(.stack, func, result_ty);
+        break :val .stack;
     };
 
-    return func.finishAir(inst, result_ptr, &.{ extra.ptr, extra.expected_value, extra.new_value });
+    return func.finishAir(inst, result, &.{ extra.ptr, extra.expected_value, extra.new_value });
 }
 
 fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -7616,8 +7511,7 @@ fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
         _ = try func.load(ptr, ty, 0);
     }
 
-    const result = try WValue.toLocal(.stack, func, ty);
-    return func.finishAir(inst, result, &.{atomic_load.ptr});
+    return func.finishAir(inst, .stack, &.{atomic_load.ptr});
 }
 
 fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
@@ -7734,8 +7628,7 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
                     .offset = ptr.offset(),
                     .alignment = @intCast(ty.abiAlignment(pt).toByteUnits().?),
                 });
-                const result = try WValue.toLocal(.stack, func, ty);
-                return func.finishAir(inst, result, &.{ pl_op.operand, extra.operand });
+                return func.finishAir(inst, .stack, &.{ pl_op.operand, extra.operand });
             },
         }
     } else {
@@ -7847,8 +7740,7 @@ fn airFrameAddress(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
         try func.initializeStack();
     }
     try func.emitWValue(func.bottom_stack_value);
-    const result = try WValue.toLocal(.stack, func, Type.usize);
-    return func.finishAir(inst, result, &.{});
+    return func.finishAir(inst, .stack, &.{});
 }
 
 fn typeOf(func: *CodeGen, inst: Air.Inst.Ref) Type {