diff options
author | Björn Gustavsson <[email protected]> | 2016-08-01 17:06:40 +0200 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2016-08-05 10:58:12 +0200 |
commit | 921cf991e09698d63d0f4f9a20bf2cfc23b2e896 (patch) | |
tree | 7513a85a22254cedc97bf95d4fdb64a61166cf53 /lib/compiler/test | |
parent | 6dcf9c56c648bb6fa2f0e27bdf6429eab23fdd8c (diff) | |
download | otp-921cf991e09698d63d0f4f9a20bf2cfc23b2e896.tar.gz otp-921cf991e09698d63d0f4f9a20bf2cfc23b2e896.tar.bz2 otp-921cf991e09698d63d0f4f9a20bf2cfc23b2e896.zip |
beam_block: Fix potentially unsafe optimization in move_allocates/1
beam_block has an optimization that only is safe when it is applied
immediately after code generation. That is pointed out in a comment:
NOTE: Moving allocation instructions is only safe because it is done
immediately after code generation so that we KNOW that if {x,X} is
initialized, all x registers with lower numbers are also initialized.
That assumption may not be true after other optimizations, such as
the beam_utils:live_opt/1 optimization.
The new beam_reorder pass added in OTP 19 runs before beam_block.
Therefore, the optimization is potentially unsafe. The optimization
is also unsafe if compilation is started from assembly code in a
.S file.
Rewrite the optimization to make it safe. See the newly added comment
for details.
ERL-202
Diffstat (limited to 'lib/compiler/test')
-rw-r--r-- | lib/compiler/test/beam_block_SUITE.erl | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/lib/compiler/test/beam_block_SUITE.erl b/lib/compiler/test/beam_block_SUITE.erl index 4bcb252833..9fcb6e497d 100644 --- a/lib/compiler/test/beam_block_SUITE.erl +++ b/lib/compiler/test/beam_block_SUITE.erl @@ -21,7 +21,8 @@ -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,move_opt_across_gc_bif/1]). + get_map_elements/1,otp_7345/1,move_opt_across_gc_bif/1, + erl_202/1]). %% The only test for the following functions is that %% the code compiles and is accepted by beam_validator. @@ -37,7 +38,8 @@ groups() -> [{p,[parallel], [get_map_elements, otp_7345, - move_opt_across_gc_bif + move_opt_across_gc_bif, + erl_202 ]}]. init_per_suite(Config) -> @@ -135,6 +137,27 @@ positive(speaking) -> paris([], P) -> P + 1. + +%% See https://bugs.erlang.org/browse/ERL-202. +%% Test that move_allocates/1 in beam_block doesn't move allocate +%% when it would not be safe. + +-record(erl_202_r1, {y}). +-record(erl_202_r2, {x}). + +erl_202(_Config) -> + Ref = make_ref(), + Ref = erl_202({{1,2},Ref}, 42), + + {Ref} = erl_202({7,8}, #erl_202_r1{y=#erl_202_r2{x=Ref}}), + + ok. + +erl_202({{_, _},X}, _) -> + X; +erl_202({_, _}, #erl_202_r1{y=R2}) -> + {R2#erl_202_r2.x}. + %%% %%% The only test of the following code is that it compiles. %%% |