File 3134-Enhance-range-analysis-for-the-bsl-operator.patch of Package erlang
From a71c2c625e4d5ef46e6ee04af1a2edc8771bc469 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Sun, 13 Aug 2023 07:32:58 +0200
Subject: [PATCH 4/6] Enhance range analysis for the bsl operator
Teach beam_bounds:bounds/3 to calculate a range for the `bsl` operator
when the left-hand side operand is partly unbounded. For example:
bsl0(A) when is_integer(A), A >= 1 ->
%% Range for A is 1..'+inf'
A bsl 3. % Range is 8..'+inf'
bsl1(A) when is_integer(A), A =< 10 ->
%% Range for A is '-inf'..10
A bsl 3. % Range is '-inf'..80
---
lib/compiler/src/beam_bounds.erl | 4 ++--
lib/compiler/test/beam_bounds_SUITE.erl | 10 ++++++++++
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/lib/compiler/src/beam_bounds.erl b/lib/compiler/src/beam_bounds.erl
index 59b7f27c86..034aded4b8 100644
--- a/lib/compiler/src/beam_bounds.erl
+++ b/lib/compiler/src/beam_bounds.erl
@@ -186,8 +186,8 @@ bounds('bsr', R1, R2) ->
end;
bounds('bsl', R1, R2) ->
case {R1,R2} of
- {{A,B}, {C,D}} when abs(A) bsr ?NUM_BITS =:= 0,
- abs(B) bsr ?NUM_BITS =:= 0 ->
+ {{A,B}, {C,D}} when A =:= '-inf' orelse abs(A) bsr ?NUM_BITS =:= 0,
+ B =:= '+inf' orelse abs(B) bsr ?NUM_BITS =:= 0 ->
Min = inf_min(inf_bsl(A, C), inf_bsl(A, D)),
Max = inf_max(inf_bsl(B, C), inf_bsl(B, D)),
normalize({Min,Max});
diff --git a/lib/compiler/test/beam_bounds_SUITE.erl b/lib/compiler/test/beam_bounds_SUITE.erl
index 42a8add3d7..5f5d2441f1 100644
--- a/lib/compiler/test/beam_bounds_SUITE.erl
+++ b/lib/compiler/test/beam_bounds_SUITE.erl
@@ -267,8 +267,13 @@ bsl_bounds(_Config) ->
{2,'+inf'} = beam_bounds:bounds('bsl', {1,10}, {1,10_000}),
{0,'+inf'} = beam_bounds:bounds('bsl', {1,10}, {-10,10_000}),
+ {'-inf',-20} = beam_bounds:bounds('bsl', {-30,-10}, {1,10_000}),
+ {'-inf',-2} = beam_bounds:bounds('bsl', {-9,-1}, {1,10_000}),
any = beam_bounds:bounds('bsl', {-7,10}, {1,10_000}),
+ {0,'+inf'} = beam_bounds:bounds('bsl', {0,'+inf'}, {0,'+inf'}),
+ {20,'+inf'} = beam_bounds:bounds('bsl', {20,30}, {0,'+inf'}),
+
any = beam_bounds:bounds('bsl', {-10,100}, {0,'+inf'}),
any = beam_bounds:bounds('bsl', {-10,100}, {1,'+inf'}),
any = beam_bounds:bounds('bsl', {-10,100}, {-1,'+inf'}),
@@ -281,6 +286,11 @@ bsl_bounds(_Config) ->
{'-inf',-1} = beam_bounds:bounds('bsl', {-10,-1}, {500,1024}),
{0,'+inf'} = beam_bounds:bounds('bsl', {1,10}, {500,1024}),
+ {'-inf',-40} = beam_bounds:bounds('bsl', {'-inf',-10}, {2,64}),
+ {'-inf',224} = beam_bounds:bounds('bsl', {'-inf',7}, {3,5}),
+
+ any = beam_bounds:bounds('bsl', {'-inf',7}, {3,'+inf'}),
+
ok.
lt_bounds(_Config) ->
--
2.35.3