authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-10 23:25:43-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-10 23:25:43-04:00
loga0427d29e4d3c47f470d88a4afdd0e87d3373325
tree103027c958819b5fa0de1eecf0b552270c4fd6a0
parent4582ec518f9984a26c68b8427a914bad6dc80c4a
signature Commit is signed but in an unrecognized format.

fix peer result locations in the face of unreachable

```zig export fn entry() void { var nothing: ?*i32 = null; var whatever = if (nothing) |x1| i32(1) else unreachable; } ``` ```llvm define void @entry() #2 !dbg !35 { Entry: %nothing = alloca i32*, align 8 %whatever = alloca i32, align 4 store i32* null, i32** %nothing, align 8, !dbg !45 call void @llvm.dbg.declare(metadata i32** %nothing, metadata !39, metadata !DIExpression()), !dbg !45 %0 = load i32*, i32** %nothing, align 8, !dbg !46 %1 = icmp ne i32* %0, null, !dbg !46 br i1 %1, label %OptionalThen, label %OptionalElse, !dbg !46 OptionalThen: ; preds = %Entry call void @llvm.dbg.declare(metadata i32** %nothing, metadata !43, metadata !DIExpression()), !dbg !46 store i32 1, i32* %whatever, align 4, !dbg !47 br label %OptionalEndIf, !dbg !46 OptionalElse: ; preds = %Entry tail call fastcc void @panic(%"[]u8"* @1, %builtin.StackTrace* null), !dbg !48 unreachable, !dbg !48 OptionalEndIf: ; preds = %OptionalThen call void @llvm.dbg.declare(metadata i32* %whatever, metadata !44, metadata !DIExpression()), !dbg !49 ret void, !dbg !50 } ```

2 files changed, 122 insertions(+), 71 deletions(-)

src/all_types.hpp+5-1
......@@ -43,6 +43,7 @@ struct TldExport;
4343struct IrAnalyze;
4444struct ResultLoc;
4545struct ResultLocPeer;
46struct ResultLocPeerParent;
4647
4748enum X64CABIClass {
4849 X64CABIClass_Unknown,
......@@ -2163,6 +2164,9 @@ struct IrBasicBlock {
21632164 // if the branch is comptime. The instruction points to the reason
21642165 // the basic block must be comptime.
21652166 IrInstruction *must_be_comptime_source_instr;
2167 IrInstruction *suspend_instruction_ref;
2168 bool already_appended;
2169 bool suspended;
21662170};
21672171
21682172// These instructions are in transition to having "pass 1" instructions
......@@ -2434,6 +2438,7 @@ struct IrInstructionPhi {
24342438 size_t incoming_count;
24352439 IrBasicBlock **incoming_blocks;
24362440 IrInstruction **incoming_values;
2441 ResultLocPeerParent *peer_parent;
24372442};
24382443
24392444enum IrUnOp {
......@@ -3646,7 +3651,6 @@ struct IrSuspendPosition {
36463651struct ResultLocPeer {
36473652 ResultLoc base;
36483653
3649 bool seen_before;
36503654 ResultLocPeerParent *parent;
36513655 IrBasicBlock *next_bb;
36523656 IrSuspendPosition suspend_pos;
src/ir.cpp+117-70
......@@ -1406,7 +1406,8 @@ static IrInstruction *ir_build_call_gen(IrAnalyze *ira, IrInstruction *source_in
14061406}
14071407
14081408static IrInstruction *ir_build_phi(IrBuilder *irb, Scope *scope, AstNode *source_node,
1409 size_t incoming_count, IrBasicBlock **incoming_blocks, IrInstruction **incoming_values)
1409 size_t incoming_count, IrBasicBlock **incoming_blocks, IrInstruction **incoming_values,
1410 ResultLocPeerParent *peer_parent)
14101411{
14111412 assert(incoming_count != 0);
14121413 assert(incoming_count != SIZE_MAX);
......@@ -1415,6 +1416,7 @@ static IrInstruction *ir_build_phi(IrBuilder *irb, Scope *scope, AstNode *source
14151416 phi_instruction->incoming_count = incoming_count;
14161417 phi_instruction->incoming_blocks = incoming_blocks;
14171418 phi_instruction->incoming_values = incoming_values;
1419 phi_instruction->peer_parent = peer_parent;
14181420
14191421 for (size_t i = 0; i < incoming_count; i += 1) {
14201422 ir_ref_bb(incoming_blocks[i]);
......@@ -3700,7 +3702,8 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode
37003702 }
37013703
37023704 ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block);
3703 return ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, incoming_blocks.items, incoming_values.items);
3705 return ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length,
3706 incoming_blocks.items, incoming_values.items, nullptr);
37043707 } else {
37053708 incoming_blocks.append(irb->current_basic_block);
37063709 incoming_values.append(ir_mark_gen(ir_build_const_void(irb, parent_scope, block_node)));
......@@ -3710,7 +3713,8 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode
37103713 ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false);
37113714 ir_mark_gen(ir_build_br(irb, parent_scope, block_node, scope_block->end_block, scope_block->is_comptime));
37123715 ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block);
3713 return ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, incoming_blocks.items, incoming_values.items);
3716 return ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length,
3717 incoming_blocks.items, incoming_values.items, nullptr);
37143718 } else {
37153719 ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false);
37163720 return ir_mark_gen(ir_mark_gen(ir_build_const_void(irb, child_scope, block_node)));
......@@ -3795,7 +3799,7 @@ static IrInstruction *ir_gen_bool_or(IrBuilder *irb, Scope *scope, AstNode *node
37953799 incoming_blocks[0] = post_val1_block;
37963800 incoming_blocks[1] = post_val2_block;
37973801
3798 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values);
3802 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr);
37993803}
38003804
38013805static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *node) {
......@@ -3837,7 +3841,7 @@ static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *nod
38373841 incoming_blocks[0] = post_val1_block;
38383842 incoming_blocks[1] = post_val2_block;
38393843
3840 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values);
3844 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr);
38413845}
38423846
38433847static ResultLocPeerParent *create_binary_result_peers(IrInstruction *cond_br_inst,
......@@ -3911,7 +3915,7 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode
39113915 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2);
39123916 incoming_blocks[0] = after_null_block;
39133917 incoming_blocks[1] = after_ok_block;
3914 IrInstruction *phi = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values);
3918 IrInstruction *phi = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values, peer_parent);
39153919 return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc);
39163920}
39173921
......@@ -5427,7 +5431,7 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode
54275431 incoming_blocks[0] = after_then_block;
54285432 incoming_blocks[1] = after_else_block;
54295433
5430 IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values);
5434 IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent);
54315435 return ir_expr_wrap(irb, scope, phi, result_loc);
54325436}
54335437
......@@ -5468,9 +5472,10 @@ static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *
54685472 // We needed a pointer to a value, but we got a value. So we create
54695473 // an instruction which just makes a pointer of it.
54705474 return ir_build_ref(irb, scope, value->source_node, value, false, false);
5475 } else {
5476 return ir_expr_wrap(irb, scope, value, result_loc);
54715477 }
54725478
5473 return ir_expr_wrap(irb, scope, value, result_loc);
54745479}
54755480
54765481static PtrLen star_token_to_ptr_len(TokenId token_id) {
......@@ -5931,7 +5936,8 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
59315936 incoming_values.append(void_else_result);
59325937 }
59335938
5934 IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items);
5939 IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length,
5940 incoming_blocks.items, incoming_values.items, peer_parent);
59355941 return ir_expr_wrap(irb, scope, phi, result_loc);
59365942 } else if (var_symbol != nullptr) {
59375943 ir_set_cursor_at_end_and_append_block(irb, cond_block);
......@@ -6022,7 +6028,8 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
60226028 incoming_values.append(void_else_result);
60236029 }
60246030
6025 IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items);
6031 IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length,
6032 incoming_blocks.items, incoming_values.items, peer_parent);
60266033 return ir_expr_wrap(irb, scope, phi, result_loc);
60276034 } else {
60286035 ir_set_cursor_at_end_and_append_block(irb, cond_block);
......@@ -6100,7 +6107,8 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
61006107 incoming_values.append(void_else_result);
61016108 }
61026109
6103 IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items);
6110 IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length,
6111 incoming_blocks.items, incoming_values.items, peer_parent);
61046112 return ir_expr_wrap(irb, scope, phi, result_loc);
61056113 }
61066114}
......@@ -6230,7 +6238,8 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
62306238 incoming_values.append(void_else_value);
62316239 }
62326240
6233 IrInstruction *phi = ir_build_phi(irb, parent_scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items);
6241 IrInstruction *phi = ir_build_phi(irb, parent_scope, node, incoming_blocks.length,
6242 incoming_blocks.items, incoming_values.items, peer_parent);
62346243 return ir_expr_wrap(irb, parent_scope, phi, result_loc);
62356244}
62366245
......@@ -6595,7 +6604,7 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN
65956604 incoming_blocks[0] = after_then_block;
65966605 incoming_blocks[1] = after_else_block;
65976606
6598 IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values);
6607 IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent);
65996608 return ir_expr_wrap(irb, scope, phi, result_loc);
66006609}
66016610
......@@ -6690,7 +6699,7 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *
66906699 incoming_blocks[0] = after_then_block;
66916700 incoming_blocks[1] = after_else_block;
66926701
6693 IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values);
6702 IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent);
66946703 return ir_expr_wrap(irb, scope, phi, result_loc);
66956704}
66966705
......@@ -6985,7 +6994,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
69856994 if (incoming_blocks.length == 0) {
69866995 result_instruction = ir_build_const_void(irb, scope, node);
69876996 } else {
6988 result_instruction = ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items);
6997 result_instruction = ir_build_phi(irb, scope, node, incoming_blocks.length,
6998 incoming_blocks.items, incoming_values.items, peer_parent);
69896999 }
69907000 return ir_expr_wrap(irb, scope, result_instruction, result_loc);
69917001}
......@@ -7273,7 +7283,7 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode
72737283 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2);
72747284 incoming_blocks[0] = after_err_block;
72757285 incoming_blocks[1] = after_ok_block;
7276 IrInstruction *phi = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values);
7286 IrInstruction *phi = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values, peer_parent);
72777287 return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc);
72787288}
72797289
......@@ -7958,7 +7968,8 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod
79587968 incoming_values[0] = const_bool_true;
79597969 incoming_blocks[1] = post_cancel_awaiter_block;
79607970 incoming_values[1] = const_bool_false;
7961 IrInstruction *destroy_ourselves = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values);
7971 IrInstruction *destroy_ourselves = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values,
7972 nullptr);
79627973 ir_gen_defers_for_block(irb, parent_scope, outer_scope, true);
79637974 ir_mark_gen(ir_build_cond_br(irb, parent_scope, node, destroy_ourselves, irb->exec->coro_final_cleanup_block, irb->exec->coro_early_final, const_bool_false));
79647975
......@@ -8080,7 +8091,7 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
80808091 case NodeTypeContinue:
80818092 return ir_lval_wrap(irb, scope, ir_gen_continue(irb, scope, node), lval, result_loc);
80828093 case NodeTypeUnreachable:
8083 return ir_lval_wrap(irb, scope, ir_build_unreachable(irb, scope, node), lval, result_loc);
8094 return ir_build_unreachable(irb, scope, node);
80848095 case NodeTypeDefer:
80858096 return ir_lval_wrap(irb, scope, ir_gen_defer(irb, scope, node), lval, result_loc);
80868097 case NodeTypeSliceExpr:
......@@ -8337,7 +8348,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
83378348 incoming_values[0] = const_bool_false;
83388349 incoming_blocks[1] = irb->exec->coro_normal_final;
83398350 incoming_values[1] = const_bool_true;
8340 IrInstruction *resume_awaiter = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values);
8351 IrInstruction *resume_awaiter = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr);
83418352
83428353 IrBasicBlock **merge_incoming_blocks = allocate<IrBasicBlock *>(2);
83438354 IrInstruction **merge_incoming_values = allocate<IrInstruction *>(2);
......@@ -8345,7 +8356,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
83458356 merge_incoming_values[0] = ir_build_const_undefined(irb, scope, node);
83468357 merge_incoming_blocks[1] = irb->exec->coro_normal_final;
83478358 merge_incoming_values[1] = await_handle_in_block;
8348 IrInstruction *awaiter_handle = ir_build_phi(irb, scope, node, 2, merge_incoming_blocks, merge_incoming_values);
8359 IrInstruction *awaiter_handle = ir_build_phi(irb, scope, node, 2, merge_incoming_blocks, merge_incoming_values, nullptr);
83498360
83508361 Buf *shrink_field_name = buf_create_from_str(ASYNC_SHRINK_FIELD_NAME);
83518362 IrInstruction *implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, scope, node,
......@@ -10737,16 +10748,27 @@ static void ir_start_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrBasicBlock *cons
1073710748static IrInstruction *ira_suspend(IrAnalyze *ira, IrInstruction *old_instruction, IrBasicBlock *next_bb,
1073810749 IrSuspendPosition *suspend_pos)
1073910750{
10751 // reserve block position
10752 if (!ira->new_irb.current_basic_block->already_appended) {
10753 ira->new_irb.current_basic_block->already_appended = true;
10754 ira->new_irb.exec->basic_block_list.append(ira->new_irb.current_basic_block);
10755 }
10756
1074010757 suspend_pos->basic_block_index = ira->old_bb_index;
1074110758 suspend_pos->instruction_index = ira->instruction_index;
1074210759
10743 ira->old_bb_index = next_bb->index;
10744 ira->old_irb.current_basic_block = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index);
10745 assert(ira->old_irb.current_basic_block == next_bb);
10746 ira->instruction_index = 0;
10747 ira->const_predecessor_bb = nullptr;
10748 next_bb->other = ir_get_new_bb_runtime(ira, next_bb, old_instruction);
10749 ira->new_irb.current_basic_block = next_bb->other;
10760 ira->old_irb.current_basic_block->suspended = true;
10761
10762 // null next_bb means that the caller plans to call ira_resume before returning
10763 if (next_bb != nullptr) {
10764 ira->old_bb_index = next_bb->index;
10765 ira->old_irb.current_basic_block = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index);
10766 assert(ira->old_irb.current_basic_block == next_bb);
10767 ira->instruction_index = 0;
10768 ira->const_predecessor_bb = nullptr;
10769 next_bb->other = ir_get_new_bb_runtime(ira, next_bb, old_instruction);
10770 ira->new_irb.current_basic_block = next_bb->other;
10771 }
1075010772 return ira->codegen->unreach_instruction;
1075110773}
1075210774
......@@ -10754,6 +10776,7 @@ static IrInstruction *ira_resume(IrAnalyze *ira) {
1075410776 IrSuspendPosition pos = ira->resume_stack.pop();
1075510777 ira->old_bb_index = pos.basic_block_index;
1075610778 ira->old_irb.current_basic_block = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index);
10779 ira->old_irb.current_basic_block->suspended = false;
1075710780 ira->instruction_index = pos.instruction_index;
1075810781 ira->const_predecessor_bb = nullptr;
1075910782 ira->new_irb.current_basic_block = ira->old_irb.current_basic_block->other;
......@@ -10762,7 +10785,10 @@ static IrInstruction *ira_resume(IrAnalyze *ira) {
1076210785}
1076310786
1076410787static void ir_finish_bb(IrAnalyze *ira) {
10765 ira->new_irb.exec->basic_block_list.append(ira->new_irb.current_basic_block);
10788 if (!ira->new_irb.current_basic_block->already_appended) {
10789 ira->new_irb.current_basic_block->already_appended = true;
10790 ira->new_irb.exec->basic_block_list.append(ira->new_irb.current_basic_block);
10791 }
1076610792 ira->instruction_index += 1;
1076710793 while (ira->instruction_index < ira->old_irb.current_basic_block->instruction_list.length) {
1076810794 IrInstruction *next_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index);
......@@ -10780,11 +10806,18 @@ static void ir_finish_bb(IrAnalyze *ira) {
1078010806 for (;;) {
1078110807 while (ira->old_bb_index < ira->old_irb.exec->basic_block_list.length) {
1078210808 IrBasicBlock *old_bb = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index);
10783 if (old_bb->other == nullptr) {
10809 if (old_bb->other == nullptr && old_bb->suspend_instruction_ref == nullptr) {
1078410810 ira->old_bb_index += 1;
1078510811 continue;
1078610812 }
10787 if (old_bb->other->instruction_list.length != 0 || ira->old_bb_index == my_old_bb_index) {
10813 // If it's the block we just finished, or
10814 // if it's already a finished block, or
10815 // if it's a suspended block,
10816 // then skip it
10817 if (ira->old_bb_index == my_old_bb_index ||
10818 old_bb->suspended ||
10819 (old_bb->other != nullptr && old_bb->other->instruction_list.length != 0))
10820 {
1078810821 ira->old_bb_index += 1;
1078910822 continue;
1079010823 }
......@@ -10796,12 +10829,19 @@ static void ir_finish_bb(IrAnalyze *ira) {
1079610829 return;
1079710830 }
1079810831
10832 if (old_bb->other == nullptr) {
10833 old_bb->other = ir_get_new_bb_runtime(ira, old_bb, old_bb->suspend_instruction_ref);
10834 }
1079910835 ira->new_irb.current_basic_block = old_bb->other;
1080010836 ir_start_bb(ira, old_bb, nullptr);
1080110837 return;
1080210838 }
10803 if (!need_repeat)
10839 if (!need_repeat) {
10840 if (ira->resume_stack.length != 0) {
10841 ira_resume(ira);
10842 }
1080410843 return;
10844 }
1080510845 need_repeat = false;
1080610846 ira->old_bb_index = 0;
1080710847 continue;
......@@ -14775,43 +14815,11 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s
1477514815 return nullptr;
1477614816
1477714817 if (peer_parent->resolved_type == nullptr) {
14778 IrInstruction *suspended_inst = ira_suspend(ira, suspend_source_instr,
14779 result_peer->next_bb, &result_peer->suspend_pos);
14780 bool last_one = result_peer->seen_before ||
14781 result_peer == &peer_parent->peers[peer_parent->peer_count - 1];
14782 result_peer->seen_before = true;
14783 if (!last_one) {
14784 return suspended_inst;
14785 }
14786 IrInstruction **instructions = allocate<IrInstruction *>(peer_parent->peer_count);
14787 for (size_t i = 0; i < peer_parent->peer_count; i += 1) {
14788 ResultLocPeer *this_peer = &peer_parent->peers[i];
14789 ResultLocPeer *opposite_peer = &peer_parent->peers[peer_parent->peer_count - i - 1];
14790
14791 IrInstruction *gen_instruction = this_peer->base.gen_instruction;
14792 if (gen_instruction == nullptr) {
14793 // unreachable instructions will cause implicit_elem_type to be null
14794 if (this_peer->base.implicit_elem_type == nullptr) {
14795 instructions[i] = ir_const_unreachable(ira, this_peer->base.source_instruction);
14796 } else {
14797 instructions[i] = ir_const(ira, this_peer->base.source_instruction,
14798 this_peer->base.implicit_elem_type);
14799 instructions[i]->value.special = ConstValSpecialRuntime;
14800 }
14801 } else {
14802 instructions[i] = gen_instruction;
14803 }
14804 if (opposite_peer->base.implicit_elem_type != nullptr &&
14805 opposite_peer->base.implicit_elem_type->id != ZigTypeIdUnreachable)
14806 {
14807 ira->resume_stack.append(opposite_peer->suspend_pos);
14808 }
14818 ResultLocPeer *last_peer = &peer_parent->peers[peer_parent->peer_count - 1];
14819 if (last_peer->next_bb->suspend_instruction_ref == nullptr) {
14820 last_peer->next_bb->suspend_instruction_ref = suspend_source_instr;
1480914821 }
14810 ZigType *expected_type = ir_result_loc_expected_type(ira, suspend_source_instr, peer_parent->parent);
14811 peer_parent->resolved_type = ir_resolve_peer_types(ira,
14812 peer_parent->base.source_instruction->source_node, expected_type, instructions,
14813 peer_parent->peer_count);
14814 return ira_resume(ira);
14822 return ira_suspend(ira, suspend_source_instr, result_peer->next_bb, &result_peer->suspend_pos);
1481514823 }
1481614824
1481714825 IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent,
......@@ -16159,7 +16167,7 @@ static IrInstruction *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr
1615916167 if (!ir_resolve_comptime(ira, br_instruction->is_comptime->child, &is_comptime))
1616016168 return ir_unreach_error(ira);
1616116169
16162 if (is_comptime || old_dest_block->ref_count == 1)
16170 if (is_comptime || (old_dest_block->ref_count == 1 && old_dest_block->suspend_instruction_ref == nullptr))
1616316171 return ir_inline_bb(ira, &br_instruction->base, old_dest_block);
1616416172
1616516173 IrBasicBlock *new_bb = ir_get_new_bb_runtime(ira, old_dest_block, &br_instruction->base);
......@@ -16254,6 +16262,45 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh
1625416262 zig_unreachable();
1625516263 }
1625616264
16265 ResultLocPeerParent *peer_parent = phi_instruction->peer_parent;
16266 if (peer_parent != nullptr && peer_parent->resolved_type == nullptr) {
16267 // Suspend the phi first so that it gets resumed last
16268 IrSuspendPosition suspend_pos;
16269 ira_suspend(ira, &phi_instruction->base, nullptr, &suspend_pos);
16270 ira->resume_stack.append(suspend_pos);
16271
16272 IrInstruction **instructions = allocate<IrInstruction *>(peer_parent->peer_count);
16273 for (size_t i = 0; i < peer_parent->peer_count; i += 1) {
16274 ResultLocPeer *this_peer = &peer_parent->peers[i];
16275 ResultLocPeer *opposite_peer = &peer_parent->peers[peer_parent->peer_count - i - 1];
16276
16277 IrInstruction *gen_instruction = this_peer->base.gen_instruction;
16278 if (gen_instruction == nullptr) {
16279 // unreachable instructions will cause implicit_elem_type to be null
16280 if (this_peer->base.implicit_elem_type == nullptr) {
16281 instructions[i] = ir_const_unreachable(ira, this_peer->base.source_instruction);
16282 } else {
16283 instructions[i] = ir_const(ira, this_peer->base.source_instruction,
16284 this_peer->base.implicit_elem_type);
16285 instructions[i]->value.special = ConstValSpecialRuntime;
16286 }
16287 } else {
16288 instructions[i] = gen_instruction;
16289 }
16290 if (opposite_peer->base.implicit_elem_type != nullptr &&
16291 opposite_peer->base.implicit_elem_type->id != ZigTypeIdUnreachable)
16292 {
16293 ira->resume_stack.append(opposite_peer->suspend_pos);
16294 }
16295 }
16296 ZigType *expected_type = ir_result_loc_expected_type(ira, &phi_instruction->base, peer_parent->parent);
16297 peer_parent->resolved_type = ir_resolve_peer_types(ira,
16298 peer_parent->base.source_instruction->source_node, expected_type, instructions,
16299 peer_parent->peer_count);
16300
16301 return ira_resume(ira);
16302 }
16303
1625716304 ZigList<IrBasicBlock*> new_incoming_blocks = {0};
1625816305 ZigList<IrInstruction*> new_incoming_values = {0};
1625916306
......@@ -16342,7 +16389,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh
1634216389
1634316390 IrInstruction *result = ir_build_phi(&ira->new_irb,
1634416391 phi_instruction->base.scope, phi_instruction->base.source_node,
16345 new_incoming_blocks.length, new_incoming_blocks.items, new_incoming_values.items);
16392 new_incoming_blocks.length, new_incoming_blocks.items, new_incoming_values.items, nullptr);
1634616393 result->value.type = resolved_type;
1634716394
1634816395 if (all_stack_ptrs) {
......@@ -24019,7 +24066,7 @@ static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstruct
2401924066 if (type_is_invalid(value->value.type))
2402024067 return ira->codegen->invalid_instruction;
2402124068
24022 bool want_resolve_result = instruction->result_loc->written;
24069 bool want_resolve_result;
2402324070 if (instruction->result_loc->written) {
2402424071 if (instruction->result_loc->scope_elide != nullptr && instr_is_comptime(value)) {
2402524072 want_resolve_result = true;