aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2019-06-14 11:41:53 -0400
committerAndrew Kelley <andrew@ziglang.org>2019-06-14 11:41:53 -0400
commit7c074b85165c6aff6bdaccd0fecea59489a2de58 (patch)
tree753126cea46836fb7af4060e2e92ca6b2471ad85
parent2ba29a1907264d6466f187cd89552a63160d3922 (diff)
downloadzig-7c074b85165c6aff6bdaccd0fecea59489a2de58.tar.gz
zig-7c074b85165c6aff6bdaccd0fecea59489a2de58.zip
fix peer result locs with switch
-rw-r--r--BRANCH_TODO16
-rw-r--r--src/all_types.hpp1
-rw-r--r--src/ir.cpp7
-rw-r--r--test/stage1/behavior.zig8
4 files changed, 23 insertions, 9 deletions
diff --git a/BRANCH_TODO b/BRANCH_TODO
index 42715a12a3..c392e8ae77 100644
--- a/BRANCH_TODO
+++ b/BRANCH_TODO
@@ -1,6 +1,8 @@
Scratch pad for stuff to do before merging master
=================================================
+uncomment all the behavior tests
+
restore test_runner.zig to master branch
- also the default panic function and unexpected_error_tracing. see the commit
that adds this text to BRANCH_TODO file.
@@ -8,11 +10,21 @@ restore test_runner.zig to master branch
get an empty file compiling successfully (with no panic fn override)
-uncomment all the behavior tests
-
better behavior for implicit casts. for example these introduce an extra allocation/memcpy:
var x: [1]i32 = [_]i32{1};
var x = ([1]i32)([_]i32{1});
whereas this one does not:
var x = [_]i32{1};
but all 3 should be semantically identical
+
+
+This example has less than ideal LLVM IR:
+```zig
+export fn entry() void {
+ _ = mul(true, 1) catch undefined;
+}
+pub fn mul(c: bool, answer: i32) error{Overflow}!i32 {
+ return if (c) error.Overflow else answer;
+}
+```
+It creates an unnecessary stack variable.
diff --git a/src/all_types.hpp b/src/all_types.hpp
index 4609d246b6..4f77a75587 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -3662,6 +3662,7 @@ struct ResultLocPeerParent {
bool skipped;
bool done_resuming;
+ IrBasicBlock *end_bb;
ResultLoc *parent;
ResultLocPeer *peers;
size_t peer_count;
diff --git a/src/ir.cpp b/src/ir.cpp
index 5dfd84ff15..3b5673839e 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -3901,6 +3901,7 @@ static ResultLocPeerParent *create_binary_result_peers(IrInstruction *cond_br_in
ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1);
peer_parent->base.id = ResultLocIdPeerParent;
peer_parent->base.source_instruction = cond_br_inst;
+ peer_parent->end_bb = endif_block;
peer_parent->is_comptime = is_comptime;
peer_parent->parent = parent;
peer_parent->peer_count = 2;
@@ -6894,6 +6895,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1);
peer_parent->base.id = ResultLocIdPeerParent;
+ peer_parent->end_bb = end_block;
peer_parent->is_comptime = is_comptime;
peer_parent->parent = result_loc;
peer_parent->peers = allocate<ResultLocPeer>(prong_count);
@@ -14923,9 +14925,8 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
}
if (peer_parent->resolved_type == nullptr) {
- ResultLocPeer *last_peer = &peer_parent->peers[peer_parent->peer_count - 1];
- if (last_peer->next_bb->suspend_instruction_ref == nullptr) {
- last_peer->next_bb->suspend_instruction_ref = suspend_source_instr;
+ if (peer_parent->end_bb->suspend_instruction_ref == nullptr) {
+ peer_parent->end_bb->suspend_instruction_ref = suspend_source_instr;
}
return ira_suspend(ira, suspend_source_instr, result_peer->next_bb, &result_peer->suspend_pos);
}
diff --git a/test/stage1/behavior.zig b/test/stage1/behavior.zig
index 56862e07a7..1dd090cbc3 100644
--- a/test/stage1/behavior.zig
+++ b/test/stage1/behavior.zig
@@ -31,7 +31,7 @@ comptime {
_ = @import("behavior/bugs/421.zig");
_ = @import("behavior/bugs/529.zig");
_ = @import("behavior/bugs/655.zig");
- //_ = @import("behavior/bugs/656.zig");
+ _ = @import("behavior/bugs/656.zig");
_ = @import("behavior/bugs/679.zig");
_ = @import("behavior/bugs/704.zig");
_ = @import("behavior/bugs/718.zig");
@@ -71,7 +71,7 @@ comptime {
_ = @import("behavior/popcount.zig");
//_ = @import("behavior/ptrcast.zig");
_ = @import("behavior/pub_enum.zig");
- //_ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig");
+ _ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig");
_ = @import("behavior/reflection.zig");
_ = @import("behavior/sizeof_and_typeof.zig");
//_ = @import("behavior/slice.zig");
@@ -81,7 +81,7 @@ comptime {
_ = @import("behavior/struct_contains_slice_of_itself.zig");
//_ = @import("behavior/switch.zig");
//_ = @import("behavior/switch_prong_err_enum.zig");
- //_ = @import("behavior/switch_prong_implicit_cast.zig");
+ _ = @import("behavior/switch_prong_implicit_cast.zig");
_ = @import("behavior/syntax.zig");
_ = @import("behavior/this.zig");
_ = @import("behavior/truncate.zig");
@@ -90,7 +90,7 @@ comptime {
//_ = @import("behavior/typename.zig");
_ = @import("behavior/undefined.zig");
_ = @import("behavior/underscore.zig");
- //_ = @import("behavior/union.zig");
+ _ = @import("behavior/union.zig");
_ = @import("behavior/var_args.zig");
_ = @import("behavior/vector.zig");
_ = @import("behavior/void.zig");