File 3852-compiler-Fix-optimization-for-binary_to_atom-and-tes.patch of Package erlang
From 7e2e56dd1e1fa73eba7db7ef13af9a89f724103c Mon Sep 17 00:00:00 2001
From: lucioleKi <isabell@erlang.org>
Date: Wed, 27 Nov 2024 14:59:35 +0100
Subject: [PATCH] compiler: Fix optimization for binary_to_atom and tests
This is a fix for [PR-9042](https://github.com/erlang/otp/pull/9042).
`binary_to_atom/1` and `binary_to_existing_atom/1` now use the correct
optimization. Tests for SSA in `non_throwing_bifs.erl` are fixed and
added to the correct suite.
---
lib/compiler/src/beam_ssa.erl | 2 +
lib/compiler/test/beam_ssa_check_SUITE.erl | 9 ++-
.../non_throwing_bifs.erl | 23 ++++--
lib/compiler/test/bif_SUITE.erl | 75 +++++++++++++++----
4 files changed, 84 insertions(+), 25 deletions(-)
diff --git a/lib/compiler/src/beam_ssa.erl b/lib/compiler/src/beam_ssa.erl
index 1773ada4b4..9c84d96363 100644
--- a/lib/compiler/src/beam_ssa.erl
+++ b/lib/compiler/src/beam_ssa.erl
@@ -239,7 +239,9 @@ no_side_effect(#b_set{op=Op}) ->
can_be_guard_bif(M, F, A) ->
case {M,F,A} of
+ {erlang, binary_to_atom, 1} -> true;
{erlang, binary_to_atom, 2} -> true;
+ {erlang, binary_to_existing_atom, 1} -> true;
{erlang, binary_to_existing_atom, 2} -> true;
{erlang, list_to_atom, 1} -> true;
{erlang, list_to_existing_atom, 1} -> true;
diff --git a/lib/compiler/test/beam_ssa_check_SUITE.erl b/lib/compiler/test/beam_ssa_check_SUITE.erl
index b1ddcb9349..eb5a834864 100644
--- a/lib/compiler/test/beam_ssa_check_SUITE.erl
+++ b/lib/compiler/test/beam_ssa_check_SUITE.erl
@@ -34,7 +34,8 @@
bs_size_unit_checks/1,
private_append_checks/1,
ret_annotation_checks/1,
- sanity_checks/1]).
+ sanity_checks/1,
+ non_throwing_bifs/1]).
suite() -> [{ct_hooks,[ts_install_cth]}].
@@ -48,7 +49,8 @@ groups() ->
appendable_checks,
private_append_checks,
ret_annotation_checks,
- sanity_checks]},
+ sanity_checks,
+ non_throwing_bifs]},
{post_ssa_opt_dynamic,test_lib:parallel(),
[bs_size_unit_checks]}].
@@ -125,6 +127,9 @@ ret_annotation_checks(Config) when is_list(Config) ->
sanity_checks(Config) when is_list(Config) ->
run_post_ssa_opt(sanity_checks, Config).
+non_throwing_bifs(Config) when is_list(Config) ->
+ run_post_ssa_opt(non_throwing_bifs, Config).
+
dynamic_workdir(Config) ->
PrivDir = proplists:get_value(priv_dir, Config),
filename:join(PrivDir, "dynamic").
diff --git a/lib/compiler/test/beam_ssa_check_SUITE_data/non_throwing_bifs.erl b/lib/compiler/test/beam_ssa_check_SUITE_data/non_throwing_bifs.erl
index 571a7b1972..bb7d2a4893 100644
--- a/lib/compiler/test/beam_ssa_check_SUITE_data/non_throwing_bifs.erl
+++ b/lib/compiler/test/beam_ssa_check_SUITE_data/non_throwing_bifs.erl
@@ -24,25 +24,32 @@
-export([try_bif1/1, try_bif2/2, try_bif3/1]).
try_bif1(B) ->
-%ssa% () when post_ssa_opt ->
-%ssa% X = bif:binary_to_atom(B),
-%ssa% _ = succeeded:guard(X).
+%ssa% (B) when post_ssa_opt ->
+%ssa% X = bif:binary_to_atom(B, utf8),
+%ssa% Y = succeeded:guard(X),
+%ssa% ret(X).
try binary_to_atom(B)
catch _:_ -> []
end.
try_bif2(A, B) ->
-%ssa% () when post_ssa_opt ->
+%ssa% (A, B) when post_ssa_opt ->
%ssa% X = bif:binary_to_atom(A, B),
-%ssa% _ = succeeded:guard(X).
+%ssa% Y = succeeded:guard(X),
+%ssa% ret(X).
try binary_to_atom(A, B)
catch _:_ -> []
end.
try_bif3(A) ->
-%ssa% () when post_ssa_opt ->
-%ssa% X = erlang:float_to_list(A),
-%ssa% _ = succeeded:body(X).
+%ssa% (A) when post_ssa_opt ->
+%ssa% X = call(fun erlang:float_to_list/1, A),
+%ssa% Y = succeeded:body(X),
+%ssa% br(Y, Succ, Fail),
+%ssa% label Succ,
+%ssa% ret(X),
+%ssa% label Fail,
+%ssa% ret([]).
try float_to_list(A)
catch _:_ -> []
end.
diff --git a/lib/compiler/test/bif_SUITE.erl b/lib/compiler/test/bif_SUITE.erl
index 24cc12d7cf..86758ebbbf 100644
--- a/lib/compiler/test/bif_SUITE.erl
+++ b/lib/compiler/test/bif_SUITE.erl
@@ -295,23 +295,68 @@ num_clamped_add(A) ->
min(max(A, 0), 10) + 100.
non_throwing(_Config) ->
- a = try binary_to_atom(<<"a">>)
- catch _:_ -> []
- end,
- l = try list_to_existing_atom([108])
- catch _:_ -> []
- end,
- [] = try list_to_existing_atom([a])
- catch _:_ -> []
- end,
- 'Erlang' = try binary_to_atom(<<"Erlang">>, unicode)
- catch _:_ -> []
- end,
- [] = try binary_to_existing_atom(a, unicode)
- catch _:_ -> []
- end,
+ abc = thing_to_atom(~"abc"),
+ [] = thing_to_atom(a),
+ [] = thing_to_atom(42),
+ [] = thing_to_atom([a,b,c]),
+ erlang = thing_to_existing_atom(~"erlang"),
+ [] = thing_to_existing_atom(~"not an existing atom"),
+ [] = thing_to_existing_atom(a),
ok.
+thing_to_atom(Bin0) ->
+ Bin = id(Bin0),
+ Res = try
+ binary_to_atom(Bin)
+ catch
+ _:_ ->
+ []
+ end,
+ Res = try
+ binary_to_atom(Bin, utf8)
+ catch
+ _:_ ->
+ []
+ end,
+ if
+ is_atom(Res) ->
+ List = unicode:characters_to_list(Bin),
+ Res = try
+ list_to_atom(List)
+ catch
+ _:_ ->
+ []
+ end;
+ true ->
+ Res
+ end.
+thing_to_existing_atom(Bin0) ->
+ Bin = id(Bin0),
+ Res = try
+ binary_to_existing_atom(Bin)
+ catch
+ _:_ ->
+ []
+ end,
+ Res = try
+ binary_to_existing_atom(Bin, utf8)
+ catch
+ _:_ ->
+ []
+ end,
+ if
+ is_atom(Res) ->
+ List = unicode:characters_to_list(Bin),
+ Res = try
+ list_to_existing_atom(List)
+ catch
+ _:_ ->
+ []
+ end;
+ true ->
+ Res
+ end.
+
%%%
%%% Common utilities.
%%%
--
2.43.0