diff --git a/lib/compiler/src/beam_ssa_type.erl b/lib/compiler/src/beam_ssa_type.erl index 52928e7b65ab..3b49ae9ebba8 100644 --- a/lib/compiler/src/beam_ssa_type.erl +++ b/lib/compiler/src/beam_ssa_type.erl @@ -222,10 +222,16 @@ sig_function_1(Id, StMap, State0, FuncDb) -> WlChanged = wl_changed(Wl0, State#sig_st.wl), #{ Id := #func_info{succ_types=SuccTypes0}=Entry0 } = FuncDb, - if - SuccTypes0 =:= SuccTypes -> + case SuccTypes of + [] -> + %% Can never succeed. (Handling this case explicitly is necessary + %% for correctness in rare circumstances to prevent osciallation.) + {false, WlChanged, State, FuncDb}; + SuccTypes0 -> + %% No change from last time. {false, WlChanged, State, FuncDb}; - SuccTypes0 =/= SuccTypes -> + _ -> + %% Success types were refined. Continue iterating. Entry = Entry0#func_info{succ_types=SuccTypes}, {true, WlChanged, State, FuncDb#{ Id := Entry }} end. diff --git a/lib/compiler/test/compilation_SUITE_data/infinite_loop.erl b/lib/compiler/test/compilation_SUITE_data/infinite_loop.erl index 8fb9125c77ad..dea8a7c44765 100644 --- a/lib/compiler/test/compilation_SUITE_data/infinite_loop.erl +++ b/lib/compiler/test/compilation_SUITE_data/infinite_loop.erl @@ -30,3 +30,13 @@ mutually_recursive(X) -> %% This LC will be implemented as mutually recursive functions. %% Analyzing them would cause an infinite loop. [0 || _ <- [], <<_>> <= X]. + +%% GH-6578. The type optimization pass would oscillate between no success +%% types and [any()] -> bitstring(). + +gh_6578(X) -> + << + 0 + || (+(is_alive())) < + [gh_6578(gh_6578(0))|| X] andalso ok + >>.