Commit 1d455896cb

Veikka Tuominen <git@vexu.eu>
2022-04-29 11:23:14
Zir: move more common instructions out of extended
1 parent a6f254e
src/AstGen.zig
@@ -1078,8 +1078,14 @@ fn awaitExpr(
         });
     }
     const operand = try expr(gz, scope, .none, rhs_node);
-    const tag: Zir.Inst.Tag = if (gz.nosuspend_node != 0) .await_nosuspend else .@"await";
-    const result = try gz.addUnNode(tag, operand, node);
+    const result = if (gz.nosuspend_node != 0)
+        try gz.addExtendedPayload(.await_nosuspend, Zir.Inst.UnNode{
+            .node = gz.nodeIndexToRelative(node),
+            .operand = operand,
+        })
+    else
+        try gz.addUnNode(.@"await", operand, node);
+
     return rvalue(gz, rl, result, node);
 }
 
@@ -2349,7 +2355,6 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner
             .int_to_ptr,
             .float_cast,
             .int_cast,
-            .err_set_cast,
             .ptr_cast,
             .truncate,
             .align_cast,
@@ -2386,15 +2391,24 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner
             .c_import,
             .@"resume",
             .@"await",
-            .await_nosuspend,
             .ret_err_value_code,
-            .extended,
             .closure_get,
             .array_base_ptr,
             .field_base_ptr,
             .param_type,
+            .ret_ptr,
+            .ret_type,
             => break :b false,
 
+            .extended => switch (gz.astgen.instructions.items(.data)[inst].extended.opcode) {
+                .breakpoint,
+                .fence,
+                .set_align_stack,
+                .set_float_mode,
+                => break :b true,
+                else => break :b false,
+            },
+
             // ZIR instructions that are always `noreturn`.
             .@"break",
             .break_inline,
@@ -2415,11 +2429,11 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner
             },
 
             // ZIR instructions that are always `void`.
-            .breakpoint,
-            .fence,
             .dbg_stmt,
             .dbg_var_ptr,
             .dbg_var_val,
+            .dbg_block_begin,
+            .dbg_block_end,
             .ensure_result_used,
             .ensure_result_non_error,
             .@"export",
@@ -2436,9 +2450,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner
             .validate_struct_init_comptime,
             .validate_array_init,
             .validate_array_init_comptime,
-            .set_align_stack,
             .set_cold,
-            .set_float_mode,
             .set_runtime_safety,
             .closure_capture,
             .memcpy,
@@ -6310,9 +6322,9 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref
     }
 
     const rl: ResultLoc = if (nodeMayNeedMemoryLocation(tree, operand_node, true)) .{
-        .ptr = try gz.addNodeExtended(.ret_ptr, node),
+        .ptr = try gz.addNode(.ret_ptr, node),
     } else .{
-        .ty = try gz.addNodeExtended(.ret_type, node),
+        .ty = try gz.addNode(.ret_type, node),
     };
     const prev_anon_name_strategy = gz.anon_name_strategy;
     gz.anon_name_strategy = .func;
@@ -7183,7 +7195,26 @@ fn builtinCall(
         },
         .fence => {
             const order = try expr(gz, scope, .{ .coerced_ty = .atomic_order_type }, params[0]);
-            const result = try gz.addUnNode(.fence, order, node);
+            const result = try gz.addExtendedPayload(.fence, Zir.Inst.UnNode{
+                .node = gz.nodeIndexToRelative(node),
+                .operand = order,
+            });
+            return rvalue(gz, rl, result, node);
+        },
+        .set_float_mode => {
+            const order = try expr(gz, scope, .{ .coerced_ty = .float_mode_type }, params[0]);
+            const result = try gz.addExtendedPayload(.set_float_mode, Zir.Inst.UnNode{
+                .node = gz.nodeIndexToRelative(node),
+                .operand = order,
+            });
+            return rvalue(gz, rl, result, node);
+        },
+        .set_align_stack => {
+            const order = try expr(gz, scope, align_rl, params[0]);
+            const result = try gz.addExtendedPayload(.set_align_stack, Zir.Inst.UnNode{
+                .node = gz.nodeIndexToRelative(node),
+                .operand = order,
+            });
             return rvalue(gz, rl, result, node);
         },
 
@@ -7198,14 +7229,13 @@ fn builtinCall(
             return rvalue(gz, rl, result, node);
         },
 
-        .breakpoint => return simpleNoOpVoid(gz, rl, node, .breakpoint),
-
         // zig fmt: off
         .This               => return rvalue(gz, rl, try gz.addNodeExtended(.this,               node), node),
         .return_address     => return rvalue(gz, rl, try gz.addNodeExtended(.ret_addr,           node), node),
         .error_return_trace => return rvalue(gz, rl, try gz.addNodeExtended(.error_return_trace, node), node),
         .frame              => return rvalue(gz, rl, try gz.addNodeExtended(.frame,              node), node),
         .frame_address      => return rvalue(gz, rl, try gz.addNodeExtended(.frame_address,      node), node),
+        .breakpoint         => return rvalue(gz, rl, try gz.addNodeExtended(.breakpoint, node), node),
 
         .type_info   => return simpleUnOpType(gz, scope, rl, node, params[0], .type_info),
         .size_of     => return simpleUnOpType(gz, scope, rl, node, params[0], .size_of),
@@ -7222,9 +7252,7 @@ fn builtinCall(
         .embed_file            => return simpleUnOp(gz, scope, rl, node, .{ .ty = .const_slice_u8_type },     params[0], .embed_file),
         .error_name            => return simpleUnOp(gz, scope, rl, node, .{ .ty = .anyerror_type },           params[0], .error_name),
         .panic                 => return simpleUnOp(gz, scope, rl, node, .{ .ty = .const_slice_u8_type },     params[0], .panic),
-        .set_align_stack       => return simpleUnOp(gz, scope, rl, node, align_rl,                            params[0], .set_align_stack),
         .set_cold              => return simpleUnOp(gz, scope, rl, node, bool_rl,                             params[0], .set_cold),
-        .set_float_mode        => return simpleUnOp(gz, scope, rl, node, .{ .coerced_ty = .float_mode_type }, params[0], .set_float_mode),
         .set_runtime_safety    => return simpleUnOp(gz, scope, rl, node, bool_rl,                             params[0], .set_runtime_safety),
         .sqrt                  => return simpleUnOp(gz, scope, rl, node, .none,                               params[0], .sqrt),
         .sin                   => return simpleUnOp(gz, scope, rl, node, .none,                               params[0], .sin),
@@ -7252,7 +7280,6 @@ fn builtinCall(
         .int_to_enum  => return typeCast(gz, scope, rl, node, params[0], params[1], .int_to_enum),
         .float_cast   => return typeCast(gz, scope, rl, node, params[0], params[1], .float_cast),
         .int_cast     => return typeCast(gz, scope, rl, node, params[0], params[1], .int_cast),
-        .err_set_cast => return typeCast(gz, scope, rl, node, params[0], params[1], .err_set_cast),
         .ptr_cast     => return typeCast(gz, scope, rl, node, params[0], params[1], .ptr_cast),
         .truncate     => return typeCast(gz, scope, rl, node, params[0], params[1], .truncate),
         // zig fmt: on
@@ -7266,6 +7293,14 @@ fn builtinCall(
             });
             return rvalue(gz, rl, result, node);
         },
+        .err_set_cast => {
+            const result = try gz.addExtendedPayload(.err_set_cast, Zir.Inst.BinNode{
+                .lhs = try typeExpr(gz, scope, params[0]),
+                .rhs = try expr(gz, scope, .none, params[1]),
+                .node = gz.nodeIndexToRelative(node),
+            });
+            return rvalue(gz, rl, result, node);
+        },
 
         // zig fmt: off
         .has_decl  => return hasDeclOrField(gz, scope, rl, node, params[0], params[1], .has_decl),
@@ -8940,7 +8975,8 @@ fn rvalue(
     const result = r: {
         if (refToIndex(raw_result)) |result_index| {
             const zir_tags = gz.astgen.instructions.items(.tag);
-            if (zir_tags[result_index].isAlwaysVoid()) {
+            const data = gz.astgen.instructions.items(.data)[result_index];
+            if (zir_tags[result_index].isAlwaysVoid(data)) {
                 break :r Zir.Inst.Ref.void_value;
             }
         }
@@ -10893,9 +10929,7 @@ const GenZir = struct {
     fn addDbgBlockBegin(gz: *GenZir) !void {
         if (gz.force_comptime) return;
 
-        _ = try gz.add(.{ .tag = .extended, .data = .{
-            .extended = .{ .opcode = .dbg_block_begin, .small = undefined, .operand = undefined },
-        } });
+        _ = try gz.add(.{ .tag = .dbg_block_begin, .data = undefined });
     }
 
     fn addDbgBlockEnd(gz: *GenZir) !void {
@@ -10903,18 +10937,15 @@ const GenZir = struct {
         const gpa = gz.astgen.gpa;
 
         const tags = gz.astgen.instructions.items(.tag);
-        const data = gz.astgen.instructions.items(.data);
         const last_inst = gz.instructions.items[gz.instructions.items.len - 1];
         // remove dbg_block_begin immediately followed by dbg_block_end
-        if (tags[last_inst] == .extended and data[last_inst].extended.opcode == .dbg_block_begin) {
+        if (tags[last_inst] == .dbg_block_begin) {
             _ = gz.instructions.pop();
             return;
         }
 
         const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len);
-        try gz.astgen.instructions.append(gpa, .{ .tag = .extended, .data = .{
-            .extended = .{ .opcode = .dbg_block_end, .small = undefined, .operand = undefined },
-        } });
+        try gz.astgen.instructions.append(gpa, .{ .tag = .dbg_block_end, .data = undefined });
         try gz.instructions.insert(gpa, gz.instructions.items.len - 1, new_index);
     }
 
src/print_zir.zig
@@ -200,9 +200,7 @@ const Writer = struct {
             .embed_file,
             .error_name,
             .panic,
-            .set_align_stack,
             .set_cold,
-            .set_float_mode,
             .set_runtime_safety,
             .sqrt,
             .sin,
@@ -231,8 +229,6 @@ const Writer = struct {
             .elem_type,
             .@"resume",
             .@"await",
-            .await_nosuspend,
-            .fence,
             .switch_cond,
             .switch_cond_ref,
             .array_base_ptr,
@@ -343,7 +339,6 @@ const Writer = struct {
             .int_to_enum,
             .float_cast,
             .int_cast,
-            .err_set_cast,
             .ptr_cast,
             .truncate,
             .align_cast,
@@ -405,13 +400,14 @@ const Writer = struct {
 
             .as_node => try self.writeAs(stream, inst),
 
-            .breakpoint,
             .repeat,
             .repeat_inline,
             .alloc_inferred,
             .alloc_inferred_mut,
             .alloc_inferred_comptime,
             .alloc_inferred_comptime_mut,
+            .ret_ptr,
+            .ret_type,
             => try self.writeNode(stream, inst),
 
             .error_value,
@@ -444,6 +440,10 @@ const Writer = struct {
 
             .dbg_stmt => try self.writeDbgStmt(stream, inst),
 
+            .dbg_block_begin,
+            .dbg_block_end,
+            => try stream.writeAll("))"),
+
             .closure_get => try self.writeInstNode(stream, inst),
 
             .extended => try self.writeExtended(stream, inst),
@@ -454,13 +454,12 @@ const Writer = struct {
         const extended = self.code.instructions.items(.data)[inst].extended;
         try stream.print("{s}(", .{@tagName(extended.opcode)});
         switch (extended.opcode) {
-            .ret_ptr,
-            .ret_type,
             .this,
             .ret_addr,
             .error_return_trace,
             .frame,
             .frame_address,
+            .breakpoint,
             => try self.writeExtNode(stream, extended),
 
             .builtin_src => {
@@ -469,10 +468,6 @@ const Writer = struct {
                 try stream.print(":{d}:{d}", .{ inst_data.line + 1, inst_data.column + 1 });
             },
 
-            .dbg_block_begin,
-            .dbg_block_end,
-            => try stream.writeAll("))"),
-
             .@"asm" => try self.writeAsm(stream, extended),
             .func => try self.writeFuncExtended(stream, extended),
             .variable => try self.writeVarExtended(stream, extended),
@@ -492,7 +487,14 @@ const Writer = struct {
             .enum_decl => try self.writeEnumDecl(stream, extended),
             .opaque_decl => try self.writeOpaqueDecl(stream, extended),
 
-            .c_undef, .c_include, .wasm_memory_size => {
+            .await_nosuspend,
+            .c_undef,
+            .c_include,
+            .fence,
+            .set_float_mode,
+            .set_align_stack,
+            .wasm_memory_size,
+            => {
                 const inst_data = self.code.extraData(Zir.Inst.UnNode, extended.operand).data;
                 const src: LazySrcLoc = .{ .node_offset = inst_data.node };
                 try self.writeInstRef(stream, inst_data.operand);
@@ -500,7 +502,12 @@ const Writer = struct {
                 try self.writeSrc(stream, src);
             },
 
-            .builtin_extern, .c_define, .wasm_memory_grow, .prefetch => {
+            .builtin_extern,
+            .c_define,
+            .err_set_cast,
+            .wasm_memory_grow,
+            .prefetch,
+            => {
                 const inst_data = self.code.extraData(Zir.Inst.BinNode, extended.operand).data;
                 const src: LazySrcLoc = .{ .node_offset = inst_data.node };
                 try self.writeInstRef(stream, inst_data.lhs);
src/Sema.zig
@@ -819,7 +819,6 @@ fn analyzeBodyInner(
             .int_to_ptr                   => try sema.zirIntToPtr(block, inst),
             .float_cast                   => try sema.zirFloatCast(block, inst),
             .int_cast                     => try sema.zirIntCast(block, inst),
-            .err_set_cast                 => try sema.zirErrSetCast(block, inst),
             .ptr_cast                     => try sema.zirPtrCast(block, inst),
             .truncate                     => try sema.zirTruncate(block, inst),
             .align_cast                   => try sema.zirAlignCast(block, inst),
@@ -842,8 +841,7 @@ fn analyzeBodyInner(
             .field_parent_ptr             => try sema.zirFieldParentPtr(block, inst),
             .builtin_async_call           => try sema.zirBuiltinAsyncCall(block, inst),
             .@"resume"                    => try sema.zirResume(block, inst),
-            .@"await"                     => try sema.zirAwait(block, inst, false),
-            .await_nosuspend              => try sema.zirAwait(block, inst, true),
+            .@"await"                     => try sema.zirAwait(block, inst),
             .array_base_ptr               => try sema.zirArrayBasePtr(block, inst),
             .field_base_ptr               => try sema.zirFieldBasePtr(block, inst),
 
@@ -894,6 +892,9 @@ fn analyzeBodyInner(
             .shl_exact => try sema.zirShl(block, inst, .shl_exact),
             .shl_sat   => try sema.zirShl(block, inst, .shl_sat),
 
+            .ret_ptr  => try sema.zirRetPtr(block, inst),
+            .ret_type => try sema.zirRetType(block, inst),
+
             // Instructions that we know to *always* be noreturn based solely on their tag.
             // These functions match the return type of analyzeBody so that we can
             // tail call them here.
@@ -916,8 +917,6 @@ fn analyzeBodyInner(
                     .enum_decl             => try sema.zirEnumDecl(          block, extended),
                     .union_decl            => try sema.zirUnionDecl(         block, extended, inst),
                     .opaque_decl           => try sema.zirOpaqueDecl(        block, extended),
-                    .ret_ptr               => try sema.zirRetPtr(            block, extended),
-                    .ret_type              => try sema.zirRetType(           block, extended),
                     .this                  => try sema.zirThis(              block, extended),
                     .ret_addr              => try sema.zirRetAddr(           block, extended),
                     .builtin_src           => try sema.zirBuiltinSrc(        block, extended),
@@ -940,16 +939,28 @@ fn analyzeBodyInner(
                     .wasm_memory_grow      => try sema.zirWasmMemoryGrow(    block, extended),
                     .prefetch              => try sema.zirPrefetch(          block, extended),
                     .field_call_bind_named => try sema.zirFieldCallBindNamed(block, extended),
+                    .err_set_cast          => try sema.zirErrSetCast(        block, extended),
+                    .await_nosuspend       => try sema.zirAwaitNosuspend(    block, extended),
                     // zig fmt: on
-                    .dbg_block_begin => {
-                        dbg_block_begins += 1;
-                        try sema.zirDbgBlockBegin(block);
+                    .fence => {
+                        try sema.zirFence(block, extended);
                         i += 1;
                         continue;
                     },
-                    .dbg_block_end => {
-                        dbg_block_begins -= 1;
-                        try sema.zirDbgBlockEnd(block);
+                    .set_float_mode => {
+                        try sema.zirSetFloatMode(block, extended);
+                        i += 1;
+                        continue;
+                    },
+                    .set_align_stack => {
+                        try sema.zirSetAlignStack(block, extended);
+                        i += 1;
+                        continue;
+                    },
+                    .breakpoint => {
+                        if (!block.is_comptime) {
+                            _ = try block.addNoOp(.breakpoint);
+                        }
                         i += 1;
                         continue;
                     },
@@ -961,18 +972,6 @@ fn analyzeBodyInner(
             // continue the loop.
             // We also know that they cannot be referenced later, so we avoid
             // putting them into the map.
-            .breakpoint => {
-                if (!block.is_comptime) {
-                    _ = try block.addNoOp(.breakpoint);
-                }
-                i += 1;
-                continue;
-            },
-            .fence => {
-                try sema.zirFence(block, inst);
-                i += 1;
-                continue;
-            },
             .dbg_stmt => {
                 try sema.zirDbgStmt(block, inst);
                 i += 1;
@@ -988,6 +987,18 @@ fn analyzeBodyInner(
                 i += 1;
                 continue;
             },
+            .dbg_block_begin => {
+                dbg_block_begins += 1;
+                try sema.zirDbgBlockBegin(block);
+                i += 1;
+                continue;
+            },
+            .dbg_block_end => {
+                dbg_block_begins -= 1;
+                try sema.zirDbgBlockEnd(block);
+                i += 1;
+                continue;
+            },
             .ensure_err_payload_void => {
                 try sema.zirEnsureErrPayloadVoid(block, inst);
                 i += 1;
@@ -1078,21 +1089,11 @@ fn analyzeBodyInner(
                 i += 1;
                 continue;
             },
-            .set_align_stack => {
-                try sema.zirSetAlignStack(block, inst);
-                i += 1;
-                continue;
-            },
             .set_cold => {
                 try sema.zirSetCold(block, inst);
                 i += 1;
                 continue;
             },
-            .set_float_mode => {
-                try sema.zirSetFloatMode(block, inst);
-                i += 1;
-                continue;
-            },
             .set_runtime_safety => {
                 try sema.zirSetRuntimeSafety(block, inst);
                 i += 1;
@@ -2452,15 +2453,12 @@ fn zirErrorSetDecl(
     return sema.analyzeDeclVal(block, src, new_decl_index);
 }
 
-fn zirRetPtr(
-    sema: *Sema,
-    block: *Block,
-    extended: Zir.Inst.Extended.InstData,
-) CompileError!Air.Inst.Ref {
+fn zirRetPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
     const tracy = trace(@src());
     defer tracy.end();
 
-    const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };
+    const inst_data = sema.code.instructions.items(.data)[inst].node;
+    const src: LazySrcLoc = .{ .node_offset = inst_data };
     try sema.requireFunctionBlock(block, src);
 
     if (block.is_comptime) {
@@ -2493,15 +2491,12 @@ fn zirRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
     return sema.analyzeRef(block, inst_data.src(), operand);
 }
 
-fn zirRetType(
-    sema: *Sema,
-    block: *Block,
-    extended: Zir.Inst.Extended.InstData,
-) CompileError!Air.Inst.Ref {
+fn zirRetType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
     const tracy = trace(@src());
     defer tracy.end();
 
-    const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };
+    const inst_data = sema.code.instructions.items(.data)[inst].node;
+    const src: LazySrcLoc = .{ .node_offset = inst_data };
     try sema.requireFunctionBlock(block, src);
     return sema.addType(sema.fn_ret_ty);
 }
@@ -3746,9 +3741,7 @@ fn zirStoreNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!v
         sema.fn_ret_ty.zigTypeTag() == .ErrorUnion)
     {
         if (Zir.refToIndex(extra.lhs)) |ptr_index| {
-            if (zir_tags[ptr_index] == .extended and
-                zir_datas[ptr_index].extended.opcode == .ret_ptr)
-            {
+            if (zir_tags[ptr_index] == .ret_ptr) {
                 try sema.addToInferredErrorSet(operand);
             }
         }
@@ -4392,11 +4385,11 @@ pub fn analyzeExport(
     errdefer de_gop.value_ptr.* = gpa.shrink(de_gop.value_ptr.*, de_gop.value_ptr.len - 1);
 }
 
-fn zirSetAlignStack(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
-    const inst_data = sema.code.instructions.items(.data)[inst].un_node;
-    const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
-    const src: LazySrcLoc = inst_data.src();
-    const alignment = try sema.resolveAlign(block, operand_src, inst_data.operand);
+fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
+    const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
+    const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
+    const src: LazySrcLoc = .{ .node_offset = extra.node };
+    const alignment = try sema.resolveAlign(block, operand_src, extra.operand);
     if (alignment > 256) {
         return sema.fail(block, src, "attempt to @setAlignStack({d}); maximum is 256", .{
             alignment,
@@ -4433,10 +4426,10 @@ fn zirSetCold(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!voi
     func.is_cold = is_cold;
 }
 
-fn zirSetFloatMode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
-    const inst_data = sema.code.instructions.items(.data)[inst].un_node;
-    const src: LazySrcLoc = inst_data.src();
-    const float_mode = try sema.resolveBuiltinEnum(block, src, inst_data.operand, "FloatMode");
+fn zirSetFloatMode(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
+    const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
+    const src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
+    const float_mode = try sema.resolveBuiltinEnum(block, src, extra.operand, "FloatMode");
     switch (float_mode) {
         .Strict => return,
         .Optimized => {
@@ -4451,12 +4444,12 @@ fn zirSetRuntimeSafety(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compile
     block.want_safety = try sema.resolveConstBool(block, operand_src, inst_data.operand);
 }
 
-fn zirFence(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
+fn zirFence(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
     if (block.is_comptime) return;
 
-    const inst_data = sema.code.instructions.items(.data)[inst].un_node;
-    const order_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
-    const order = try sema.resolveAtomicOrder(block, order_src, inst_data.operand);
+    const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
+    const order_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
+    const order = try sema.resolveAtomicOrder(block, order_src, extra.operand);
 
     if (@enumToInt(order) < @enumToInt(std.builtin.AtomicOrder.Acquire)) {
         return sema.fail(block, order_src, "atomic ordering must be Acquire or stricter", .{});
@@ -14144,12 +14137,11 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
     return block.addBitCast(type_res, operand_coerced);
 }
 
-fn zirErrSetCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
-    const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
-    const src = inst_data.src();
-    const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
-    const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
-    const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
+fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
+    const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
+    const src: LazySrcLoc = .{ .node_offset = extra.node };
+    const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
+    const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };
     const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);
     const operand = sema.resolveInst(extra.rhs);
     const operand_ty = sema.typeOf(operand);
@@ -16007,15 +15999,24 @@ fn zirAwait(
     sema: *Sema,
     block: *Block,
     inst: Zir.Inst.Index,
-    is_nosuspend: bool,
 ) CompileError!Air.Inst.Ref {
     const inst_data = sema.code.instructions.items(.data)[inst].un_node;
     const src = inst_data.src();
 
-    _ = is_nosuspend;
     return sema.fail(block, src, "TODO: Sema.zirAwait", .{});
 }
 
+fn zirAwaitNosuspend(
+    sema: *Sema,
+    block: *Block,
+    extended: Zir.Inst.Extended.InstData,
+) CompileError!Air.Inst.Ref {
+    const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
+    const src: LazySrcLoc = .{ .node_offset = extra.node };
+
+    return sema.fail(block, src, "TODO: Sema.zirAwaitNosuspend", .{});
+}
+
 fn zirVarExtended(
     sema: *Sema,
     block: *Block,
src/Zir.zig
@@ -278,8 +278,6 @@ pub const Inst = struct {
         /// break instruction in a block, and the target block is the parent.
         /// Uses the `break` union field.
         break_inline,
-        /// Uses the `node` union field.
-        breakpoint,
         /// Function call.
         /// Uses `pl_node`. AST node is the function call. Payload is `Call`.
         call,
@@ -331,6 +329,10 @@ pub const Inst = struct {
         /// Same as `dbg_var_ptr` but the local is always a const and the operand
         /// is the local's value.
         dbg_var_val,
+        /// Marks the beginning of a semantic scope for debug info variables.
+        dbg_block_begin,
+        /// Marks the end of a semantic scope for debug info variables.
+        dbg_block_end,
         /// Uses a name to identify a Decl and takes a pointer to it.
         /// Uses the `str_tok` union field.
         decl_ref,
@@ -499,6 +501,12 @@ pub const Inst = struct {
         /// this instruction; a following 'ret' instruction will do the diversion.
         /// Uses the `str_tok` union field.
         ret_err_value_code,
+        /// Obtains a pointer to the return value.
+        /// Uses the `node` union field.
+        ret_ptr,
+        /// Obtains the return type of the in-scope function.
+        /// Uses the `node` union field.
+        ret_type,
         /// Create a pointer type that does not have a sentinel, alignment, address space, or bit range specified.
         /// Uses the `ptr_type_simple` union field.
         ptr_type_simple,
@@ -744,8 +752,6 @@ pub const Inst = struct {
         size_of,
         /// Implements the `@bitSizeOf` builtin. Uses `un_node`.
         bit_size_of,
-        /// Implements the `@fence` builtin. Uses `un_node`.
-        fence,
 
         /// Implement builtin `@ptrToInt`. Uses `un_node`.
         /// Convert a pointer to a `usize` integer.
@@ -774,12 +780,8 @@ pub const Inst = struct {
         error_name,
         /// Implement builtin `@panic`. Uses `un_node`.
         panic,
-        /// Implement builtin `@setAlignStack`. Uses `un_node`.
-        set_align_stack,
         /// Implement builtin `@setCold`. Uses `un_node`.
         set_cold,
-        /// Implement builtin `@setFloatMode`. Uses `un_node`.
-        set_float_mode,
         /// Implement builtin `@setRuntimeSafety`. Uses `un_node`.
         set_runtime_safety,
         /// Implement builtin `@sqrt`. Uses `un_node`.
@@ -843,9 +845,6 @@ pub const Inst = struct {
         /// Convert an integer value to another integer type, asserting that the destination type
         /// can hold the same mathematical value.
         int_cast,
-        /// Implements the `@errSetCast` builtin.
-        /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.
-        err_set_cast,
         /// Implements the `@ptrCast` builtin.
         /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.
         ptr_cast,
@@ -972,7 +971,6 @@ pub const Inst = struct {
         /// Implements `resume` syntax. Uses `un_node` field.
         @"resume",
         @"await",
-        await_nosuspend,
 
         /// When a type or function refers to a comptime value from an outer
         /// scope, that forms a closure over comptime value.  The outer scope
@@ -1028,8 +1026,6 @@ pub const Inst = struct {
                 .bool_br_and,
                 .bool_br_or,
                 .bool_not,
-                .breakpoint,
-                .fence,
                 .call,
                 .cmp_lt,
                 .cmp_lte,
@@ -1044,6 +1040,8 @@ pub const Inst = struct {
                 .dbg_stmt,
                 .dbg_var_ptr,
                 .dbg_var_val,
+                .dbg_block_begin,
+                .dbg_block_end,
                 .decl_ref,
                 .decl_val,
                 .load,
@@ -1164,9 +1162,7 @@ pub const Inst = struct {
                 .bool_to_int,
                 .embed_file,
                 .error_name,
-                .set_align_stack,
                 .set_cold,
-                .set_float_mode,
                 .set_runtime_safety,
                 .sqrt,
                 .sin,
@@ -1192,7 +1188,6 @@ pub const Inst = struct {
                 .int_to_ptr,
                 .float_cast,
                 .int_cast,
-                .err_set_cast,
                 .ptr_cast,
                 .truncate,
                 .align_cast,
@@ -1231,11 +1226,12 @@ pub const Inst = struct {
                 .c_import,
                 .@"resume",
                 .@"await",
-                .await_nosuspend,
                 .ret_err_value_code,
                 .extended,
                 .closure_get,
                 .closure_capture,
+                .ret_ptr,
+                .ret_type,
                 => false,
 
                 .@"break",
@@ -1258,13 +1254,13 @@ pub const Inst = struct {
         /// AstGen uses this to find out if `Ref.void_value` should be used in place
         /// of the result of a given instruction. This allows Sema to forego adding
         /// the instruction to the map after analysis.
-        pub fn isAlwaysVoid(tag: Tag) bool {
+        pub fn isAlwaysVoid(tag: Tag, data: Data) bool {
             return switch (tag) {
-                .breakpoint,
-                .fence,
                 .dbg_stmt,
                 .dbg_var_ptr,
                 .dbg_var_val,
+                .dbg_block_begin,
+                .dbg_block_end,
                 .ensure_result_used,
                 .ensure_result_non_error,
                 .ensure_err_payload_void,
@@ -1283,9 +1279,7 @@ pub const Inst = struct {
                 .validate_array_init_comptime,
                 .@"export",
                 .export_value,
-                .set_align_stack,
                 .set_cold,
-                .set_float_mode,
                 .set_runtime_safety,
                 .memcpy,
                 .memset,
@@ -1464,7 +1458,6 @@ pub const Inst = struct {
                 .int_to_ptr,
                 .float_cast,
                 .int_cast,
-                .err_set_cast,
                 .ptr_cast,
                 .truncate,
                 .align_cast,
@@ -1500,9 +1493,7 @@ pub const Inst = struct {
                 .c_import,
                 .@"resume",
                 .@"await",
-                .await_nosuspend,
                 .ret_err_value_code,
-                .extended,
                 .closure_get,
                 .closure_capture,
                 .@"break",
@@ -1514,11 +1505,18 @@ pub const Inst = struct {
                 .ret_load,
                 .ret_tok,
                 .ret_err_value,
+                .ret_ptr,
+                .ret_type,
                 .@"unreachable",
                 .repeat,
                 .repeat_inline,
                 .panic,
                 => false,
+
+                .extended => switch (data.extended.opcode) {
+                    .breakpoint, .fence => true,
+                    else => false,
+                },
             };
         }
 
@@ -1563,7 +1561,6 @@ pub const Inst = struct {
                 .bool_br_or = .bool_br,
                 .@"break" = .@"break",
                 .break_inline = .@"break",
-                .breakpoint = .node,
                 .call = .pl_node,
                 .cmp_lt = .pl_node,
                 .cmp_lte = .pl_node,
@@ -1580,6 +1577,8 @@ pub const Inst = struct {
                 .dbg_stmt = .dbg_stmt,
                 .dbg_var_ptr = .str_op,
                 .dbg_var_val = .str_op,
+                .dbg_block_begin = .tok,
+                .dbg_block_end = .tok,
                 .decl_ref = .str_tok,
                 .decl_val = .str_tok,
                 .load = .un_node,
@@ -1623,6 +1622,8 @@ pub const Inst = struct {
                 .ret_tok = .un_tok,
                 .ret_err_value = .str_tok,
                 .ret_err_value_code = .str_tok,
+                .ret_ptr = .node,
+                .ret_type = .node,
                 .ptr_type_simple = .ptr_type_simple,
                 .ptr_type = .ptr_type,
                 .slice_start = .pl_node,
@@ -1685,7 +1686,6 @@ pub const Inst = struct {
                 .type_info = .un_node,
                 .size_of = .un_node,
                 .bit_size_of = .un_node,
-                .fence = .un_node,
 
                 .ptr_to_int = .un_node,
                 .error_to_int = .un_node,
@@ -1698,9 +1698,7 @@ pub const Inst = struct {
                 .embed_file = .un_node,
                 .error_name = .un_node,
                 .panic = .un_node,
-                .set_align_stack = .un_node,
                 .set_cold = .un_node,
-                .set_float_mode = .un_node,
                 .set_runtime_safety = .un_node,
                 .sqrt = .un_node,
                 .sin = .un_node,
@@ -1728,7 +1726,6 @@ pub const Inst = struct {
                 .int_to_enum = .pl_node,
                 .float_cast = .pl_node,
                 .int_cast = .pl_node,
-                .err_set_cast = .pl_node,
                 .ptr_cast = .pl_node,
                 .truncate = .pl_node,
                 .align_cast = .pl_node,
@@ -1788,7 +1785,6 @@ pub const Inst = struct {
 
                 .@"resume" = .un_node,
                 .@"await" = .un_node,
-                .await_nosuspend = .un_node,
 
                 .closure_capture = .un_tok,
                 .closure_get = .inst_node,
@@ -1834,12 +1830,6 @@ pub const Inst = struct {
         /// `operand` is payload index to `OpaqueDecl`.
         /// `small` is `OpaqueDecl.Small`.
         opaque_decl,
-        /// Obtains a pointer to the return value.
-        /// `operand` is `src_node: i32`.
-        ret_ptr,
-        /// Obtains the return type of the in-scope function.
-        /// `operand` is `src_node: i32`.
-        ret_type,
         /// Implements the `@This` builtin.
         /// `operand` is `src_node: i32`.
         this,
@@ -1917,10 +1907,6 @@ pub const Inst = struct {
         /// The `@prefetch` builtin.
         /// `operand` is payload index to `BinNode`.
         prefetch,
-        /// Marks the beginning of a semantic scope for debug info variables.
-        dbg_block_begin,
-        /// Marks the end of a semantic scope for debug info variables.
-        dbg_block_end,
         /// Given a pointer to a struct or object that contains virtual fields, returns the
         /// named field.  If there is no named field, searches in the type for a decl that
         /// matches the field name.  The decl is resolved and we ensure that it's a function
@@ -1931,6 +1917,22 @@ pub const Inst = struct {
         /// `builtin_call` instruction.  Any other use is invalid zir and may crash the compiler.
         /// Uses `pl_node` field. The AST node is the `@field` builtin. Payload is FieldNamedNode.
         field_call_bind_named,
+        /// Implements the `@fence` builtin.
+        /// `operand` is payload index to `UnNode`.
+        fence,
+        /// Implement builtin `@setFloatMode`.
+        /// `operand` is payload index to `UnNode`.
+        set_float_mode,
+        /// Implement builtin `@setAlignStack`.
+        /// `operand` is payload index to `UnNode`.
+        set_align_stack,
+        /// Implements the `@errSetCast` builtin.
+        /// `operand` is payload index to `BinNode`. `lhs` is dest type, `rhs` is operand.
+        err_set_cast,
+        /// `operand` is payload index to `UnNode`.
+        await_nosuspend,
+        /// `operand` is `src_node: i32`.
+        breakpoint,
 
         pub const InstData = struct {
             opcode: Extended,