summaryrefslogtreecommitdiff
path: root/lib/compiler
diff options
context:
space:
mode:
authorJohn Högberg <john@erlang.org>2023-04-27 08:59:59 +0200
committerGitHub <noreply@github.com>2023-04-27 08:59:59 +0200
commitb9ce2f45df308b2359812372579b599d897c8214 (patch)
treeaf4251f9cc705eb137029fb71be68dbe6c6cc204 /lib/compiler
parent896f8c1e3120192e8fffb9876ffd9ede3f2da971 (diff)
parent3b3e4625195443cfe9186b82cd556fd6b4c49ebf (diff)
downloaderlang-b9ce2f45df308b2359812372579b599d897c8214.tar.gz
Merge pull request #7173 from jhogberg/john/compiler/improve-validator-range-inference/GH-7171
beam_validator: Improve arithmetic range inference
Diffstat (limited to 'lib/compiler')
-rw-r--r--lib/compiler/src/beam_validator.erl12
-rw-r--r--lib/compiler/test/beam_validator_SUITE.erl21
2 files changed, 30 insertions, 3 deletions
diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl
index 37945fc8aa..217b7a2c97 100644
--- a/lib/compiler/src/beam_validator.erl
+++ b/lib/compiler/src/beam_validator.erl
@@ -3435,7 +3435,17 @@ bif_types(Op, Ss, Vst) ->
Other
end;
{_,_} ->
- beam_call_types:types(erlang, Op, Args)
+ Res0 = beam_call_types:types(erlang, Op, Args),
+ {Ret0, ArgTypes, SubSafe} = Res0,
+
+ %% Match the non-converging range analysis done in
+ %% `beam_ssa_type:opt_ranges/1`. This is safe since the validator
+ %% doesn't have to worry about convergence.
+ case beam_call_types:arith_type({bif, Op}, Args) of
+ any -> Res0;
+ Ret0 -> Res0;
+ Ret -> {meet(Ret, Ret0), ArgTypes, SubSafe}
+ end
end.
join_tuple_elements(Tuple) ->
diff --git a/lib/compiler/test/beam_validator_SUITE.erl b/lib/compiler/test/beam_validator_SUITE.erl
index 6b63f561c1..2092d7401a 100644
--- a/lib/compiler/test/beam_validator_SUITE.erl
+++ b/lib/compiler/test/beam_validator_SUITE.erl
@@ -43,7 +43,7 @@
container_performance/1,
infer_relops/1,
not_equal_inference/1,bad_bin_unit/1,singleton_inference/1,
- inert_update_type/1]).
+ inert_update_type/1,range_inference/1]).
-include_lib("common_test/include/ct.hrl").
@@ -80,7 +80,7 @@ groups() ->
bs_saved_position_units,parent_container,
container_performance,infer_relops,
not_equal_inference,bad_bin_unit,singleton_inference,
- inert_update_type]}].
+ inert_update_type,range_inference]}].
init_per_suite(Config) ->
test_lib:recompile(?MODULE),
@@ -1129,5 +1129,22 @@ mike([Head | _Rest]) -> joe(Head).
joe({Name, 42}) -> Name;
joe({sys_period, {A, _B}}) -> {41, 42, A}.
+range_inference(_Config) ->
+ ok = range_inference_1(id(<<$a>>)),
+ ok = range_inference_1(id(<<0>>)),
+ ok = range_inference_1(id(<<1114111/utf8>>)),
+
+ ok.
+
+range_inference_1(<<X/utf8>>) ->
+ case 9223372036854775807 - abs(X) of
+ Y when X < Y ->
+ ok;
+ 9223372036854775807 ->
+ ok;
+ -2147483648 ->
+ ok
+ end.
+
id(I) ->
I.