Hello, thanks for the patch! LGTM with a minor comment. Sergey On 7/21/26 17:53, Sergey Kaplun wrote: > From: Mike Pall > > 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 We usually add parentheses to the name of the function. Here and below. Feel free to ignore. > +-- 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)