Packages

nerves_system_br

1.23.3
1.34.0 1.33.9 1.33.8 1.33.7 1.33.6 1.33.5 1.33.4 1.33.3 1.33.2 1.33.1 1.33.0 1.32.5 1.32.4 1.32.3 1.32.2 1.32.1 1.32.0 1.31.7 1.31.6 1.31.5 1.31.4 1.31.3 1.31.2 1.31.1 1.31.0 1.30.1 1.30.0 1.29.3 1.29.2 1.29.1 1.29.0 1.28.3 1.28.2 1.28.1 1.28.0 1.27.3 1.27.2 1.27.1 1.27.0 1.26.1 1.26.0 1.25.3 1.25.2 1.25.1 1.25.0 1.24.1 1.24.0 1.23.3 1.23.2 1.23.1 1.23.0 1.22.8 1.22.7 1.22.6 1.22.5 1.22.4 1.22.3 1.22.2 1.22.1 1.22.0 1.21.6 1.21.5 1.21.4 1.21.3 1.21.2 1.21.1 1.21.0 1.20.6 1.20.5 1.20.4 1.20.3 1.20.2 1.20.1 1.20.0 1.19.1 1.19.0 1.18.6 1.18.5 1.18.4 1.18.3 1.18.2 1.18.1 1.18.0 1.17.4 1.17.3 1.17.2 1.17.1 1.17.0 1.16.5 1.16.4 1.16.3 1.16.2 1.16.1 1.16.0 1.15.2 1.15.1 1.15.0 1.14.5 1.14.4 1.14.3 1.14.2 1.14.1 1.14.0 1.13.8 1.13.7 1.13.6 1.13.5 1.13.4 1.13.3 1.13.2 1.13.1 1.13.0 1.12.4 1.12.3 1.12.2 1.12.1 1.12.0 1.12.0-rc.0 1.11.4 1.11.3 1.11.2 1.11.1 1.11.0 1.10.3 1.10.2 1.10.1 1.10.0 1.9.5 1.9.4 1.9.3 1.9.2 1.9.1 1.9.0 1.8.6 1.8.5 1.8.4 1.8.3 1.8.2 1.8.1 1.8.0 1.7.3 1.7.2 1.7.1 1.7.0 1.6.8 1.6.7 1.6.6 1.6.5 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.6 1.5.5 1.5.4 1.5.3 1.5.2 1.5.1 1.5.0 1.4.5 1.4.4 1.4.3 1.4.2 1.4.1 1.4.0 1.3.2 1.3.1 1.3.0 1.2.2 1.2.1 1.2.0 1.1.0 1.0.1 1.0.0 1.0.0-rc.4 1.0.0-rc.3 1.0.0-rc.2 1.0.0-rc.1 1.0.0-rc.0 0.17.0 0.16.4 0.16.3 0.16.2 0.16.1-2017-11 0.16.0-2017-11 0.15.1 0.15.0 0.14.1 0.14.0 0.13.9 0.13.8 0.13.7 0.13.6 0.13.5 0.13.4 retired 0.13.3 0.13.2 0.13.0 0.12.1 0.12.0 0.11.1 0.11.0 0.10.1 0.10.0 0.9.4 0.9.3 0.9.2 0.9.1 0.9.0 0.8.2 0.8.1 0.8.0 0.7.0 0.6.1 0.6.0 0.5.2 0.5.1 0.5.0 0.4.2 0.4.1

Nerves System BR - Buildroot based build platform for Nerves Systems

Current section

Files

Jump to
nerves_system_br patches buildroot 0016-erlang-add-aarch64-div-rem-JIT-fix.patch
Raw

patches/buildroot/0016-erlang-add-aarch64-div-rem-JIT-fix.patch

From 1aaad4a32e6fcf5df01d9f8a5447afd0e29ea8dd Mon Sep 17 00:00:00 2001
From: Frank Hunleth <fhunleth@troodon-software.com>
Date: Fri, 25 Aug 2023 15:18:39 -0400
Subject: [PATCH] erlang: add aarch64 div/rem JIT fix
---
...-Fix-incorrect-fusion-of-div-and-rem.patch | 293 ++++++++++++++++++
1 file changed, 293 insertions(+)
create mode 100644 package/erlang/26.0.2/0004-Fix-incorrect-fusion-of-div-and-rem.patch
diff --git a/package/erlang/26.0.2/0004-Fix-incorrect-fusion-of-div-and-rem.patch b/package/erlang/26.0.2/0004-Fix-incorrect-fusion-of-div-and-rem.patch
new file mode 100644
index 0000000000..6f2f5957a3
--- /dev/null
+++ b/package/erlang/26.0.2/0004-Fix-incorrect-fusion-of-div-and-rem.patch
@@ -0,0 +1,293 @@
+From 9f46c61840c699228694716edbd31ee002e733ba Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
+Date: Wed, 16 Aug 2023 18:17:31 +0200
+Subject: [PATCH] Fix incorrect fusion of `div` and `rem`
+
+The JIT would generate code that calculated the remainder incorrectly
+for the following example:
+
+ bug(Bin) ->
+ N = byte_size(Bin),
+ {N rem 128, N div 128}.
+
+Essentially, the JIT would rewrite the code like this:
+
+ bug(Bin) ->
+ N = byte_size(Bin),
+ Q = N bsr 7,
+ {Q band 16#7f, Q}.
+
+That is, the remainder would be calculated as `(N div 128) rem 128`.
+
+Fixes #7566
+---
+ erts/emulator/beam/jit/arm/instr_arith.cpp | 7 +-
+ erts/emulator/test/small_SUITE.erl | 198 +++++++++++++++++++--
+ 2 files changed, 188 insertions(+), 17 deletions(-)
+
+diff --git a/erts/emulator/beam/jit/arm/instr_arith.cpp b/erts/emulator/beam/jit/arm/instr_arith.cpp
+index 1fbec6dbb2..485f93956d 100644
+--- a/erts/emulator/beam/jit/arm/instr_arith.cpp
++++ b/erts/emulator/beam/jit/arm/instr_arith.cpp
+@@ -696,9 +696,14 @@ void BeamModuleAssembler::emit_div_rem(const ArgLabel &Fail,
+ if (Support::isPowerOf2(divisor) &&
+ std::get<0>(getClampedRange(LHS)) >= 0) {
+ int trailing_bits = Support::ctz<Eterm>(divisor);
++ arm::Gp LHS_reg = lhs.reg;
+ if (need_div) {
+ comment("optimized div by replacing with right shift");
+ ERTS_CT_ASSERT(_TAG_IMMED1_SMALL == _TAG_IMMED1_MASK);
++ if (need_rem && quotient.reg == lhs.reg) {
++ LHS_reg = TMP1;
++ a.mov(LHS_reg, lhs.reg);
++ }
+ a.lsr(quotient.reg, lhs.reg, imm(trailing_bits));
+ a.orr(quotient.reg, quotient.reg, imm(_TAG_IMMED1_SMALL));
+ }
+@@ -706,7 +711,7 @@ void BeamModuleAssembler::emit_div_rem(const ArgLabel &Fail,
+ comment("optimized rem by replacing with masking");
+ auto mask = Support::lsbMask<Uint>(trailing_bits +
+ _TAG_IMMED1_SIZE);
+- a.and_(remainder.reg, lhs.reg, imm(mask));
++ a.and_(remainder.reg, LHS_reg, imm(mask));
+ }
+ } else {
+ a.asr(TMP1, lhs.reg, imm(_TAG_IMMED1_SIZE));
+diff --git a/erts/emulator/test/small_SUITE.erl b/erts/emulator/test/small_SUITE.erl
+index c3ca540cd5..7d49522f05 100644
+--- a/erts/emulator/test/small_SUITE.erl
++++ b/erts/emulator/test/small_SUITE.erl
+@@ -521,17 +521,21 @@ div_gen_pairs() ->
+ {_, MaxSmall} = determine_small_limits(0),
+ NumBitsMaxSmall = num_bits(MaxSmall),
+
++ Divisors = [-8,-2,-1,1,2,3,4,5,8,16,17,64,22222333] ++
++ [1 bsl P || P <- lists:seq(8, 12) ++ lists:seq(26, 36)],
++
+ %% Generate random pairs of smalls.
+- Pairs0 = [{rand:uniform(MaxSmall) * rand_sign(),
++ Pairs0 = [{rand:uniform(MaxSmall),
+ rand:uniform(MaxSmall) * rand_sign()} ||
+- _ <- lists:seq(1, 75)],
+-
+- Pairs1 = [{rand:uniform(MaxSmall), N} ||
+- N <- [-4,-3,-2,-1,1,2,3,5,17,63,64,1111,22222]] ++ Pairs0,
++ _ <- lists:seq(1, 50)],
++ Pairs1 = [{rand:uniform(MaxSmall), N} || N <- Divisors] ++ Pairs0,
++ Pairs2 = [{N, M} || N <- lists:seq(0, 7), M <- [-2,-1,1,2,3,4]] ++ Pairs1,
++ Pairs3 = [{abs(M) * (rand:uniform(10)+1) + rand:uniform(1000), M} ||
++ M <- Divisors] ++ Pairs2,
+
+ %% Generate pairs of numbers whose product are bignums.
+ [{rand:uniform(MaxSmall),1 bsl Pow} ||
+- Pow <- lists:seq(NumBitsMaxSmall - 4, NumBitsMaxSmall - 1)] ++ Pairs1.
++ Pow <- lists:seq(NumBitsMaxSmall - 4, NumBitsMaxSmall - 1)] ++ Pairs3.
+
+ rand_sign() ->
+ case rand:uniform() < 0.2 of
+@@ -572,6 +576,22 @@ gen_div_function({Name,{A,B}}) ->
+ put(prevent_div_rem_fusion, Q),
+ R = X rem Y,
+ {Q, R};
++ '@Name@'(pos_integer1, X, fixed) when is_integer(X), 0 =< X, X < _@APlusOne@ ->
++ Y = _@B@,
++ Q = X div Y,
++ R = X rem Y,
++ {Q, R};
++ '@Name@'(pos_integer2, X, fixed) when is_integer(X), 0 =< X, X < _@APlusOne@ ->
++ Y = _@B@,
++ R = X rem Y,
++ Q = X div Y,
++ {Q, R};
++ '@Name@'(pos_integer3, X, fixed) when is_integer(X), 0 =< X, X < _@APlusOne@ ->
++ Y = _@B@,
++ Q = X div Y,
++ put(prevent_div_rem_fusion, Q),
++ R = X rem Y,
++ {Q, R};
+ '@Name@'(number0, X, Y) when -_@APlusOne@ < X, X < _@APlusOne@,
+ -_@BPlusOne@ < Y, Y < _@BPlusOne@ ->
+ Q = X div Y,
+@@ -593,6 +613,108 @@ gen_div_function({Name,{A,B}}) ->
+ Q = X div Y,
+ {Q, R};
+ '@Name@'(number4, X, fixed) when -_@APlusOne@ < X, X < _@APlusOne@ ->
++ Y = _@B@,
++ Q = X div Y,
++ put(prevent_div_rem_fusion, Q),
++ R = X rem Y,
++ {Q, R};
++ '@Name@'(any0, X, fixed) ->
++ Y = _@B@,
++ Q = X div Y,
++ R = X rem Y,
++ {Q, R};
++ '@Name@'(any1, X, fixed) ->
++ Y = _@B@,
++ R = X rem Y,
++ Q = X div Y,
++ {Q, R};
++ '@Name@'(any2, X, fixed) ->
++ Y = _@B@,
++ Q = X div Y,
++ put(prevent_div_rem_fusion, Q),
++ R = X rem Y,
++ {Q, R};
++ '@Name@'(X0, Y0, integer0) ->
++ Q = X0 div Y0,
++ R = X0 rem Y0,
++ if X0 > 0, Y0 > 0 ->
++ <<X:_@NumBitsA@>> = <<X0:_@NumBitsA@>>,
++ <<Y:_@NumBitsB@>> = <<Y0:_@NumBitsB@>>,
++ Q = X div Y,
++ R = X rem Y,
++ {Q, R};
++ true ->
++ {Q, R}
++ end;
++ '@Name@'(X, fixed, integer1) when is_integer(X), -_@APlusOne@ < X, X < _@APlusOne@ ->
++ Y = _@B@,
++ Q = X div Y,
++ R = X rem Y,
++ {Q, R};
++ '@Name@'(X, fixed, integer2) when is_integer(X), -_@APlusOne@ < X, X < _@APlusOne@ ->
++ Y = _@B@,
++ R = X rem Y,
++ Q = X div Y,
++ {Q, R};
++ '@Name@'(X, fixed, integer3) when is_integer(X), -_@APlusOne@ < X, X < _@APlusOne@ ->
++ Y = _@B@,
++ Q = X div Y,
++ put(prevent_div_rem_fusion, Q),
++ R = X rem Y,
++ {Q, R};
++ '@Name@'(X, fixed, pos_integer1) when is_integer(X), 0 =< X, X < _@APlusOne@ ->
++ Y = _@B@,
++ Q = X div Y,
++ R = X rem Y,
++ {Q, R};
++ '@Name@'(X, fixed, pos_integer2) when is_integer(X), 0 =< X, X < _@APlusOne@ ->
++ Y = _@B@,
++ R = X rem Y,
++ Q = X div Y,
++ {Q, R};
++ '@Name@'(X, fixed, pos_integer3) when is_integer(X), 0 =< X, X < _@APlusOne@ ->
++ Y = _@B@,
++ Q = X div Y,
++ put(prevent_div_rem_fusion, Q),
++ R = X rem Y,
++ {Q, R};
++ '@Name@'(X, Y, number0) when -_@APlusOne@ < X, X < _@APlusOne@,
++ -_@BPlusOne@ < Y, Y < _@BPlusOne@ ->
++ Q = X div Y,
++ R = X rem Y,
++ {Q, R};
++ '@Name@'(X, Y, number1) when -_@APlusOne@ < X, X < _@APlusOne@,
++ -_@BPlusOne@ < Y, Y < _@BPlusOne@ ->
++ R = X rem Y,
++ Q = X div Y,
++ {Q, R};
++ '@Name@'(X, fixed, number2) when -_@APlusOne@ < X, X < _@APlusOne@ ->
++ Y = _@B@,
++ Q = X div Y,
++ R = X rem Y,
++ {Q, R};
++ '@Name@'(X, fixed, number3) when -_@APlusOne@ < X, X < _@APlusOne@ ->
++ Y = _@B@,
++ R = X rem Y,
++ Q = X div Y,
++ {Q, R};
++ '@Name@'(X, fixed, number4) when -_@APlusOne@ < X, X < _@APlusOne@ ->
++ Y = _@B@,
++ Q = X div Y,
++ put(prevent_div_rem_fusion, Q),
++ R = X rem Y,
++ {Q, R};
++ '@Name@'(X, fixed, any0) ->
++ Y = _@B@,
++ Q = X div Y,
++ R = X rem Y,
++ {Q, R};
++ '@Name@'(X, fixed, any1) ->
++ Y = _@B@,
++ R = X rem Y,
++ Q = X div Y,
++ {Q, R};
++ '@Name@'(X, fixed, any2) ->
+ Y = _@B@,
+ Q = X div Y,
+ put(prevent_div_rem_fusion, Q),
+@@ -602,16 +724,60 @@ gen_div_function({Name,{A,B}}) ->
+ test_division([{Name,{A,B}}|T], Mod) ->
+ F = fun Mod:Name/3,
+ try
+- Res0 = {A div B, A rem B},
+- Res0 = F(integer0, A, B),
+- Res0 = F(integer1, A, fixed),
+- Res0 = F(integer2, A, fixed),
+- Res0 = F(integer3, A, fixed),
+- Res0 = F(number0, A, B),
+- Res0 = F(number1, A, B),
+- Res0 = F(number2, A, fixed),
+- Res0 = F(number3, A, fixed),
+- Res0 = F(number4, A, fixed)
++ PosRes = {A div B, A rem B},
++ NegRes = {-A div B, -A rem B},
++
++ PosRes = F(integer0, A, B),
++ PosRes = F(integer1, A, fixed),
++ PosRes = F(integer2, A, fixed),
++ PosRes = F(integer3, A, fixed),
++ PosRes = F(pos_integer1, A, fixed),
++ PosRes = F(pos_integer2, A, fixed),
++ PosRes = F(pos_integer3, A, fixed),
++ PosRes = F(number0, A, B),
++ PosRes = F(number1, A, B),
++ PosRes = F(number2, A, fixed),
++ PosRes = F(number3, A, fixed),
++ PosRes = F(number4, A, fixed),
++ PosRes = F(any0, A, fixed),
++ PosRes = F(any1, A, fixed),
++ PosRes = F(any2, A, fixed),
++
++ PosRes = F(A, B, integer0),
++ PosRes = F(A, fixed, integer1),
++ PosRes = F(A, fixed, integer2),
++ PosRes = F(A, fixed, integer3),
++ PosRes = F(A, fixed, pos_integer1),
++ PosRes = F(A, fixed, pos_integer2),
++ PosRes = F(A, fixed, pos_integer3),
++ PosRes = F(A, B, number0),
++ PosRes = F(A, B, number1),
++ PosRes = F(A, fixed, number2),
++ PosRes = F(A, fixed, number3),
++ PosRes = F(A, fixed, number4),
++ PosRes = F(A, fixed, any0),
++ PosRes = F(A, fixed, any1),
++ PosRes = F(A, fixed, any2),
++
++ NegRes = F(integer0, -A, B),
++ NegRes = F(integer1, -A, fixed),
++ NegRes = F(integer2, -A, fixed),
++ NegRes = F(integer3, -A, fixed),
++ NegRes = F(number0, -A, B),
++ NegRes = F(number1, -A, B),
++ NegRes = F(number2, -A, fixed),
++ NegRes = F(number3, -A, fixed),
++ NegRes = F(number4, -A, fixed),
++
++ NegRes = F(-A, B, integer0),
++ NegRes = F(-A, fixed, integer1),
++ NegRes = F(-A, fixed, integer2),
++ NegRes = F(-A, fixed, integer3),
++ NegRes = F(-A, B, number0),
++ NegRes = F(-A, B, number1),
++ NegRes = F(-A, fixed, number2),
++ NegRes = F(-A, fixed, number3),
++ NegRes = F(-A, fixed, number4)
+ catch
+ C:R:Stk ->
+ io:format("~p failed. numbers: ~p ~p\n", [Name,A,B]),
+--
+2.34.1
+
--
2.34.1