Tarantool development patches archive
 help / color / mirror / Atom feed
* [Tarantool-patches] [PATCH luajit 0/2] Fix tobit conversion on arm architectures
@ 2026-07-21 14:53 Sergey Kaplun via Tarantool-patches
  2026-07-21 14:53 ` [Tarantool-patches] [PATCH luajit 1/2] ARM64: Make tobit conversions match JIT backend behavior Sergey Kaplun via Tarantool-patches
  2026-07-21 14:53 ` [Tarantool-patches] [PATCH luajit 2/2] ARM: Make hard-float " Sergey Kaplun via Tarantool-patches
  0 siblings, 2 replies; 3+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2026-07-21 14:53 UTC (permalink / raw)
  To: Sergey Bronnikov, Evgeniy Temirgaleev; +Cc: tarantool-patches

This patchset fixes tobit conversion for ARM64 (1) and ARM
architectures. The second commit isn't necessary but helps with future
backporting due to avoiding conflicts.

Branch: https://github.com/tarantool/luajit/tree/skaplun/lj-1253-tobit-conversion
Related issues:
* https://github.com/LuaJIT/LuaJIT/issues/1253
* https://github.com/tarantool/tarantool/issues/12880

Mike Pall (2):
  ARM64: Make tobit conversions match JIT backend behavior.
  ARM: Make hard-float tobit conversions match JIT backend behavior.

 src/vm_arm.dasc                               | 13 ++++++++-
 src/vm_arm64.dasc                             | 20 ++++---------
 .../lj-1253-tobit-conversion.test.lua         | 28 +++++++++++++++++++
 3 files changed, 46 insertions(+), 15 deletions(-)
 create mode 100644 test/tarantool-tests/lj-1253-tobit-conversion.test.lua

-- 
2.55.0


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Tarantool-patches] [PATCH luajit 1/2] ARM64: Make tobit conversions match JIT backend behavior.
  2026-07-21 14:53 [Tarantool-patches] [PATCH luajit 0/2] Fix tobit conversion on arm architectures Sergey Kaplun via Tarantool-patches
@ 2026-07-21 14:53 ` Sergey Kaplun via Tarantool-patches
  2026-07-21 14:53 ` [Tarantool-patches] [PATCH luajit 2/2] ARM: Make hard-float " Sergey Kaplun via Tarantool-patches
  1 sibling, 0 replies; 3+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2026-07-21 14:53 UTC (permalink / raw)
  To: Sergey Bronnikov, Evgeniy Temirgaleev; +Cc: tarantool-patches

From: Mike Pall <mike>

Thanks to Peter Cawley.

(cherry picked from commit cdc2db3aeac442e139c3b1fda715fdfa78da8791)

On the aarch64 architecture, the `tobit()` function incorrectly
truncates instead of rounding to the nearest integer. This leads to
inconsistency between various VMs (comparing to x86/x64, for example)
and between the arm64 VM and JIT.

This patch uses an addition of 2^52 + 2^51 constant to the given
argument to convert it to the nearest integer value. After reading the
lowest 32 bits of the register, we get the expected result.

Sergey Kaplun:
* added the description and the test for the problem

Part of tarantool/tarantool#12880
---
 src/vm_arm64.dasc                             | 20 ++++---------
 .../lj-1253-tobit-conversion.test.lua         | 28 +++++++++++++++++++
 2 files changed, 34 insertions(+), 14 deletions(-)
 create mode 100644 test/tarantool-tests/lj-1253-tobit-conversion.test.lua

diff --git a/src/vm_arm64.dasc b/src/vm_arm64.dasc
index 57131140..4ffd7378 100644
--- a/src/vm_arm64.dasc
+++ b/src/vm_arm64.dasc
@@ -1613,22 +1613,14 @@ static void build_subroutines(BuildCtx *ctx)
   |
   |//-- Bit library --------------------------------------------------------
   |
-  |// FP number to bit conversion for soft-float. Clobbers CARG1-CARG3
+  |// FP number to bit conversion. Clobbers CARG1-CARG2, FARG1-FARG2.
   |->vm_tobit_fb:
   |  bls ->fff_fallback
-  |  add CARG2, CARG1, CARG1
-  |  mov CARG3, #1076
-  |  sub CARG3, CARG3, CARG2, lsr #53
-  |  cmp CARG3, #53
-  |  bhi >1
-  |  and CARG2, CARG2, #U64x(001fffff,ffffffff)
-  |  orr CARG2, CARG2, #U64x(00200000,00000000)
-  |   cmp CARG1, #0
-  |  lsr CARG2, CARG2, CARG3
-  |   cneg CARG1w, CARG2w, mi
-  |  br lr
-  |1:
-  |  mov CARG1w, #0
+  |  fmov FARG1, CARG1
+  |  movz CARG2, #0x4338, lsl #48
+  |  fmov FARG2, CARG2
+  |  fadd FARG1, FARG1, FARG2
+  |  fmov CARG1w, s0
   |  br lr
   |
   |.macro .ffunc_bit, name
diff --git a/test/tarantool-tests/lj-1253-tobit-conversion.test.lua b/test/tarantool-tests/lj-1253-tobit-conversion.test.lua
new file mode 100644
index 00000000..31cf97ca
--- /dev/null
+++ b/test/tarantool-tests/lj-1253-tobit-conversion.test.lua
@@ -0,0 +1,28 @@
+local tap = require('tap')
+
+-- Test file to demonstrate LuaJIT's incorrect bit.tobit
+-- behaviour for arm64.
+-- See also: https://github.com/LuaJIT/LuaJIT/issues/1253.
+
+local test = tap.test('lj-1253-tobit-conversion')
+
+test:plan(2)
+
+test:is(bit.tobit(1.7), 2, 'correct bit.tobit rounding')
+
+test:skipcond({
+  ['Test requires JIT enabled'] = not jit.status(),
+})
+
+local results = {}
+
+jit.opt.start('hotloop=1')
+
+for i = 1, 4 do
+  -- Use constants on trace.
+  results[i] = bit.tobit(1.7)
+end
+
+test:samevalues(results, 'consistent JIT and VM behaviour for bit.tobit')
+
+test:done(true)
-- 
2.55.0


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Tarantool-patches] [PATCH luajit 2/2] ARM: Make hard-float tobit conversions match JIT backend behavior.
  2026-07-21 14:53 [Tarantool-patches] [PATCH luajit 0/2] Fix tobit conversion on arm architectures Sergey Kaplun via Tarantool-patches
  2026-07-21 14:53 ` [Tarantool-patches] [PATCH luajit 1/2] ARM64: Make tobit conversions match JIT backend behavior Sergey Kaplun via Tarantool-patches
@ 2026-07-21 14:53 ` Sergey Kaplun via Tarantool-patches
  1 sibling, 0 replies; 3+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2026-07-21 14:53 UTC (permalink / raw)
  To: Sergey Bronnikov, Evgeniy Temirgaleev; +Cc: tarantool-patches

From: Mike Pall <mike>

Reported by Peter Cawley.

(cherry picked from commit 32a683d226a3b57adbfeabff17d1ae0f7676545d)

On the arm architecture, the `tobit()` function incorrectly truncates
instead of rounding to the nearest integer. This leads to inconsistency
between various VMs (comparing to x86/x64, for example) and between the
arm VM and JIT.

This patch uses an addition of 2^52 + 2^51 constant to the given
argument to convert it to the nearest integer value. After reading the
lowest 32 bits of the register, we get the expected result.

The test is the same as for the previous commit.

Sergey Kaplun:
* added the description for the problem

Part of tarantool/tarantool#12880
---
 src/vm_arm.dasc | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/src/vm_arm.dasc b/src/vm_arm.dasc
index 7ed555f8..139f7fed 100644
--- a/src/vm_arm.dasc
+++ b/src/vm_arm.dasc
@@ -1829,9 +1829,19 @@ static void build_subroutines(BuildCtx *ctx)
   |
   |//-- Bit library --------------------------------------------------------
   |
-  |// FP number to bit conversion for soft-float. Clobbers r0-r3.
   |->vm_tobit_fb:
   |  bhi ->fff_fallback
+  |.if FPU
+  |// FP number to bit conversion for hard-float. Clobbers r0, d0-d1.
+  |  vldr d1, >9
+  |  vmov d0, CARG1, CARG2
+  |  vadd.f64 d0, d0, d1
+  |  vmov CARG1, s0
+  |  bx lr
+  |9:
+  |  .long 0, 0x43380000		// (double)(2^52 + 2^51).
+  |.else
+  |// FP number to bit conversion for soft-float. Clobbers r0-r3.
   |->vm_tobit:
   |  lsl RB, CARG2, #1
   |  adds RB, RB, #0x00200000
@@ -1856,6 +1866,7 @@ static void build_subroutines(BuildCtx *ctx)
   |  orr CARG1, CARG4, CARG1, lsl RB
   |   rsblt CARG1, CARG1, #0
   |  bx lr
+  |.endif
   |
   |.macro .ffunc_bit, name
   |  .ffunc_1 bit_..name
-- 
2.55.0


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-07-21 14:54 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-07-21 14:53 [Tarantool-patches] [PATCH luajit 0/2] Fix tobit conversion on arm architectures Sergey Kaplun via Tarantool-patches
2026-07-21 14:53 ` [Tarantool-patches] [PATCH luajit 1/2] ARM64: Make tobit conversions match JIT backend behavior Sergey Kaplun via Tarantool-patches
2026-07-21 14:53 ` [Tarantool-patches] [PATCH luajit 2/2] ARM: Make hard-float " Sergey Kaplun via Tarantool-patches

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox