File 3133-Enhance-range-analysis-for-the-rem-operator.patch of Package erlang

From acf3116e55f2381f815944e5d69012a8eed432a2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Sun, 13 Aug 2023 09:33:15 +0200
Subject: [PATCH 3/6] Enhance range analysis for the rem operator

Teach beam_bounds:bound/3 to determine a range for the `rem` operator
when nothing is known about the right-hand side operand. For example:

    rem0(A, B) when is_integer(A), 0 =< A, A < 1204 ->
        %% Range for A is 0..1023
        A rem B.                % Range is 0..1023 (same as for A)
---
 lib/compiler/src/beam_bounds.erl        |  6 ++++++
 lib/compiler/test/beam_bounds_SUITE.erl | 13 ++++++++-----
 2 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/lib/compiler/src/beam_bounds.erl b/lib/compiler/src/beam_bounds.erl
index 95a222cf9d..59b7f27c86 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 33f216548d..42a8add3d7 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.
 
-- 
2.35.3

openSUSE Build Service is sponsored by