diff --git a/lib/compiler/src/beam_bounds.erl b/lib/compiler/src/beam_bounds.erl index dbe84c566f15..cfa6e4d37877 100644 --- a/lib/compiler/src/beam_bounds.erl +++ b/lib/compiler/src/beam_bounds.erl @@ -118,6 +118,9 @@ bounds('*', R1, R2) -> Min = lists:min(All), Max = lists:max(All), normalize({Min,Max}); + {{A,'+inf'}, {C,'+inf'}} when abs(A) bsr ?NUM_BITS =:= 0, A >= 0, + abs(C) bsr ?NUM_BITS =:= 0, C >= 0 -> + {A*C,'+inf'}; {{A,'+inf'}, {C,D}} when abs(A) bsr ?NUM_BITS =:= 0, abs(C) bsr ?NUM_BITS =:= 0, abs(D) bsr ?NUM_BITS =:= 0, diff --git a/lib/compiler/src/beam_call_types.erl b/lib/compiler/src/beam_call_types.erl index ca05d04d1d86..222e586a7943 100644 --- a/lib/compiler/src/beam_call_types.erl +++ b/lib/compiler/src/beam_call_types.erl @@ -484,6 +484,24 @@ types(erlang, Op, [LHS, RHS]) when Op =:= '+'; Op =:= '-' -> mixed_arith_types([LHS, RHS]) end; +types(erlang, '*', [LHS, RHS]) -> + case get_range(LHS, RHS, #t_number{}) of + {Type, {A,B}, {C,D}} -> + case beam_bounds:bounds('*', {A,B}, {C,D}) of + {Min,_Max} when is_integer(Min), Min >= 0 -> + R = {Min,'+inf'}, + RetType = case Type of + integer -> #t_integer{elements=R}; + number -> #t_number{elements=R} + end, + sub_unsafe(RetType, [#t_number{}, #t_number{}]); + _ -> + mixed_arith_types([LHS, RHS]) + end; + _ -> + mixed_arith_types([LHS, RHS]) + end; + types(erlang, abs, [Type]) -> case meet(Type, #t_number{}) of #t_float{} ->