mirror of
https://github.com/ziglang/zig.git
synced 2025-12-30 18:13:19 +00:00
fix nested peer result locs with no memory loc
```zig
export fn entry2(c: bool) i32 {
return if (c)
i32(0)
else if (c)
i32(1)
else
i32(2);
}
```
```llvm
define i32 @entry2(i1) #2 !dbg !35 {
Entry:
%c = alloca i1, align 1
store i1 %0, i1* %c, align 1
call void @llvm.dbg.declare(metadata i1* %c, metadata !41, metadata !DIExpression()), !dbg !42
%1 = load i1, i1* %c, align 1, !dbg !43
br i1 %1, label %Then, label %Else, !dbg !43
Then: ; preds = %Entry
br label %EndIf3, !dbg !45
Else: ; preds = %Entry
%2 = load i1, i1* %c, align 1, !dbg !46
br i1 %2, label %Then1, label %Else2, !dbg !46
Then1: ; preds = %Else
br label %EndIf, !dbg !47
Else2: ; preds = %Else
br label %EndIf, !dbg !47
EndIf: ; preds = %Else2, %Then1
%3 = phi i32 [ 1, %Then1 ], [ 2, %Else2 ], !dbg !47
br label %EndIf3, !dbg !45
EndIf3: ; preds = %EndIf, %Then
%4 = phi i32 [ 0, %Then ], [ %3, %EndIf ], !dbg !45
ret i32 %4, !dbg !48
}
```
This commit is contained in:
parent
1526d89711
commit
e6fa2ee706
@ -3652,6 +3652,7 @@ struct ResultLocReturn {
|
||||
struct ResultLocPeerParent {
|
||||
ResultLoc base;
|
||||
|
||||
bool skipped;
|
||||
ResultLoc *parent;
|
||||
ResultLocPeer *peers;
|
||||
size_t peer_count;
|
||||
|
||||
27
src/ir.cpp
27
src/ir.cpp
@ -14899,7 +14899,10 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s
|
||||
bool is_comptime;
|
||||
if (!ir_resolve_comptime(ira, peer_parent->is_comptime->child, &is_comptime))
|
||||
return ira->codegen->invalid_instruction;
|
||||
if (is_comptime) return nullptr;
|
||||
peer_parent->skipped = is_comptime;
|
||||
if (peer_parent->skipped) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (peer_parent->resolved_type == nullptr) {
|
||||
ResultLocPeer *last_peer = &peer_parent->peers[peer_parent->peer_count - 1];
|
||||
@ -14916,6 +14919,7 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s
|
||||
{
|
||||
return parent_result_loc;
|
||||
}
|
||||
result_loc->written = true;
|
||||
result_loc->resolved_loc = parent_result_loc;
|
||||
return result_loc->resolved_loc;
|
||||
}
|
||||
@ -16385,16 +16389,15 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh
|
||||
}
|
||||
|
||||
ResultLocPeerParent *peer_parent = phi_instruction->peer_parent;
|
||||
if (peer_parent != nullptr && peer_parent->resolved_type == nullptr) {
|
||||
bool is_comptime;
|
||||
if (!ir_resolve_comptime(ira, peer_parent->is_comptime->child, &is_comptime))
|
||||
return ira->codegen->invalid_instruction;
|
||||
if (is_comptime) goto skip_peer_stuff;
|
||||
|
||||
if (peer_parent != nullptr && peer_parent->resolved_type == nullptr && !peer_parent->skipped) {
|
||||
// Suspend the phi first so that it gets resumed last
|
||||
IrSuspendPosition suspend_pos;
|
||||
ira_suspend(ira, &phi_instruction->base, nullptr, &suspend_pos);
|
||||
ira->resume_stack.append(suspend_pos);
|
||||
ira->resume_stack.add_one();
|
||||
for (size_t i = ira->resume_stack.length;;) {
|
||||
if (i <= 1) break;
|
||||
i -= 1;
|
||||
ira->resume_stack.items[i] = ira->resume_stack.items[i-1];
|
||||
}
|
||||
ira_suspend(ira, &phi_instruction->base, nullptr, &ira->resume_stack.items[0]);
|
||||
|
||||
IrInstruction **instructions = allocate<IrInstruction *>(peer_parent->peer_count);
|
||||
for (size_t i = 0; i < peer_parent->peer_count; i += 1) {
|
||||
@ -16427,7 +16430,6 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh
|
||||
|
||||
return ira_resume(ira);
|
||||
}
|
||||
skip_peer_stuff:
|
||||
|
||||
ZigList<IrBasicBlock*> new_incoming_blocks = {0};
|
||||
ZigList<IrInstruction*> new_incoming_values = {0};
|
||||
@ -24598,6 +24600,9 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ira->codegen->verbose_ir) {
|
||||
fprintf(stderr, "analyze #%zu\n", old_instruction->debug_id);
|
||||
}
|
||||
IrInstruction *new_instruction = ir_analyze_instruction_base(ira, old_instruction);
|
||||
if (new_instruction != nullptr) {
|
||||
ir_assert(new_instruction->value.type != nullptr || new_instruction->value.type != nullptr, old_instruction);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user