From 482d643063cf7e280c838b1c77326ec0d124f8e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Fri, 3 Mar 2023 13:19:23 +0100 Subject: [PATCH] Fix compilation error with disabled optimizations Consider this code: -module(t). -export([foo/0, bar/4]). foo() -> bar(ok, 0 div 0, node(), [-1]). bar(_, _, _, _) -> ok. It fails to compile when some optimizations are turned off: $ erlc +no_copt +no_ssa_opt t.erl t:1: function foo/0+7: Internal consistency check failed - please report this bug. Instruction: {test_heap,2,2} Error: {{x,0},not_live}: --- lib/compiler/src/beam_ssa_pre_codegen.erl | 34 ++++++++++++++--------- lib/compiler/test/beam_ssa_SUITE.erl | 16 +++++++++++ 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/lib/compiler/src/beam_ssa_pre_codegen.erl b/lib/compiler/src/beam_ssa_pre_codegen.erl index 99e6e72007eb..e1b5f5973897 100644 --- a/lib/compiler/src/beam_ssa_pre_codegen.erl +++ b/lib/compiler/src/beam_ssa_pre_codegen.erl @@ -2870,9 +2870,9 @@ reserve_call_args(Args) -> reserve_call_args(Args, 0, #{}). reserve_call_args([#b_var{}=Var|As], X, Xs) -> - reserve_call_args(As, X+1, Xs#{Var=>{x,X}}); + reserve_call_args(As, X+1, Xs#{Var => {x,X}}); reserve_call_args([#b_literal{}|As], X, Xs) -> - reserve_call_args(As, X+1, Xs); + reserve_call_args(As, X+1, Xs#{{x,X} => hole}); reserve_call_args([], _, Xs) -> Xs. reserve_xreg(V, Xs, Res) -> @@ -2898,21 +2898,29 @@ reserve_xreg(V, Xs, Res) -> %% invoking the garbage collector. res_xregs_prune(Xs, Used, Res) when map_size(Xs) =/= 0 -> - %% The number of safe registers is the number of the X registers - %% used after this point. The actual number of safe registers may - %% be higher than this number, but this is a conservative safe - %% estimate. - NumSafe = foldl(fun(V, N) -> - case Res of - #{V:={x,_}} -> N + 1; - #{V:=_} -> N; - #{} -> N + 1 + %% Calculate a conservative estimate for the number of safe + %% registers based on the used X register after this point. The + %% actual number of safe registers may be higher than this number. + NumSafe0 = foldl(fun(V, N) -> + %% Count the number of used variables + %% allocated to X registers. + case Res of + #{V := {x,_}} -> N + 1; + #{V := _} -> N; + #{} -> N + 1 + end + end, 0, Used), + NumSafe = foldl(fun(X, N) -> + %% Decrement the count if there are holes. + case Xs of + #{{x,X} := hole} -> N - 1; + #{} -> N end - end, 0, Used), + end, NumSafe0, seq(0, NumSafe0-1)), %% Remove unsafe registers from the list of potential %% preferred registers. - maps:filter(fun(_, {x,X}) -> X < NumSafe end, Xs); + #{Var => Reg || Var := {x,X}=Reg <- Xs, X < NumSafe}; res_xregs_prune(Xs, _Used, _Res) -> Xs. %%% diff --git a/lib/compiler/test/beam_ssa_SUITE.erl b/lib/compiler/test/beam_ssa_SUITE.erl index adab3bbbc8fb..5868af5972e1 100644 --- a/lib/compiler/test/beam_ssa_SUITE.erl +++ b/lib/compiler/test/beam_ssa_SUITE.erl @@ -901,6 +901,9 @@ grab_bag(_Config) -> {'EXIT',{if_clause,[_|_]}} = catch grab_bag_20(), + 6 = grab_bag_21(id(64)), + {'EXIT',{badarith,_}} = catch grab_bag_21(id(a)), + ok. grab_bag_1() -> @@ -1164,6 +1167,19 @@ grab_bag_20() -> error end}. +%% With the `no_copt` and `no_ssa_opt` options, an internal +%% consistency error would be reported: +%% +%% Internal consistency check failed - please report this bug. +%% Instruction: {test_heap,2,2} +%% Error: {{x,0},not_live}: +grab_bag_21(A) -> + _ = id(0), + grab_bag_21(ok, A div 10, node(), [-1]). + +grab_bag_21(_, D, _, _) -> + D. + 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]]])),