File 0698-hipe-Assume-that-erlc-only-emits-get_tuple_element-w.patch of Package erlang
From 493d55e875ab1c8a00f4cb0b5b0eb3c4acb5a3d6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20H=C3=B6gberg?= <john@erlang.org>
Date: Mon, 3 Feb 2020 13:05:49 +0100
Subject: [PATCH 2/2] hipe: Assume that erlc only emits get_tuple_element when
safe
---
lib/hipe/icode/hipe_icode_primops.erl | 10 ++-------
lib/hipe/test/basic_SUITE_data/basic_bugs_hipe.erl | 26 ++++++++++++++++++++++
2 files changed, 28 insertions(+), 8 deletions(-)
diff --git a/lib/hipe/icode/hipe_icode_primops.erl b/lib/hipe/icode/hipe_icode_primops.erl
index a1f1128124..4b4fb45322 100644
--- a/lib/hipe/icode/hipe_icode_primops.erl
+++ b/lib/hipe/icode/hipe_icode_primops.erl
@@ -435,14 +435,8 @@ type(Primop, Args) ->
#element{} ->
erl_bif_types:type(erlang, element, 2, Args);
#unsafe_element{index = N} ->
- [Type] = Args,
- case erl_types:t_is_tuple(Type) of
- false ->
- erl_types:t_none();
- true ->
- Index = erl_types:t_from_term(N),
- erl_bif_types:type(erlang, element, 2, [Index|Args])
- end;
+ Index = erl_types:t_from_term(N),
+ erl_bif_types:type(erlang, element, 2, [Index | Args]);
#unsafe_update_element{index = N} ->
%% Same, same
erl_bif_types:type(erlang, setelement, 3, [erl_types:t_integer(N)|Args]);
diff --git a/lib/hipe/test/basic_SUITE_data/basic_bugs_hipe.erl b/lib/hipe/test/basic_SUITE_data/basic_bugs_hipe.erl
index 430e097b91..c6bec39632 100644
--- a/lib/hipe/test/basic_SUITE_data/basic_bugs_hipe.erl
+++ b/lib/hipe/test/basic_SUITE_data/basic_bugs_hipe.erl
@@ -8,6 +8,9 @@
-export([test/0]).
+% Ensure type optimization is turned off for id/1
+-export([id/1]).
+
test() ->
ok = test_ets_bifs(),
ok = test_szar_bug(),
@@ -19,6 +22,7 @@ test() ->
ok = test_switch_neg_int(),
ok = test_icode_range_anal(),
ok = test_icode_range_call(),
+ ok = test_icode_type_miscompile(),
ok.
%%-----------------------------------------------------------------------
@@ -503,3 +507,25 @@ range_client(Server, N) ->
receive proceed -> ok end,
range_client(Server, N - 1), % non-tailrecursive call with ignored result
ok.
+
+test_icode_type_miscompile() ->
+ List0 = id([{1,1},{1,1}]),
+
+ %% The expressions below produce a list that the SSA type pass knows is
+ %% a list of two-tuples, but hipe_icode_type does not.
+ %%
+ %% Changing the `F(X)` call to just `X` helps the icode type pass figure
+ %% things out, making the bug disappear.
+ F = fun({_, _}=X) -> X end,
+ List = [F(X) || {_,_}=X <- List0],
+
+ type_miscompile(List, List, []).
+
+type_miscompile([{Same, Same} | As], [{Same, Same} | Bs], Acc) ->
+ type_miscompile(As, Bs, [gaffel | Acc]);
+type_miscompile([], [], Acc) ->
+ %% Acc is non-empty when everything works as expected.
+ true = Acc =/= [],
+ ok.
+
+id(I) -> I.
--
2.16.4