From c17f5de254be9dc3cb911c5b9e573291b1bd6928 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Thu, 1 Jun 2023 10:41:49 +0200 Subject: [PATCH] Fix miscompilation of guard with `or` Closes #7370 --- lib/compiler/src/beam_ssa_bool.erl | 5 ++++- lib/compiler/test/guard_SUITE.erl | 11 +++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/compiler/src/beam_ssa_bool.erl b/lib/compiler/src/beam_ssa_bool.erl index b0d4ab04ffe6..7d267dc072ca 100644 --- a/lib/compiler/src/beam_ssa_bool.erl +++ b/lib/compiler/src/beam_ssa_bool.erl @@ -366,7 +366,10 @@ pre_opt_is([#b_set{op={succeeded,_},dst=Dst,args=Args0}=I0|Is], Sub = Sub0#{Dst=>#b_literal{val=true}}, pre_opt_is(Is, Reached, Sub, Acc); false -> - pre_opt_is(Is, Reached, Sub0, [I|Acc]) + %% Don't remember boolean expressions that can potentially fail, + %% because that can cause unsafe optimizations. + Sub = maps:remove(Arg, Sub0), + pre_opt_is(Is, Reached, Sub, [I|Acc]) end; pre_opt_is([#b_set{dst=Dst,args=Args0}=I0|Is], Reached, Sub0, Acc) -> Args = sub_args(Args0, Sub0), diff --git a/lib/compiler/test/guard_SUITE.erl b/lib/compiler/test/guard_SUITE.erl index 047bebe978b9..88c6e70bd645 100644 --- a/lib/compiler/test/guard_SUITE.erl +++ b/lib/compiler/test/guard_SUITE.erl @@ -2619,6 +2619,7 @@ beam_bool_SUITE(_Config) -> gh_6164(), gh_6184(), gh_7339(), + gh_7370(), ok. before_and_inside_if() -> @@ -3177,6 +3178,16 @@ do_gh_7339(M) when is_number(M) or (not is_map(M#{a => b})) -> do_gh_7339(_) -> b. +gh_7370() -> + b = gh_7370(id(42)), + b = gh_7370(id(42.0)), + ok. + +gh_7370(A) when (not (not is_float(A))) =/= ((ok and ok) or true) -> + a; +gh_7370(_) -> + b. + %%% %%% End of beam_bool_SUITE tests. %%%