diff --git a/lib/compiler/src/beam_bounds.erl b/lib/compiler/src/beam_bounds.erl index 95a222cf9d48..59b7f27c8649 100644 --- a/lib/compiler/src/beam_bounds.erl +++ b/lib/compiler/src/beam_bounds.erl @@ -319,6 +319,12 @@ rem_bounds(_, {C,D}) when is_integer(C), is_integer(D), Max = max(abs(C), abs(D)) - 1, Min = -Max, normalize({Min,Max}); +rem_bounds({A,B}, _) -> + %% The sign of the remainder is the same as the sign of the + %% left-hand side operand; it does not depend on the sign of the + %% right-hand side operand. Therefore, the range of the remainder + %% is the same as the range of the left-hand side operand. + {A,B}; rem_bounds(_, _) -> any. diff --git a/lib/compiler/test/beam_bounds_SUITE.erl b/lib/compiler/test/beam_bounds_SUITE.erl index 33f216548d3e..42a8add3d716 100644 --- a/lib/compiler/test/beam_bounds_SUITE.erl +++ b/lib/compiler/test/beam_bounds_SUITE.erl @@ -154,11 +154,14 @@ rem_bounds(_Config) -> {-7,7} = beam_bounds:bounds('rem', {'-inf',10}, {1,8}), {0,7} = beam_bounds:bounds('rem', {10,'+inf'}, {1,8}), - any = beam_bounds:bounds('rem', {1,10}, {'-inf',10}), - any = beam_bounds:bounds('rem', {1,10}, {10,'+inf'}), - - any = beam_bounds:bounds('rem', {-10,10}, {'-inf',10}), - any = beam_bounds:bounds('rem', {-10,10}, {10,'+inf'}), + {1,10} = beam_bounds:bounds('rem', {1,10}, {'-inf',10}), + {20,'+inf'} = beam_bounds:bounds('rem', {20,'+inf'}, {10,'+inf'}), + {'-inf',10} = beam_bounds:bounds('rem', {'-inf',10}, any), + + {-11,10} = beam_bounds:bounds('rem', {-11,10}, {'-inf',89}), + {-11,10} = beam_bounds:bounds('rem', {-11,10}, {7,'+inf'}), + {-11,10} = beam_bounds:bounds('rem', {-11,10}, {'-inf',113}), + {-11,10} = beam_bounds:bounds('rem', {-11,10}, {55,'+inf'}), ok.