File 0370-beam_ssa_opt-Intersect-CSE-candidates-on-failure-pat.patch of Package erlang
From 519b1e601f1172d6a8d29b4e1ce26f4d26fe44bb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20H=C3=B6gberg?= <john@erlang.org>
Date: Fri, 20 Sep 2024 16:36:58 +0200
Subject: [PATCH] beam_ssa_opt: Intersect CSE candidates on failure path
---
lib/compiler/src/beam_ssa_opt.erl | 18 +++++++++---------
lib/compiler/test/beam_ssa_SUITE.erl | 22 ++++++++++++++++++++++
2 files changed, 31 insertions(+), 9 deletions(-)
diff --git a/lib/compiler/src/beam_ssa_opt.erl b/lib/compiler/src/beam_ssa_opt.erl
index fca1e08877..a6dfc0ddb3 100644
--- a/lib/compiler/src/beam_ssa_opt.erl
+++ b/lib/compiler/src/beam_ssa_opt.erl
@@ -1089,18 +1089,18 @@ cse_successors_1([L|Ls], Es0, M) ->
end;
cse_successors_1([], _, M) -> M.
-cse_successor_fail(Fail, Src, Es0, M) ->
+cse_successor_fail(Fail, Src, LHS0, M) ->
case M of
- #{Fail := Es1} when map_size(Es1) =:= 0 ->
+ #{Fail := RHS} when map_size(RHS) =:= 0 ->
M;
- #{Fail := Es1} ->
- Es = #{Var => Val || Var := Val <- Es0,
- is_map_key(Var, Es1),
- Val =/= Src},
- M#{Fail := Es};
+ #{Fail := RHS} ->
+ LHS = #{Var => Val || Var := Val <- LHS0,
+ is_map_key(Var, RHS),
+ Val =/= Src},
+ M#{Fail := cse_intersection(LHS, RHS)};
#{} ->
- Es = #{Var => Val || Var := Val <- Es0, Val =/= Src},
- M#{Fail => Es}
+ LHS = #{Var => Val || Var := Val <- LHS0, Val =/= Src},
+ M#{Fail => LHS}
end.
%% Calculate the intersection of the two maps. Both keys and values
diff --git a/lib/compiler/test/beam_ssa_SUITE.erl b/lib/compiler/test/beam_ssa_SUITE.erl
index 49a15b4be7..e28868f64b 100644
--- a/lib/compiler/test/beam_ssa_SUITE.erl
+++ b/lib/compiler/test/beam_ssa_SUITE.erl
@@ -942,6 +942,8 @@ grab_bag(_Config) ->
{reply,{ok,foo_bar},#{page_title := foo_bar}} =
grab_bag_23(id(#{page_title => unset})),
+ ok = grab_bag_24(),
+
ok.
grab_bag_1() ->
@@ -1243,6 +1245,26 @@ grab_bag_23(#{page_title := unset} = State1) ->
end},
State2}.
+
+-record(test, {a,b,c}).
+-record(test_a, {a}).
+
+%% GH-8818: The CSE pass in beam_ssa_opt failed to intersect candidates on
+%% the failure path, crashing the type optimization pass.
+grab_bag_24() ->
+ {'EXIT', _} = catch do_grab_bag_24(id(0), id(0), id(0), id(0)),
+ ok.
+
+do_grab_bag_24(A, B, C, D) ->
+ A#test.a,
+ {E, F} = ext:ernal(D#test_a.a),
+ if
+ D#test_a.a == 0 andalso (B < E * A#test.a) orelse (B > F * A#test.a) ->
+ false;
+ (C =:= A#test.b) orelse (C =:= A#test.a) ->
+ true
+ end.
+
redundant_br(_Config) ->
{false,{x,y,z}} = redundant_br_1(id({x,y,z})),
{true,[[a,b,c]]} = redundant_br_1(id([[[a,b,c]]])),
--
2.43.0