summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjörn Gustavsson <bjorn@erlang.org>2022-11-07 05:33:34 +0100
committerGitHub <noreply@github.com>2022-11-07 05:33:34 +0100
commitd0f071a9e634c6fdd6fea353a7d331fd31a517fb (patch)
treec592920c3f25fa64efa070686429540c1a7476c3
parent41f02c135673f5939ae648f45ba3a963a2e8113b (diff)
parent0cff4a3636f80c6b2ec037f80f8fe78ea163e2c5 (diff)
downloaderlang-d0f071a9e634c6fdd6fea353a7d331fd31a517fb.tar.gz
Merge pull request #6430 from bjorng/bjorn/compiler/ssa_opt_ranges/GH-6427
Eliminate internal error in sub pass ssa_opt_ranges
-rw-r--r--lib/compiler/src/beam_ssa_type.erl14
-rw-r--r--lib/compiler/test/beam_type_SUITE.erl34
2 files changed, 47 insertions, 1 deletions
diff --git a/lib/compiler/src/beam_ssa_type.erl b/lib/compiler/src/beam_ssa_type.erl
index 7e74e7e3f7..b293250365 100644
--- a/lib/compiler/src/beam_ssa_type.erl
+++ b/lib/compiler/src/beam_ssa_type.erl
@@ -920,8 +920,20 @@ update_anno_types_1([#b_var{}=V|As], Ts, Index, ArgTypes) ->
case beam_types:meet(T0, T1) of
any ->
update_anno_types_1(As, Ts, Index + 1, ArgTypes);
+ none ->
+ %% This instruction will never be reached. This happens when
+ %% compiling code such as the following:
+ %%
+ %% f(X) when is_integer(X), 0 =< X, X < 64 ->
+ %% (X = bnot X) + 1.
+ %%
+ %% The main type optimization sub pass will not find out
+ %% that `(X = bnot X)` will never succeed and that the `+`
+ %% operator is never executed, but this sub pass will.
+ %% This happens very rarely; therefore, don't bother removing
+ %% the unreachable instruction.
+ update_anno_types_1(As, Ts, Index + 1, ArgTypes);
T ->
- true = T =/= none, %Assertion.
update_anno_types_1(As, Ts, Index + 1, ArgTypes#{Index => T})
end;
update_anno_types_1([_|As], Ts, Index, ArgTypes) ->
diff --git a/lib/compiler/test/beam_type_SUITE.erl b/lib/compiler/test/beam_type_SUITE.erl
index 3439e36236..8bdce54543 100644
--- a/lib/compiler/test/beam_type_SUITE.erl
+++ b/lib/compiler/test/beam_type_SUITE.erl
@@ -119,6 +119,11 @@ integers(_Config) ->
{'EXIT',{system_limit,_}} = catch do_integers_12(42),
{'EXIT',{system_limit,_}} = catch do_integers_12([]),
+ {'EXIT',{{badmatch,42},_}} = catch do_integers_13(-43),
+ {'EXIT',{{badmatch,0},_}} = catch do_integers_13(-1),
+ {'EXIT',{{badmatch,-1},_}} = catch do_integers_13(0),
+ {'EXIT',{{badmatch,-18},_}} = catch do_integers_13(17),
+
ok.
do_integers_1(B0) ->
@@ -202,6 +207,35 @@ do_integers_11(V) ->
do_integers_12(X) ->
(1 bsl (1 bsl 100)) + X.
+%% GH-6427.
+do_integers_13(X) ->
+ try do_integers_13_1(<<X>>) of
+ _ -> error(should_fail)
+ catch
+ C:R:_ ->
+ try do_integers_13_2(X) of
+ _ -> error(should_fail)
+ catch
+ C:R:_ ->
+ try do_integers_13_3(X) of
+ _ -> error(should_fail)
+ catch
+ C:R:Stk ->
+ erlang:raise(C, R, Stk)
+ end
+ end
+ end.
+
+do_integers_13_1(<<X>>) ->
+ <<(X = bnot X)>>.
+
+do_integers_13_2(X) when is_integer(X), -64 < X, X < 64 ->
+ (X = bnot X) + 1.
+
+do_integers_13_3(X) when is_integer(X), -64 < X, X < 64 ->
+ X = bnot X,
+ X + 1.
+
numbers(_Config) ->
Int = id(42),
true = is_integer(Int),