diff options
author | Erlang/OTP <otp@erlang.org> | 2020-05-20 09:57:30 +0200 |
---|---|---|
committer | Erlang/OTP <otp@erlang.org> | 2020-05-20 09:57:30 +0200 |
commit | bb6a061d36f20717be9207a10b5ed97864c1d5fe (patch) | |
tree | bb0a0406a956e88419fbc4f9c81147fd7e75b496 | |
parent | 01c8f2b5638a485bc8dff172d9d581d5e2279993 (diff) | |
parent | 03ffcfd77b466ee40576f33518c51c1120f60c1a (diff) | |
download | erlang-bb6a061d36f20717be9207a10b5ed97864c1d5fe.tar.gz |
Merge branch 'bjorn/compiler/beam_ssa_bool/ERL-1246/OTP-16652' into maint-23
* bjorn/compiler/beam_ssa_bool/ERL-1246/OTP-16652:
Fix incorrect compilation of guard expressions with 'not'
-rw-r--r-- | lib/compiler/src/beam_ssa_bool.erl | 8 | ||||
-rw-r--r-- | lib/compiler/test/guard_SUITE.erl | 25 |
2 files changed, 30 insertions, 3 deletions
diff --git a/lib/compiler/src/beam_ssa_bool.erl b/lib/compiler/src/beam_ssa_bool.erl index 7ae9070df2..8fb87391c5 100644 --- a/lib/compiler/src/beam_ssa_bool.erl +++ b/lib/compiler/src/beam_ssa_bool.erl @@ -922,9 +922,11 @@ opt_digraph_instr(#b_set{dst=Dst}=I, G0, St) -> %% Rewriting 'xor' is not practical. Fortunately, %% 'xor' is almost never used in practice. not_possible(); - #b_set{op={bif,'not'},args=[#b_var{}=Bool]} -> - G = convert_to_br_node(I, Fail, G1, St), - redirect_test(Bool, {fail,Succ}, G, St); + #b_set{op={bif,'not'}} -> + %% This is suprisingly rare. The previous attempt to + %% optimize it was broken, which wasn't noticed because + %% very few test cases triggered this code. + not_possible(); #b_set{op=phi,dst=Bool} -> Vtx = get_vertex(Bool, St), G2 = del_out_edges(Vtx, G1), diff --git a/lib/compiler/test/guard_SUITE.erl b/lib/compiler/test/guard_SUITE.erl index 4a53698e15..badbde612e 100644 --- a/lib/compiler/test/guard_SUITE.erl +++ b/lib/compiler/test/guard_SUITE.erl @@ -2300,6 +2300,7 @@ beam_bool_SUITE(_Config) -> in_catch(), recv_semi(), andalso_repeated_var(), + erl1246(), ok. before_and_inside_if() -> @@ -2597,6 +2598,30 @@ andalso_repeated_var() -> andalso_repeated_var(B) when B andalso B -> ok; andalso_repeated_var(_) -> error. +-record(erl1246, {tran_stat = 0}). + +erl1246() -> + false = erl1246(#erl1246{tran_stat = 0}, #{cid => 1131}), + false = erl1246(#erl1246{tran_stat = 12}, #{cid => 1131}), + false = erl1246(#erl1246{tran_stat = 12}, #{cid => 9502}), + true = erl1246(#erl1246{tran_stat = 0}, #{cid => 9502}), + ok. + +erl1246(Rec, #{cid := CollID}) -> + {GiftCollID, _} = erl1246_conf(gift_coll), + IsTranStat = Rec#erl1246.tran_stat =:= erl1246_conf(transform_id), + if + %% Optimization of 'not' in a guard was broken. + CollID =:= GiftCollID andalso not IsTranStat -> + true; + true -> + false + end. + +erl1246_conf(gift_coll) -> {9502, {112, 45}}; +erl1246_conf(transform_id) -> 12; +erl1246_conf(_) -> undefined. + %%% %%% End of beam_bool_SUITE tests. %%% |