From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from [87.239.111.99] (localhost [127.0.0.1]) by dev.tarantool.org (Postfix) with ESMTP id 203636E456; Fri, 24 Jul 2026 13:00:58 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 203636E456 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1784887258; bh=FWW2QNp0awlwCdYoURr7FgeJV5iz705HH9asFMh1Hpo=; h=Date:To:Cc:References:In-Reply-To:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=o4Awya4/6Hkhthjx+p2dG3r7yTU/RLdGWjZi/NcwZwxZ4JArN7NC+2/QFTv1uKx76 4nejE0h+m6spaZXKyZD26q5ZdNjNIoHNj7xslgXKbdjGMLLEYcWn6wiF081jdkYziK FYQnlff1oChCbhJjUtlKEggFXlUFWWBVECdRc8To= Received: from send104.i.mail.ru (send104.i.mail.ru [89.221.237.199]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id 133B56E456 for ; Fri, 24 Jul 2026 13:00:57 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 133B56E456 Received: by exim-smtp-6c76488b9f-qk49n with esmtpa (envelope-from ) id 1wnCi7-000000006mp-42X4; Fri, 24 Jul 2026 13:00:56 +0300 Content-Type: multipart/alternative; boundary="------------qnjc7BtypGA0HeWVElHxTSZb" Message-ID: <0a098bc2-ddb1-4fca-afdf-2a91cc80f7b9@tarantool.org> Date: Fri, 24 Jul 2026 13:00:54 +0300 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Content-Language: en-US To: Sergey Kaplun , Evgeniy Temirgaleev Cc: tarantool-patches@dev.tarantool.org References: In-Reply-To: X-Mailru-Src: smtp X-4EC0790: 10 X-7564579A: 646B95376F6C166E X-77F55803: 4F1203BC0FB41BD93ED3C6BF6FFA701F0B3D367FDA022B56BB42D82DE118CAD0182A05F5380850400A9F094DD3BC49403DE06ABAFEAF670544BBD812BE5DE68D7EC1506C8F585ED7CFC0F0949690F79B X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE751C3618ECA219898EA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F7900637AC83A81C8FD4AD23D82A6BABE6F325AC2E85FA5F3EDFCBAA7353EFBB55337566DDF253B6BCADDB79F50596265B569106FE889E4082F9F0535A62FB2B4D28D922389733CBF5DBD5E913377AFFFEAFD269176DF2183F8FC7C078FCF50C7EAF9C588941B15DA834481FCF19DD082D7633A0EF3E4896CB9E6436389733CBF5DBD5E9D5E8D9A59859A8B65FF0BFC5AEE34BE6CC7F00164DA146DA6F5DAA56C3B73B237318B6A418E8EAB86D1867E19FE14079C09775C1D3CA48CF3D321E7403792E342EB15956EA79C166A417C69337E82CC275ECD9A6C639B01B78DA827A17800CE70BB89B22BF4660DC731C566533BA786AA5CC5B56E945C8DA X-C1DE0DAB: 0D63561A33F958A52C77E7AC3E95AD875002B1117B3ED69633EE5F7EA5906F94E41E333F9D1358D5823CB91A9FED034534781492E4B8EEADAE4FDBF11360AC9BBDAD6C7F3747799A X-C8649E89: 1C3962B70DF3F0AD73CAD6646DEDE191716CD42B3DD1D34CAB70F9BE574AE9C625B6776AC983F447FC0B9F89525902EE6F57B2FD27647F25E66C117BDB76D659A33DFFF6574E75F8E09441D4E518682801D61112A4D311E26E50053320EF165BDA7DC9CD57FFD1F1B8341EE9D5BE9A0A2661E89975A31B3AD66CC0B6B5AB83BA357A4598C4542CB56536EB022892E5344C41F94D744909CE2512F26BEC029E55448553D2254B8D95CD72808BE417F3B9E0E7457915DAA85F X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu53w8ahmwBjZKM/YPHZyZHvz5uv+WouB9+ObcCpyrx6l7KImUglyhkEat/+ysWwi0gdhEs0JGjl6ggRWTy1haxBpVdbIX1nthFXMZebaIdHP2ghjoIc/363UZI6Kf1ptIMVWmxowtcrDwUx6Drq+cvruM= X-DA7885C5: AA778E9089EDAAE6F255D290C0D534F97CC599E76153F24B8E6E2CF2D82BEDCC107EC297F82AEAD95B1A4C17EAA7BC4BEF2421ABFA55128DAF83EF9164C44C7E X-Mailru-Sender: 689FA8AB762F7393520AF17B8A65FDE2AAAC5D31158641A2B22FFDC3A6C765944F3A09E10636C3C7EF86D5F70DA33880E41E8EF7A07863ECB274557F927329BE2DDF8182D28ACDB545BD1C3CC395C826B4A721A3011E896F X-Mras: Ok Subject: Re: [Tarantool-patches] [PATCH luajit 1/2] ARM64: Make tobit conversions match JIT backend behavior. X-BeenThere: tarantool-patches@dev.tarantool.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Sergey Bronnikov via Tarantool-patches Reply-To: Sergey Bronnikov Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" This is a multi-part message in MIME format. --------------qnjc7BtypGA0HeWVElHxTSZb Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit 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) --------------qnjc7BtypGA0HeWVElHxTSZb Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 7bit

Hello,

thanks for the patch! LGTM with a minor comment.

Sergey

On 7/21/26 17:53, Sergey Kaplun wrote:
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

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)
--------------qnjc7BtypGA0HeWVElHxTSZb--