From 992a1f18934f071858b5e87f32bda5b49bed637d Mon Sep 17 00:00:00 2001 From: Kostis Sagonas Date: Mon, 11 Jun 2018 17:47:37 +0200 Subject: Fix a crash ih HoPE's lazy code motion pass Some change in the BEAM compiler resulted in the creation of basic blocks that differed from those previously created by the compiler. As a result, the lazy code motion pass of RTL crashed when compiling some of the new code. Crashes were privately reported by @richcarl. --- lib/hipe/rtl/hipe_rtl_lcm.erl | 9 ++++--- .../test/basic_SUITE_data/basic_issues_hipe.erl | 28 ++++++++++++++++++++-- 2 files changed, 32 insertions(+), 5 deletions(-) (limited to 'lib/hipe') diff --git a/lib/hipe/rtl/hipe_rtl_lcm.erl b/lib/hipe/rtl/hipe_rtl_lcm.erl index af39c9a0a4..2c8cc80e56 100644 --- a/lib/hipe/rtl/hipe_rtl_lcm.erl +++ b/lib/hipe/rtl/hipe_rtl_lcm.erl @@ -267,14 +267,17 @@ try_insert_expr_last(CFG0, Label, Instr) -> %% with the new code inserted second to last (assuming the last expression %% is a branch operation). insert_expr_last_work(_Instr, [#call{}]) -> - %% Call instructions clobber all expressions; we musn't insert the expression - %% before it + %% Call instructions clobber all expressions; we must not insert the + %% expression before it not_safe; insert_expr_last_work(Instr, [Code1]) -> %% We insert the code next to last. [Instr, Code1]; insert_expr_last_work(Instr, [Code|Codes]) -> - [Code|insert_expr_last_work(Instr, Codes)]. + case insert_expr_last_work(Instr, Codes) of + not_safe -> not_safe; + NewCodes -> [Code|NewCodes] + end. %%============================================================================= %% Inserts expression first in the block for the given label. diff --git a/lib/hipe/test/basic_SUITE_data/basic_issues_hipe.erl b/lib/hipe/test/basic_SUITE_data/basic_issues_hipe.erl index e71045bfe2..860d882632 100644 --- a/lib/hipe/test/basic_SUITE_data/basic_issues_hipe.erl +++ b/lib/hipe/test/basic_SUITE_data/basic_issues_hipe.erl @@ -8,8 +8,9 @@ -export([test/0]). -%% functions that need to be exported so that they are retained. --export([auth/4]). +%% functions that need to be exported so that they are retained and/or +%% not specialized away by the compiler. +-export([auth/4, wxSizer_replace/2, parent_class/1]). test() -> ok = test_dominance_trees(), @@ -18,6 +19,7 @@ test() -> ok = test_bif_fails(), ok = test_find_catches(), ok = test_heap_allocate_trim(), + ok = wxSizer_replace(), ok. %%-------------------------------------------------------------------- @@ -151,3 +153,25 @@ get_next_retry(Error, Count) -> end. pair(A, B) -> {A, B}. + +%%-------------------------------------------------------------------- +%% Date: June 11, 2018 +%% +%% Stripped down test case (from `wxSizer') that crashed the lazy code +%% motion pass of the HiPE compiler in a pre-release of Erlang/OTP 21. +%% A similar crash existed in `ssl_correction'. +%%-------------------------------------------------------------------- + +wxSizer_replace() -> + wxSizer_replace(wxSizer, wxSizer). + +-define(CLASS(Type, Class), ((Type) =:= Class) orelse (Type):parent_class(Class)). + +wxSizer_replace(OldwinT, NewwinT) -> % this function was the culprit + ?CLASS(OldwinT, wxSizer), + ?CLASS(NewwinT, wxSizer), + ok. + +parent_class(wxWindow) -> true; +parent_class(wxEvtHandler) -> true; +parent_class(_Class) -> erlang:error({badtype, ?MODULE}). -- cgit v1.2.3 From 1d48b1114d195228c750fd0fcd98cb223c714479 Mon Sep 17 00:00:00 2001 From: Kostis Sagonas Date: Tue, 12 Jun 2018 11:26:00 +0200 Subject: No reason to refer to wxSizer in the test --- lib/hipe/test/basic_SUITE_data/basic_issues_hipe.erl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/hipe') diff --git a/lib/hipe/test/basic_SUITE_data/basic_issues_hipe.erl b/lib/hipe/test/basic_SUITE_data/basic_issues_hipe.erl index 860d882632..fc87abb54e 100644 --- a/lib/hipe/test/basic_SUITE_data/basic_issues_hipe.erl +++ b/lib/hipe/test/basic_SUITE_data/basic_issues_hipe.erl @@ -163,13 +163,13 @@ pair(A, B) -> {A, B}. %%-------------------------------------------------------------------- wxSizer_replace() -> - wxSizer_replace(wxSizer, wxSizer). + wxSizer_replace(?MODULE, ?MODULE). -define(CLASS(Type, Class), ((Type) =:= Class) orelse (Type):parent_class(Class)). wxSizer_replace(OldwinT, NewwinT) -> % this function was the culprit - ?CLASS(OldwinT, wxSizer), - ?CLASS(NewwinT, wxSizer), + ?CLASS(OldwinT, ?MODULE), + ?CLASS(NewwinT, ?MODULE), ok. parent_class(wxWindow) -> true; -- cgit v1.2.3