diff options
author | Björn Gustavsson <[email protected]> | 2016-05-31 22:49:42 +0200 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2016-06-01 10:09:20 +0200 |
commit | aab1db16d0a732823fa9e2964c6a52b109c61742 (patch) | |
tree | 3ba6111af79e023fc1476dc815a14f9f95faa69a /lib/compiler/test/beam_block_SUITE.erl | |
parent | ac927e00f82b3df962abe082393f45197de49156 (diff) | |
download | otp-aab1db16d0a732823fa9e2964c6a52b109c61742.tar.gz otp-aab1db16d0a732823fa9e2964c6a52b109c61742.tar.bz2 otp-aab1db16d0a732823fa9e2964c6a52b109c61742.zip |
beam_block: Eliminate crash in beam_utils
Somewhat simplified, beam_block would rewrite the target for
the first instruction in this code sequence:
move x(0) => y(1)
gc_bif '+' 1 x(0) => y(0)
move y(1) => x(1)
move nil => x(0)
call 2 local_function/2
The resulting code would be:
move x(0) => x(1) %% Changed target.
gc_bif '+' 1 x(0) => y(0)
move x(1) => y(1) %% Operands swapped (see 02d6135813).
move nil => x(0)
call 2 local_function/2
The resulting code is not safe because the x(1) will be killed
by the gc_bif instruction.
7a47b20c3a cleaned up move optimizations and would reject the
optimization if the target was an X register and an allocating
instruction was found. To avoid this bug, the optimization must be
rejected even if the target is a Y register.
Diffstat (limited to 'lib/compiler/test/beam_block_SUITE.erl')
-rw-r--r-- | lib/compiler/test/beam_block_SUITE.erl | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/lib/compiler/test/beam_block_SUITE.erl b/lib/compiler/test/beam_block_SUITE.erl index d343e26737..4bcb252833 100644 --- a/lib/compiler/test/beam_block_SUITE.erl +++ b/lib/compiler/test/beam_block_SUITE.erl @@ -21,7 +21,7 @@ -export([all/0,suite/0,groups/0,init_per_suite/1,end_per_suite/1, init_per_group/2,end_per_group/2, - get_map_elements/1,otp_7345/1]). + get_map_elements/1,otp_7345/1,move_opt_across_gc_bif/1]). %% The only test for the following functions is that %% the code compiles and is accepted by beam_validator. @@ -36,7 +36,8 @@ all() -> groups() -> [{p,[parallel], [get_map_elements, - otp_7345 + otp_7345, + move_opt_across_gc_bif ]}]. init_per_suite(Config) -> @@ -118,6 +119,22 @@ otp_7345(ObjRef, _RdEnv, Args) -> 10}, id(LlUnitdataReq). + +%% Doing move optimizations across GC bifs are in general not safe. +move_opt_across_gc_bif(_Config) -> + [0,true,1] = positive(speaking), + ok. + +positive(speaking) -> + try + Positive = 0, + [+Positive, case Positive of _ -> true end, paris([], Positive)] + after + mailing + end. + +paris([], P) -> P + 1. + %%% %%% The only test of the following code is that it compiles. %%% |