From e8f770a925db7ed4319944d738472afbc9c6a608 Mon Sep 17 00:00:00 2001 From: Frej Drejhammar Date: Wed, 24 Jul 2024 14:48:28 +0200 Subject: [PATCH] compiler alias analysis: Fix bug in status of map extracts As the destructive update pass does not have any support for patching literal maps, as it can do for tuples to ensure that the term that will be destructively updated is on the heap, we must conservatively consider anything extracted from a literal map as aliased. This is not a significant limitation as tracking the alias status of individual associations of non-literal maps is currently considered non feasible. --- lib/compiler/src/beam_ssa_alias.erl | 2 ++ .../test/beam_ssa_check_SUITE_data/alias.erl | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/lib/compiler/src/beam_ssa_alias.erl b/lib/compiler/src/beam_ssa_alias.erl index 34353feb6fd5..de53ab24aea2 100644 --- a/lib/compiler/src/beam_ssa_alias.erl +++ b/lib/compiler/src/beam_ssa_alias.erl @@ -918,6 +918,8 @@ aa_derive_from(Dst, [Parent|Parents], State0) -> aa_derive_from(Dst, Parents, aa_derive_from(Dst, Parent, State0)); aa_derive_from(_Dst, [], State0) -> State0; +aa_derive_from(#b_var{}=Dst, #b_literal{val=Val}, State) when is_map(Val) -> + aa_set_aliased(Dst, State); aa_derive_from(#b_var{}, #b_literal{}, State) -> State; aa_derive_from(#b_var{}=Dst, #b_var{}=Parent, State) -> diff --git a/lib/compiler/test/beam_ssa_check_SUITE_data/alias.erl b/lib/compiler/test/beam_ssa_check_SUITE_data/alias.erl index 762fb243b23d..08cdf68a35c5 100644 --- a/lib/compiler/test/beam_ssa_check_SUITE_data/alias.erl +++ b/lib/compiler/test/beam_ssa_check_SUITE_data/alias.erl @@ -60,6 +60,7 @@ not_transformable3/1, not_transformable4/1, not_transformable5/1, + not_transformable6/0, bad_get_status_by_type/0, stacktrace0/0, @@ -607,6 +608,17 @@ not_transformable5b([H|T], Acc) -> not_transformable5b([], Acc) -> Acc. +%% Check that anything extracted from a map is aliased. This is +%% required as otherwise the destructive update pass could try to +%% update a literal. +not_transformable6() -> +%ssa% () when post_ssa_opt -> +%ssa% E = get_map_element(...), +%ssa% _ = bs_create_bin(append, _, E, ...) { aliased => [E], first_fragment_dies => true }. + M = #{a=> <<>>}, + #{a:=X} = M, + <>. + %% Reproducer for a bug in beam_ssa_alias:aa_get_status_by_type/2 %% where it would return the wrong alias/uniqe status for certain %% combinations of returned types.