File 2911-Strengthen-tests-of-relational-operators.patch of Package erlang

From cc712e241005c08d81b6d980fa477011c29b0b88 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Wed, 27 Apr 2022 07:00:30 +0200
Subject: [PATCH] Strengthen tests of relational operators

Strengthen tests of relational operators to better test current
and potential future optimizations done by the JIT.
---
 erts/emulator/test/op_SUITE.erl   | 255 ++++++++++++++++++++++++++++--
 lib/compiler/test/guard_SUITE.erl |  29 +++-
 2 files changed, 269 insertions(+), 15 deletions(-)

diff --git a/erts/emulator/test/op_SUITE.erl b/erts/emulator/test/op_SUITE.erl
index 8353bae15e..fa03262f09 100644
--- a/erts/emulator/test/op_SUITE.erl
+++ b/erts/emulator/test/op_SUITE.erl
@@ -23,18 +23,19 @@
 -include_lib("common_test/include/ct.hrl").
 
 -export([all/0, suite/0,
-         bsl_bsr/1,logical/1,t_not/1,relop_simple/1,relop/1,complex_relop/1]).
+         bsl_bsr/1,logical/1,t_not/1,relop_simple/1,relop/1,
+         complex_relop/1,
+         range_tests/1]).
 
--export([]).
 -import(lists, [foldl/3,flatmap/2]).
 
 suite() ->
     [{ct_hooks,[ts_install_cth]},
      {timetrap, {minutes, 5}}].
 
-all() -> 
+all() ->
     [bsl_bsr, logical, t_not, relop_simple, relop,
-     complex_relop].
+     complex_relop, range_tests].
 
 %% Test the bsl and bsr operators.
 bsl_bsr(Config) when is_list(Config) ->
@@ -334,18 +334,25 @@ run_test_module(Cases, GuardsOk) ->
     Module = erl_parse:new_anno(Module0),
     lists:foreach(fun(F) -> io:put_chars([erl_pp:form(F),"\n"]) end, Module),
 
-    %% Compile, load, and run the generated module.
+    %% Compile, load, and run the generated module. Test both with and
+    %% without compiler optimizations to ensure that we test both the
+    %% implementation of the BIFs and the BEAM instructions.
+    do_run_test_module(Module, []),
+    do_run_test_module(Module, [no_copt,no_ssa_opt,no_postopt]).
+
+do_run_test_module(Module, Opts) ->
+    {ok,Mod,Code1} = compile:forms(Module, [time|Opts]),
+    _ = code:delete(Mod),
+    _ = code:purge(Mod),
 
-    {ok,Mod,Code1} = compile:forms(Module, [time]),
-    code:delete(Mod),
-    code:purge(Mod),
     {module,Mod} = code:load_binary(Mod, Mod, Code1),
+
     run_function(Mod, guard_tests),
     run_function(Mod, body_tests),
     run_function(Mod, bif_tests),
 
     true = code:delete(Mod),
-    code:purge(Mod),
+    _ = code:purge(Mod),
 
     ok.
 
@@ -424,6 +432,236 @@ eval(E0) ->
         {value,Val,_Bs} -> Val
     end.
 
+range_tests(_Config) ->
+    %% Define the limits for smalls on a 64-bit system.
+    {MinSmall, MaxSmall} = {-1 bsl 59, (1 bsl 59) - 1},
+    case erlang:system_info(wordsize) of
+        8 ->
+            %% Assertions.
+            2 = erts_debug:flat_size(MinSmall-1),
+            0 = erts_debug:flat_size(MinSmall),
+            0 = erts_debug:flat_size(MaxSmall),
+            2 = erts_debug:flat_size(MaxSmall+1);
+        4 ->
+            ok
+    end,
+
+    lesser = range(-1 bsl 64),
+    lesser = range(MinSmall),
+    lesser = range(0),
+    lesser = range(-1),
+    lesser = range(0.9999),
+
+    inside = range_any(1),
+    inside = range_any(2),
+    inside = range_any(2.5),
+    inside = range_any(math:pi()),
+    inside = range_any(5),
+    inside = range_any(9),
+    inside = range_any(10),
+
+    greater = range(10.0001),
+    greater = range(11),
+    greater = range(MaxSmall),
+    greater = range(1 bsl 64),
+    greater = range(atom),
+    greater = range(self()),
+    greater = range(make_ref()),
+    greater = range({a,b}),
+    greater = range([a,b]),
+    greater = range([]),
+    greater = range(<<1,2,3>>),
+    greater = range(fun() -> ok end),
+    greater = range(fun ?MODULE:range_tests/1),
+
+    lesser = range(-1 bsl 64),
+    lesser = range(float(-1 bsl 64)),
+    lesser = range_big(MinSmall - 2),
+    lesser = range_barely_small(MinSmall - 1),
+
+    inside = range_barely_small(MinSmall),
+    inside = range_barely_small(-1 bsl 58),
+    inside = range_barely_small(0),
+    inside = range_barely_small(17.75),
+    inside = range_barely_small(1 bsl 58),
+    inside = range_barely_small(MaxSmall),
+
+    greater = range_barely_small(MaxSmall + 1),
+    greater = range_big(MaxSmall + 2),
+    greater = range_big(1 bsl 64),
+    greater = range_big(float(1 bsl 64)),
+
+    lesser = range(-1 bsl 64),
+    lesser = range(float(-1 bsl 64)),
+    lesser = range_big(MinSmall - 2),
+
+    inside = range_big(MinSmall),
+    inside = range_big(-1 bsl 58),
+    inside = range_big(0),
+    inside = range_barely_small(17.75),
+    inside = range_big(1 bsl 58),
+    inside = range_big(MaxSmall),
+
+    greater = range_big(MaxSmall + 2),
+    greater = range_big(1 bsl 64),
+    greater = range_big(float(1 bsl 64)),
+
+    ok.
+
+range(X) ->
+    Res = range_any(X),
+    if
+        is_integer(X) ->
+            Res = range_any(float(X)),
+            Res = range_number(X),
+            Res = range_number(float(X)),
+            Res = range_int(X),
+            if
+                X =:= X band 16#ffff ->
+                    Res = range_small_int(X);
+                true ->
+                    Res
+            end;
+        is_number(X) ->
+            Res = range_number(X);
+        true ->
+            Res = range_big(X),
+            Res = range_barely_small(X)
+    end.
+
+range_any(X0) ->
+    X = id(X0),
+    case range_any_1(X) of
+        inside ->
+            inside = range_any_2(X);
+        Other ->
+            outside = range_any_2(X),
+            Other
+    end.
+
+%% The guard tests have different failure labels.
+range_any_1(X) when 1 =< X, X =< 10 ->
+    inside;
+range_any_1(X) when X < 1 ->
+    lesser;
+range_any_1(X) when X > 10 ->
+    greater.
+
+%% The guard tests have the same failure label.
+range_any_2(X) when 1 =< X, X =< 10 ->
+    inside;
+range_any_2(_) ->
+    outside.
+
+range_number(X) when is_number(X) ->
+    case range_number_1(X) of
+        inside ->
+            inside = range_number_2(X);
+        Other ->
+            outside = range_number_2(X),
+            Other
+    end.
+
+range_number_1(X) when 1 =< X, X =< 10 ->
+    inside;
+range_number_1(X) when X < 1 ->
+    lesser;
+range_number_1(X) when X > 10 ->
+    greater.
+
+range_number_2(X) when 1 =< X, X =< 10 ->
+    inside;
+range_number_2(_) ->
+    outside.
+
+range_int(X) when is_integer(X) ->
+    case range_int_1(X) of
+        inside ->
+            inside = range_int_2(X);
+        Other ->
+            outside = range_int_2(X),
+            Other
+    end.
+
+range_int_1(X) when 1 =< X, X =< 10 ->
+    inside;
+range_int_1(X) when X < 1 ->
+    lesser;
+range_int_1(X) when X > 10 ->
+    greater.
+
+range_int_2(X) when 1 =< X, X =< 10 ->
+    inside;
+range_int_2(_) ->
+    outside.
+
+range_small_int(X) when is_integer(X) ->
+    case range_small_int_1(X) of
+        inside ->
+            inside = range_small_int_2(X);
+        Other ->
+            outside = range_small_int_2(X),
+            Other
+    end.
+
+range_small_int_1(X) when 1 =< X, X =< 10 ->
+    inside;
+range_small_int_1(X) when X < 1 ->
+    lesser;
+range_small_int_1(X) when X > 10 ->
+    greater.
+
+range_small_int_2(X) when 1 =< X, X =< 10 ->
+    inside;
+range_small_int_2(_) ->
+    outside.
+
+range_barely_small(X) ->
+    case range_barely_small_1(X) of
+        inside ->
+            inside = range_barely_small_2(X);
+        Other ->
+            outside = range_barely_small_2(X),
+            Other
+    end.
+
+range_barely_small_1(X) when -1 bsl 59 =< X, X =< (1 bsl 59) - 1 ->
+    inside;
+range_barely_small_1(X) when X < -1 bsl 59 ->
+    lesser;
+range_barely_small_1(X) when X > (1 bsl 59) - 1 ->
+    greater.
+
+range_barely_small_2(X) when -1 bsl 59 =< X, X =< (1 bsl 59) - 1 ->
+    inside;
+range_barely_small_2(_) ->
+    outside.
+
+range_big(X) ->
+    case range_big_1(X) of
+        inside ->
+            inside = range_big_2(X);
+        Other ->
+            outside = range_big_2(X),
+            Other
+    end.
+
+range_big_1(X) when (-1 bsl 59) - 1 =< X, X =< 1 bsl 59 ->
+    inside;
+range_big_1(X) when X < (-1 bsl 59) - 1 ->
+    lesser;
+range_big_1(X) when X > 1 bsl 59 ->
+    greater.
+
+range_big_2(X) when (-1 bsl 59) - 1 =< X, X =< 1 bsl 59 ->
+    inside;
+range_big_2(_) ->
+    outside.
+
+%%%
+%%% Utilities.
+%%%
+
 unvalue(V) ->
     Abstr = erl_parse:abstract(V),
     erl_parse:anno_to_term(Abstr).
diff --git a/lib/compiler/test/guard_SUITE.erl b/lib/compiler/test/guard_SUITE.erl
index 5a4d8d1e80..ba89255e7b 100644
--- a/lib/compiler/test/guard_SUITE.erl
+++ b/lib/compiler/test/guard_SUITE.erl
@@ -1435,16 +1435,24 @@ rel_op_combinations(Config) when is_list(Config) ->
 	lists:seq(16#06F0, 16#06F9),
     Digits = gb_sets:from_list(Digits0),
     rel_op_combinations_1(16#0700, Digits),
+    false = is_digit(-1 bsl 59),
+    false = is_digit(-1 bsl 64),
+    false = is_digit((1 bsl 59) - 1),
+    false = is_digit(1 bsl 64),
 
     BrokenRange0 = lists:seq(3, 5) ++
 	lists:seq(10, 12) ++ lists:seq(14, 20),
     BrokenRange = gb_sets:from_list(BrokenRange0),
     rel_op_combinations_2(30, BrokenRange),
+    false = broken_range(-1 bsl 64),
+    false = broken_range(1 bsl 64),
 
     Red0 = [{I,2*I} || I <- lists:seq(0, 50)] ++
 	[{I,5*I} || I <- lists:seq(51, 80)],
     Red = gb_trees:from_orddict(Red0),
     rel_op_combinations_3(100, Red),
+    2 * (-1 bsl 64) = redundant(-1 bsl 64),
+    none = redundant(1 bsl 64),
 
     rel_op_combinations_4(),
 
@@ -1454,6 +1462,10 @@ rel_op_combinations_1(0, _) ->
     ok;
 rel_op_combinations_1(N, Digits) ->
     Bool = gb_sets:is_member(N, Digits),
+    Bool = is_digit(N),
+    rel_op_combinations_1(N-1, Digits).
+
+is_digit(N) ->
     Bool = is_digit_1(N),
     Bool = is_digit_2(N),
     Bool = is_digit_3(N),
@@ -1464,8 +1476,7 @@ rel_op_combinations_1(N, Digits) ->
     Bool = is_digit_8(N),
     Bool = is_digit_9(42, N),
     Bool = is_digit_10(N, 0),
-    Bool = is_digit_11(N, 0),
-    rel_op_combinations_1(N-1, Digits).
+    Bool = is_digit_11(N, 0).
 
 is_digit_1(X) when 16#0660 =< X, X =< 16#0669 -> true;
 is_digit_1(X) when 16#0030 =< X, X =< 16#0039 -> true;
@@ -1530,6 +1541,10 @@ rel_op_combinations_2(0, _) ->
     ok;
 rel_op_combinations_2(N, Range) ->
     Bool = gb_sets:is_member(N, Range),
+    Bool = broken_range(N),
+    rel_op_combinations_2(N-1, Range).
+
+broken_range(N) ->
     Bool = broken_range_1(N),
     Bool = broken_range_2(N),
     Bool = broken_range_3(N),
@@ -1542,8 +1557,7 @@ rel_op_combinations_2(N, Range) ->
     Bool = broken_range_10(N),
     Bool = broken_range_11(N),
     Bool = broken_range_12(N),
-    Bool = broken_range_13(N),
-    rel_op_combinations_2(N-1, Range).
+    Bool = broken_range_13(N).
 
 broken_range_1(X) when X >= 10, X =< 20, X =/= 13 -> true;
 broken_range_1(X) when X >= 3, X =< 5 -> true;
@@ -1615,6 +1629,10 @@ rel_op_combinations_3(N, Red) ->
 	      none -> none;
 	      {value,V} -> V
 	  end,
+    Val = redundant(N),
+    rel_op_combinations_3(N-1, Red).
+
+redundant(N) ->
     Val = redundant_1(N),
     Val = redundant_2(N),
     Val = redundant_3(N),
@@ -1626,8 +1644,7 @@ rel_op_combinations_3(N, Red) ->
     Val = redundant_9(N),
     Val = redundant_10(N),
     Val = redundant_11(N),
-    Val = redundant_12(N),
-    rel_op_combinations_3(N-1, Red).
+    Val = redundant_12(N).
 
 redundant_1(X) when X >= 51, X =< 80 -> 5*X;
 redundant_1(X) when X < 51 -> 2*X;
-- 
2.34.1

openSUSE Build Service is sponsored by