File 1312-beam_ssa_bool-Fix-miscompilation.patch of Package erlang
From 42e6979a68a1b15869dcfb99dbac127c108616df Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Mon, 31 Jul 2023 10:38:39 +0200
Subject: [PATCH] beam_ssa_bool: Fix miscompilation
Fixes #7517
---
lib/compiler/src/beam_ssa_bool.erl | 32 +++++++++++++++++++++---------
lib/compiler/test/guard_SUITE.erl | 12 +++++++++++
2 files changed, 35 insertions(+), 9 deletions(-)
diff --git a/lib/compiler/src/beam_ssa_bool.erl b/lib/compiler/src/beam_ssa_bool.erl
index 7bc6751396..5a621080fa 100644
--- a/lib/compiler/src/beam_ssa_bool.erl
+++ b/lib/compiler/src/beam_ssa_bool.erl
@@ -1040,15 +1040,11 @@ ensure_no_failing_instructions(First, Second, G, St) ->
can_fail({succeeded,_}, V, G) -> not eaten_by_phi(V, G);
can_fail(put_map, _, _) -> true;
-can_fail(_, _, _) -> false.
-
-eaten_by_phi(V, G) ->
- {br,_,Fail} = get_targets(V, G),
- case beam_digraph:vertex(G, Fail) of
- br ->
- [To] = beam_digraph:out_neighbours(G, Fail),
- case beam_digraph:vertex(G, To) of
- #b_set{op=phi} ->
+can_fail(_, V, G) ->
+ case get_targets(V, G) of
+ {br,_Succ,Fail} ->
+ case follow_branch(G, Fail) of
+ {external,_} ->
true;
_ ->
false
@@ -1057,6 +1053,24 @@ eaten_by_phi(V, G) ->
false
end.
+eaten_by_phi(V, G) ->
+ {br,_,Fail} = get_targets(V, G),
+ case follow_branch(G, Fail) of
+ #b_set{op=phi} ->
+ true;
+ _ ->
+ false
+ end.
+
+follow_branch(G, Br) ->
+ case beam_digraph:vertex(G, Br) of
+ br ->
+ [To] = beam_digraph:out_neighbours(G, Br),
+ beam_digraph:vertex(G, To);
+ _ ->
+ none
+ end.
+
%% order_args([Arg1,Arg2], G, St) -> {First,Second}.
%% Order arguments for a boolean operator so that there is path in the
%% digraph from the instruction referered to by the first operand to
diff --git a/lib/compiler/test/guard_SUITE.erl b/lib/compiler/test/guard_SUITE.erl
index 7a8b72135d..0b2c209b68 100644
--- a/lib/compiler/test/guard_SUITE.erl
+++ b/lib/compiler/test/guard_SUITE.erl
@@ -2621,6 +2621,7 @@ beam_bool_SUITE(_Config) ->
gh_7252(),
gh_7339(),
gh_7370(),
+ gh_7517(),
ok.
before_and_inside_if() ->
@@ -3216,6 +3217,17 @@ gh_7370(A) when (not (not is_float(A))) =/= ((ok and ok) or true) ->
gh_7370(_) ->
b.
+gh_7517() ->
+ ok = catch do_gh_7517([]),
+ ok = catch do_gh_7517([a,b,c]),
+ {'EXIT',{function_clause,_}} = catch do_gh_7517(ok),
+ {'EXIT',{function_clause,_}} = catch do_gh_7517(<<>>),
+ ok.
+
+do_gh_7517(A) when (ok /= A) or is_float(is_list(A) orelse ok andalso ok) ->
+ ok.
+
+
%%%
%%% End of beam_bool_SUITE tests.
%%%
--
2.35.3