From 94cf118367b2cd6b64d9fed40d12075027f0e58b Mon Sep 17 00:00:00 2001 From: Frej Drejhammar Date: Fri, 2 Aug 2024 11:11:22 +0200 Subject: [PATCH] fixup: compiler alias analysis: Avoid variable creation for plain values Extracting from a plain value is not possible, but the alias analysis pass can sometimes encounter it when no type information is available. Don't crash when trying to add an edge when trying to add an edge recording the extraction when the source doesn't exist. Instead conservatively set the result to aliased and leave the source unchanged. --- lib/compiler/src/beam_ssa_ss.erl | 10 +++- lib/compiler/test/beam_ssa_check_SUITE.erl | 5 ++ .../no_type_info.erl | 48 +++++++++++++++++++ 3 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 lib/compiler/test/beam_ssa_check_SUITE_data/no_type_info.erl diff --git a/lib/compiler/src/beam_ssa_ss.erl b/lib/compiler/src/beam_ssa_ss.erl index 2c628d4d87a8..bf5fd649e040 100644 --- a/lib/compiler/src/beam_ssa_ss.erl +++ b/lib/compiler/src/beam_ssa_ss.erl @@ -213,7 +213,7 @@ add_embedding(Dst, Src, Element, State0) -> extract(Dst, Src, Element, State) -> ?DP("Extracting ~p[~p] into ~p~n", [Src,Element,Dst]), ?assert_state(State), - case beam_digraph:vertex(State, Src, unique) of + case beam_digraph:vertex(State, Src, plain) of aliased -> %% The pair/tuple is aliased, so what is extracted will be aliased. ?assert_state(set_status(Dst, aliased, State)); @@ -226,7 +226,13 @@ extract(Dst, Src, Element, State) -> [Dst, Src, Element, OutEdges]), extract_element(Dst, Src, Element, OutEdges, State); no_info -> - ?assert_state(set_status(Dst, no_info, State)) + ?assert_state(set_status(Dst, no_info, State)); + plain -> + %% Extracting from a plain value is not possible, but the + %% alias analysis pass can sometimes encounter it when no + %% type information is available. Conservatively set the + %% result to aliased. + ?assert_state(set_status(Dst, aliased, State)) end. %% Note that extract_element/5 will never be given an out edge with a diff --git a/lib/compiler/test/beam_ssa_check_SUITE.erl b/lib/compiler/test/beam_ssa_check_SUITE.erl index 013aacad7487..9f7ec88c7bae 100644 --- a/lib/compiler/test/beam_ssa_check_SUITE.erl +++ b/lib/compiler/test/beam_ssa_check_SUITE.erl @@ -32,6 +32,7 @@ annotation_checks/1, appendable_checks/1, bs_size_unit_checks/1, + no_type_info_checks/1, private_append_checks/1, ret_annotation_checks/1, sanity_checks/1, @@ -47,6 +48,7 @@ groups() -> [alias_checks, annotation_checks, appendable_checks, + no_type_info_checks, private_append_checks, ret_annotation_checks, sanity_checks, @@ -99,6 +101,9 @@ appendable_checks(Config) when is_list(Config) -> bs_size_unit_checks(Config) when is_list(Config) -> gen_and_run_post_ssa_opt(bs_size_unit_checks, Config). +no_type_info_checks(Config) when is_list(Config) -> + run_post_ssa_opt(no_type_info, Config). + private_append_checks(Config) when is_list(Config) -> run_post_ssa_opt(private_append, Config). diff --git a/lib/compiler/test/beam_ssa_check_SUITE_data/no_type_info.erl b/lib/compiler/test/beam_ssa_check_SUITE_data/no_type_info.erl new file mode 100644 index 000000000000..00a87fcb6618 --- /dev/null +++ b/lib/compiler/test/beam_ssa_check_SUITE_data/no_type_info.erl @@ -0,0 +1,48 @@ +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2024. All Rights Reserved. +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%% +%% %CopyrightEnd% +%% +%% This module tests functions which have previously crashed the +%% compiler when the `no_type_opt` option was used. +%% + +-module(no_type_info). +-export([bug/0]). + +-compile(no_type_opt). + +bug() -> + begin + + <<42 || + $s <- + try + something + catch + error:false -> + [] + end + >> + end:(hd(not girl))( + try home of + _ when 34 -> + 8 + catch + _:_ -> + whatever + after + ok + end).