<HTML><BODY><div class="cl-093ni2485s"><div class="js-helper_mr_css_attr js-readmsg-msg_mr_css_attr"><div id="style_17852627132025491536_mr_css_attr"><div id="style_17852627132025491536_BODY_mr_css_attr"><div class="cl-v5khaokp2q_mr_css_attr"><div>Hi, Sergey! Thanks for the patch!</div><div> </div><div>LGTM with a comment, please see below. <br> </div><div data-signature-widget="container"><div data-signature-widget="content"><div>--<br>Best regards,</div><div>Evgeniy Temirgaleev</div></div></div> <div class="mail-quote-collapse_mr_css_attr"><div class="mail-quote-collapse"><blockquote style="border-left:1px solid #0857A6;margin:10px;padding:0 0 0 10px"><span><span>From: Sergey Kaplun <<a href="mailto:skaplun@tarantool.org">skaplun@tarantool.org</a>><br>To: Sergey Bronnikov <<a href="mailto:sergeyb@tarantool.org">sergeyb@tarantool.org</a>>, Evgeniy Temirgaleev <<a href="mailto:e.temirgaleev@tarantool.org">e.temirgaleev@tarantool.org</a>><br>Cc: tarantool-patches@dev.tarantool.org, Sergey Kaplun <<a href="mailto:skaplun@tarantool.org">skaplun@tarantool.org</a>><br>Date: Tuesday, July 21, 2026 5:53 PM +03:00</span></span> <div> <div><div id=""><div class="cl-274sapn1z2_mr_css_attr"><div class="js-helper_mr_css_attr js-readmsg-msg_mr_css_attr"><div id="style_17846456050926390647_mr_css_attr"><div id="style_17846456050926390647_BODY_mr_css_attr">From: Mike Pall <mike><br><br>Thanks to Peter Cawley.<br><br>(cherry picked from commit cdc2db3aeac442e139c3b1fda715fdfa78da8791)<br><br>On the aarch64 architecture, the `tobit()` function incorrectly<br>truncates instead of rounding to the nearest integer. This leads to<br>inconsistency between various VMs (comparing to x86/x64, for example)<br>and between the arm64 VM and JIT.<br><br>This patch uses an addition of 2^52 + 2^51 constant to the given<br>argument to convert it to the nearest integer value. After reading the<br>lowest 32 bits of the register, we get the expected result.<br><br>Sergey Kaplun:<br>* added the description and the test for the problem<br><br>Part of tarantool/tarantool#12880<br>---<br>src/vm_arm64.dasc | 20 ++++---------<br>.../lj-1253-tobit-conversion.test.lua | 28 +++++++++++++++++++<br>2 files changed, 34 insertions(+), 14 deletions(-)<br>create mode 100644 test/tarantool-tests/lj-1253-tobit-conversion.test.lua<br><br>diff --git a/src/vm_arm64.dasc b/src/vm_arm64.dasc<br>index 57131140..4ffd7378 100644<br>--- a/src/vm_arm64.dasc<br>+++ b/src/vm_arm64.dasc<br>@@ -1613,22 +1613,14 @@ static void build_subroutines(BuildCtx *ctx)<br>|<br>|//-- Bit library --------------------------------------------------------<br>|<br>- |// FP number to bit conversion for soft-float. Clobbers CARG1-CARG3<br>+ |// FP number to bit conversion. Clobbers CARG1-CARG2, FARG1-FARG2.<br>|->vm_tobit_fb:<br>| bls ->fff_fallback<br>- | add CARG2, CARG1, CARG1<br>- | mov CARG3, #1076<br>- | sub CARG3, CARG3, CARG2, lsr #53<br>- | cmp CARG3, #53<br>- | bhi >1<br>- | and CARG2, CARG2, #U64x(001fffff,ffffffff)<br>- | orr CARG2, CARG2, #U64x(00200000,00000000)<br>- | cmp CARG1, #0<br>- | lsr CARG2, CARG2, CARG3<br>- | cneg CARG1w, CARG2w, mi<br>- | br lr<br>- |1:<br>- | mov CARG1w, #0<br>+ | fmov FARG1, CARG1<br>+ | movz CARG2, #0x4338, lsl #48<br>+ | fmov FARG2, CARG2<br>+ | fadd FARG1, FARG1, FARG2<br>+ | fmov CARG1w, s0<br>| br lr<br>|<br>|.macro .ffunc_bit, name<br>diff --git a/test/tarantool-tests/lj-1253-tobit-conversion.test.lua b/test/tarantool-tests/lj-1253-tobit-conversion.test.lua<br>new file mode 100644<br>index 00000000..31cf97ca<br>--- /dev/null<br>+++ b/test/tarantool-tests/lj-1253-tobit-conversion.test.lua<br>@@ -0,0 +1,28 @@<br>+local tap = require('tap')<br>+<br>+-- Test file to demonstrate LuaJIT's incorrect bit.tobit<br>+-- behaviour for arm64.<br>+-- See also: <a href="https://github.com/LuaJIT/LuaJIT/issues/1253">https://github.com/LuaJIT/LuaJIT/issues/1253</a>.<br>+<br>+local test = tap.test('lj-1253-tobit-conversion')<br>+<br>+test:plan(2)<br>+<br>+test:is(bit.tobit(1.7), 2, 'correct bit.tobit rounding')</div></div></div></div></div></div></div></blockquote></div></div></div><div>I suppose, what Sergey Bronnikov proposes adding parentheses in the messages also. Here,</div><div class="cl-v5khaokp2q_mr_css_attr"><div class="mail-quote-collapse_mr_css_attr"><blockquote style="border-left:1px solid #0857A6;margin:10px;padding:0 0 0 10px"><div><div><div class="cl-274sapn1z2_mr_css_attr"><div class="js-helper_mr_css_attr js-readmsg-msg_mr_css_attr"><div><div>+<br>+test:skipcond({<br>+ ['Test requires JIT enabled'] = not jit.status(),<br>+})<br>+<br>+local results = {}<br>+<br>+jit.opt.start('hotloop=1')<br>+<br>+for i = 1, 4 do<br>+ -- Use constants on trace.<br>+ results[i] = bit.tobit(1.7)<br>+end<br>+<br>+test:samevalues(results, 'consistent JIT and VM behaviour for bit.tobit')</div></div></div></div></div></div></blockquote></div></div></div></div></div></div><div>and here.</div><div class="cl-093ni2485s"><div class="js-helper_mr_css_attr js-readmsg-msg_mr_css_attr"><div><div><div class="cl-v5khaokp2q_mr_css_attr"><div class="mail-quote-collapse_mr_css_attr"><blockquote style="border-left:1px solid #0857A6;margin:10px;padding:0 0 0 10px"><div><div><div class="cl-274sapn1z2_mr_css_attr"><div class="js-helper_mr_css_attr js-readmsg-msg_mr_css_attr"><div><div>+<br>+test:done(true)<br>--<br>2.55.0</div></div></div></div></div></div></blockquote></div></div></div></div></div></div></BODY></HTML>