summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Högberg <john@erlang.org>2023-02-22 12:17:49 +0100
committerGitHub <noreply@github.com>2023-02-22 12:17:49 +0100
commitca77c52d2ed2a578648996b3178aaf4a21d44095 (patch)
tree5e2bd3fe9ef445fd08808283aaa12115ded014ef
parentd318661ccb9f9ae775533551052ca05af2a3f7eb (diff)
parent28b1d8fe91763abfde7672f2d3d5e3beab98c445 (diff)
downloaderlang-ca77c52d2ed2a578648996b3178aaf4a21d44095.tar.gz
Merge pull request #6842 from jhogberg/john/compiler/infer-more-arithmetic
beam_call_types: Infer range of various arithmetic operations
-rw-r--r--lib/compiler/src/beam_call_types.erl26
1 files changed, 20 insertions, 6 deletions
diff --git a/lib/compiler/src/beam_call_types.erl b/lib/compiler/src/beam_call_types.erl
index 6226b6d088..8285425374 100644
--- a/lib/compiler/src/beam_call_types.erl
+++ b/lib/compiler/src/beam_call_types.erl
@@ -396,15 +396,18 @@ types(erlang, 'band', [_,_]=Args) ->
types(erlang, 'bor', [_,_]=Args) ->
sub_unsafe(beam_bounds_type('bor', #t_integer{}, Args),
[#t_integer{}, #t_integer{}]);
-types(erlang, 'bxor', [_,_]) ->
- sub_unsafe(#t_integer{}, [#t_integer{}, #t_integer{}]);
-types(erlang, 'bsl', [_,_]) ->
- sub_unsafe(#t_integer{}, [#t_integer{}, #t_integer{}]);
+types(erlang, 'bxor', [_,_]=Args) ->
+ sub_unsafe(beam_bounds_type('bxor', #t_integer{}, Args),
+ [#t_integer{}, #t_integer{}]);
+types(erlang, 'bsl', [_,_]=Args) ->
+ sub_unsafe(beam_bounds_type('bsl', #t_integer{}, Args),
+ [#t_integer{}, #t_integer{}]);
types(erlang, 'bsr', [_,_]=Args) ->
sub_unsafe(beam_bounds_type('bsr', #t_integer{}, Args),
[#t_integer{}, #t_integer{}]);
-types(erlang, 'bnot', [_]) ->
- sub_unsafe(#t_integer{}, [#t_integer{}]);
+types(erlang, 'bnot', [_]=Args) ->
+ sub_unsafe(beam_bounds_type('bnot', #t_integer{}, Args),
+ [#t_integer{}]);
%% Fixed-type arithmetic
types(erlang, 'float', [_]) ->
@@ -1081,6 +1084,17 @@ beam_bounds_type(Op, Type, [LHS, RHS]) ->
#t_integer{elements=beam_bounds:bounds(Op, R1, R2)};
{number, R1, R2} ->
#t_number{elements=beam_bounds:bounds(Op, R1, R2)}
+ end;
+beam_bounds_type(Op, Type, [Arg]) ->
+ case beam_types:meet(Arg, Type) of
+ #t_float{elements=R} ->
+ #t_float{elements=beam_bounds:bounds(Op, R)};
+ #t_integer{elements=R} ->
+ #t_integer{elements=beam_bounds:bounds(Op, R)};
+ #t_number{elements=R} ->
+ #t_number{elements=beam_bounds:bounds(Op, R)};
+ none ->
+ none
end.
get_range(LHS, RHS, Type) ->