diff options
| author | John Högberg <john@erlang.org> | 2023-04-27 08:59:59 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-27 08:59:59 +0200 |
| commit | b9ce2f45df308b2359812372579b599d897c8214 (patch) | |
| tree | af4251f9cc705eb137029fb71be68dbe6c6cc204 /lib/compiler | |
| parent | 896f8c1e3120192e8fffb9876ffd9ede3f2da971 (diff) | |
| parent | 3b3e4625195443cfe9186b82cd556fd6b4c49ebf (diff) | |
| download | erlang-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.erl | 12 | ||||
| -rw-r--r-- | lib/compiler/test/beam_validator_SUITE.erl | 21 |
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. |
