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

openSUSE Build Service is sponsored by