File 0438-Correct-bug-in-CSE-optimization.patch of Package erlang
From a874fbc4893cd253e708cfc06b71f04a5c38e4eb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Sun, 31 Jul 2022 13:49:47 +0200
Subject: [PATCH] Correct bug in CSE optimization
The expression:
#{assoc := V} = #{key => self()}, V.
is supposed to raise a `badmatch` exception, but because of an
overeager common subexpression elimination optimization, it
returned `#{}`.
---
lib/compiler/src/beam_ssa_opt.erl | 2 +-
lib/compiler/test/map_SUITE.erl | 33 +++++++++++++++++++++++++++++--
2 files changed, 32 insertions(+), 3 deletions(-)
diff --git a/lib/compiler/src/beam_ssa_opt.erl b/lib/compiler/src/beam_ssa_opt.erl
index 261a751880..4533b5b2ef 100644
--- a/lib/compiler/src/beam_ssa_opt.erl
+++ b/lib/compiler/src/beam_ssa_opt.erl
@@ -1005,7 +1005,7 @@ cse_add_inferred_exprs(#b_set{op={bif,tl},dst=Tl,args=[List]}, Es) ->
Es#{{get_tl,[List]} => Tl};
cse_add_inferred_exprs(#b_set{op={bif,map_get},dst=Value,args=[Key,Map]}, Es) ->
Es#{{get_map_element,[Map,Key]} => Value};
-cse_add_inferred_exprs(#b_set{op=put_map,dst=Map,args=Args}, Es) ->
+cse_add_inferred_exprs(#b_set{op=put_map,dst=Map,args=[_,_|Args]}, Es) ->
cse_add_map_get(Args, Map, Es);
cse_add_inferred_exprs(_, Es) -> Es.
diff --git a/lib/compiler/test/map_SUITE.erl b/lib/compiler/test/map_SUITE.erl
index 6269851e85..aec95f1e6d 100644
--- a/lib/compiler/test/map_SUITE.erl
+++ b/lib/compiler/test/map_SUITE.erl
@@ -77,7 +77,10 @@
t_duplicate_keys/1,
%% new in OTP 23
- t_key_expressions/1
+ t_key_expressions/1,
+
+ %% miscellaneous
+ t_cse_assoc/1
]).
suite() -> [].
@@ -138,7 +141,10 @@ all() ->
t_duplicate_keys,
%% new in OTP 23
- t_key_expressions
+ t_key_expressions,
+
+ %% miscellaneous
+ t_cse_assoc
].
groups() -> [].
@@ -2350,6 +2356,29 @@ dup_keys_1(Map) ->
O2
end.
+t_cse_assoc(_Config) ->
+ {'EXIT',{{case_clause,#{key:=any}},_}} = catch do_cse_assoc(id(any)),
+
+ {'EXIT',{{case_clause,#{key:=value}},_}} = catch do_cse_assoc(id(#{}), id(value)),
+ 42 = do_cse_assoc(id(#{assoc => 42}), id(any)),
+
+ ok.
+
+do_cse_assoc(V) ->
+ case #{key => V} of
+ #{assoc := Assoc} ->
+ %% The CSE optimization would consider the first two arguments in
+ %% the argument for `put_map` to be the key `alloc` and the value
+ %% `#{}`.
+ Assoc
+ end.
+
+do_cse_assoc(M, V) ->
+ case M#{key => V} of
+ #{assoc := Assoc} ->
+ Assoc
+ end.
+
%% aux
rand_terms(0) -> [];
--
2.35.3