aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2018-11-02 10:16:59 +0100
committerBjörn Gustavsson <[email protected]>2018-11-02 10:16:59 +0100
commitad8ef2bda1fa8cc337e581dca0c67cfc756f5e4f (patch)
tree634f5c219153593919a3ffe7d3f1c4caa502d4d4 /lib/compiler
parent9c33f00f78724ce0f68fef1dfc6ab4810d8c45f1 (diff)
parent3e742b1d270069ede1aa8b6ae69c83fc6e71f814 (diff)
downloadotp-ad8ef2bda1fa8cc337e581dca0c67cfc756f5e4f.tar.gz
otp-ad8ef2bda1fa8cc337e581dca0c67cfc756f5e4f.tar.bz2
otp-ad8ef2bda1fa8cc337e581dca0c67cfc756f5e4f.zip
Merge branch 'maint'
* maint: Fix bug when beam_jump removes put_tuple instructions Conflicts: lib/compiler/src/beam_jump.erl lib/compiler/test/beam_jump_SUITE.erl
Diffstat (limited to 'lib/compiler')
-rw-r--r--lib/compiler/src/beam_jump.erl15
-rw-r--r--lib/compiler/test/beam_jump_SUITE.erl18
2 files changed, 26 insertions, 7 deletions
diff --git a/lib/compiler/src/beam_jump.erl b/lib/compiler/src/beam_jump.erl
index d694bd2a5b..edc4522cc7 100644
--- a/lib/compiler/src/beam_jump.erl
+++ b/lib/compiler/src/beam_jump.erl
@@ -128,7 +128,7 @@
%%% on the program state.
%%%
--import(lists, [foldl/3,mapfoldl/3,reverse/1,reverse/2]).
+-import(lists, [dropwhile/2,foldl/3,mapfoldl/3,reverse/1,reverse/2]).
-type instruction() :: beam_utils:instruction().
@@ -522,14 +522,19 @@ opt_useless_loads([{test,_,{f,L},_}=I|Is], L, St) ->
opt_useless_loads(Is, _L, St) ->
{Is,St}.
-opt_useless_block_loads([{set,[Dst],_,_}=I|Is], L, Index) ->
- BlockJump = [{block,Is},{jump,{f,L}}],
+opt_useless_block_loads([{set,[Dst],_,_}=I|Is0], L, Index) ->
+ BlockJump = [{block,Is0},{jump,{f,L}}],
case beam_utils:is_killed(Dst, BlockJump, Index) of
true ->
- %% The register is killed and not used, we can remove the load
+ %% The register is killed and not used, we can remove the load.
+ %% Remove any `put` instructions in case we just
+ %% removed a `put_tuple` instruction.
+ Is = dropwhile(fun({set,_,_,put}) -> true;
+ (_) -> false
+ end, Is0),
opt_useless_block_loads(Is, L, Index);
false ->
- [I|opt_useless_block_loads(Is, L, Index)]
+ [I|opt_useless_block_loads(Is0, L, Index)]
end;
opt_useless_block_loads([I|Is], L, Index) ->
[I|opt_useless_block_loads(Is, L, Index)];
diff --git a/lib/compiler/test/beam_jump_SUITE.erl b/lib/compiler/test/beam_jump_SUITE.erl
index f6cddbf1b1..40eb6f06c3 100644
--- a/lib/compiler/test/beam_jump_SUITE.erl
+++ b/lib/compiler/test/beam_jump_SUITE.erl
@@ -22,7 +22,7 @@
-export([all/0,suite/0,groups/0,init_per_suite/1,end_per_suite/1,
init_per_group/2,end_per_group/2,
undefined_label/1,ambiguous_catch_try_state/1,
- unsafe_move_elimination/1]).
+ unsafe_move_elimination/1,build_tuple/1]).
suite() ->
[{ct_hooks,[ts_install_cth]}].
@@ -34,7 +34,8 @@ groups() ->
[{p,[parallel],
[undefined_label,
ambiguous_catch_try_state,
- unsafe_move_elimination
+ unsafe_move_elimination,
+ build_tuple
]}].
init_per_suite(Config) ->
@@ -112,6 +113,19 @@ unsafe_move_elimination(Left, Right, Simple0) ->
end,
{id({Left,Right,Simple}),Simple}.
+-record(message2, {id, p1}).
+-record(message3, {id, p1, p2}).
+
+build_tuple(_Config) ->
+ {'EXIT',{{badrecord,message3},_}} = (catch do_build_tuple(#message2{})),
+ ok.
+
+do_build_tuple(Message) ->
+ if is_record(Message, message2) ->
+ Res = {res, rand:uniform(100)},
+ {Message#message3.id, Res}
+ end.
+
id(I) ->
I.