Tarantool development patches archive
 help / color / mirror / Atom feed
* [Tarantool-patches] [PATCH luajit] x86/x64: Fix math.ceil(-0.9) result sign.
@ 2023-11-02 12:36 Sergey Kaplun via Tarantool-patches
  2023-11-07  9:44 ` Maxim Kokryashkin via Tarantool-patches
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2023-11-02 12:36 UTC (permalink / raw)
  To: Maxim Kokryashkin, Sergey Bronnikov; +Cc: tarantool-patches

From: Mike Pall <mike>

Reported by minoki.

(cherry-picked from commit 674afcd4e21d0cf64de3219d347557a0aed8ecc7)

The `ceil` (`floor`) math function implementation calculates (|x| +
2^52) - 2^52 for its argument to determine the fractional part of x , so
it will be rounded to the nearest integer and its sign is restored.
After that, if the original value is < (>) than the result, the -1 (1)
is subtracted from it. Take a look at the `ceil()` case. The result of
the operation `-1 - (-1)` is +0 for FP arithmetic, against -0 expected
as a result.

This patch changes the `- (-1)` operation to `+ 1` and restores sign
after it again.

NB: Since in DUALNUM mode on x86/x64 all results are tried to be
converted to integers the sign of 0 is neglected.

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

Part of tarantool/tarantool#9145
---

Branch: https://github.com/tarantool/luajit/tree/skaplun/lj-859-math-ceil-sign
Tarantool PR: https://github.com/tarantool/tarantool/pull/9326
Related issues:
* https://github.com/LuaJIT/LuaJIT/issues/859
* https://github.com/tarantool/tarantool/issues/9145

 src/vm_x64.dasc                               | 13 ++++++------
 src/vm_x86.dasc                               | 13 ++++++------
 .../lj-859-math-ceil-sign.test.lua            | 20 +++++++++++++++++++
 3 files changed, 32 insertions(+), 14 deletions(-)
 create mode 100644 test/tarantool-tests/lj-859-math-ceil-sign.test.lua

diff --git a/src/vm_x64.dasc b/src/vm_x64.dasc
index 399dfcbf..fc4c6259 100644
--- a/src/vm_x64.dasc
+++ b/src/vm_x64.dasc
@@ -400,9 +400,6 @@
 |.macro sseconst_1, reg, tmp		// Synthesize 1.0.
 |  sseconst_hi reg, tmp, 3ff00000
 |.endmacro
-|.macro sseconst_m1, reg, tmp		// Synthesize -1.0.
-|  sseconst_hi reg, tmp, bff00000
-|.endmacro
 |.macro sseconst_2p52, reg, tmp		// Synthesize 2^52.
 |  sseconst_hi reg, tmp, 43300000
 |.endmacro
@@ -2598,15 +2595,17 @@ static void build_subroutines(BuildCtx *ctx)
   |  addsd xmm1, xmm3			// (|x| + 2^52) - 2^52
   |  subsd xmm1, xmm3
   |  orpd xmm1, xmm2			// Merge sign bit back in.
+  |  sseconst_1 xmm3, RD
   |  .if mode == 1		// ceil(x)?
-  |    sseconst_m1 xmm2, RD		// Must subtract -1 to preserve -0.
   |    cmpsd xmm0, xmm1, 6		// x > result?
+  |    andpd xmm0, xmm3
+  |    addsd xmm1, xmm0			// If yes, add 1.
+  |    orpd xmm1, xmm2			// Merge sign bit back in (again).
   |  .else			// floor(x)?
-  |    sseconst_1 xmm2, RD
   |    cmpsd xmm0, xmm1, 1		// x < result?
+  |    andpd xmm0, xmm3
+  |    subsd xmm1, xmm0			// If yes, subtract 1.
   |  .endif
-  |  andpd xmm0, xmm2
-  |  subsd xmm1, xmm0			// If yes, subtract +-1.
   |.endif
   |  movaps xmm0, xmm1
   |1:
diff --git a/src/vm_x86.dasc b/src/vm_x86.dasc
index 9fa9a3f7..05a8267b 100644
--- a/src/vm_x86.dasc
+++ b/src/vm_x86.dasc
@@ -533,9 +533,6 @@
 |.macro sseconst_1, reg, tmp		// Synthesize 1.0.
 |  sseconst_hi reg, tmp, 3ff00000
 |.endmacro
-|.macro sseconst_m1, reg, tmp		// Synthesize -1.0.
-|  sseconst_hi reg, tmp, bff00000
-|.endmacro
 |.macro sseconst_2p52, reg, tmp		// Synthesize 2^52.
 |  sseconst_hi reg, tmp, 43300000
 |.endmacro
@@ -3089,15 +3086,17 @@ static void build_subroutines(BuildCtx *ctx)
   |  addsd xmm1, xmm3			// (|x| + 2^52) - 2^52
   |  subsd xmm1, xmm3
   |  orpd xmm1, xmm2			// Merge sign bit back in.
+  |  sseconst_1 xmm3, RDa
   |  .if mode == 1		// ceil(x)?
-  |    sseconst_m1 xmm2, RDa		// Must subtract -1 to preserve -0.
   |    cmpsd xmm0, xmm1, 6		// x > result?
+  |    andpd xmm0, xmm3
+  |    addsd xmm1, xmm0			// If yes, add 1.
+  |    orpd xmm1, xmm2			// Merge sign bit back in (again).
   |  .else			// floor(x)?
-  |    sseconst_1 xmm2, RDa
   |    cmpsd xmm0, xmm1, 1		// x < result?
+  |    andpd xmm0, xmm3
+  |    subsd xmm1, xmm0			// If yes, subtract 1.
   |  .endif
-  |  andpd xmm0, xmm2
-  |  subsd xmm1, xmm0			// If yes, subtract +-1.
   |.endif
   |  movaps xmm0, xmm1
   |1:
diff --git a/test/tarantool-tests/lj-859-math-ceil-sign.test.lua b/test/tarantool-tests/lj-859-math-ceil-sign.test.lua
new file mode 100644
index 00000000..df0ca329
--- /dev/null
+++ b/test/tarantool-tests/lj-859-math-ceil-sign.test.lua
@@ -0,0 +1,20 @@
+local tap = require('tap')
+
+-- Test file to demonstrate the incorrect LuaJIT's behaviour
+-- for `math.ceil(x)` when argument `x`: -1 < x < -0.5.
+-- See also https://github.com/LuaJIT/LuaJIT/issues/859.
+
+local test = tap.test('lj-859-math-ceil-sign')
+
+test:plan(1)
+
+local IS_DUALNUM = tostring(tonumber('-0')) ~= tostring(-0)
+local IS_X86_64 = jit.arch == 'x86' or jit.arch == 'x64'
+
+-- Use `tostirng()` to compare sign of the returned value.
+-- Take any value from the mentioned range. Chosen one is
+-- mentioned in the commit message.
+test:ok((IS_DUALNUM and IS_X86_64) or tostring(math.ceil(-0.9)) == '-0',
+        'correct zero sign')
+
+test:done(true)
-- 
2.42.0


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

* Re: [Tarantool-patches] [PATCH luajit] x86/x64: Fix math.ceil(-0.9) result sign.
  2023-11-02 12:36 [Tarantool-patches] [PATCH luajit] x86/x64: Fix math.ceil(-0.9) result sign Sergey Kaplun via Tarantool-patches
@ 2023-11-07  9:44 ` Maxim Kokryashkin via Tarantool-patches
  2023-11-07 10:21   ` Sergey Kaplun via Tarantool-patches
  2023-11-09 13:26 ` Sergey Bronnikov via Tarantool-patches
  2023-11-23  6:31 ` Igor Munkin via Tarantool-patches
  2 siblings, 1 reply; 8+ messages in thread
From: Maxim Kokryashkin via Tarantool-patches @ 2023-11-07  9:44 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Hi, Sergey!
Thanks for the patch!
LGTM, except for a few nits below.

On Thu, Nov 02, 2023 at 03:36:16PM +0300, Sergey Kaplun wrote:
> From: Mike Pall <mike>
> 
> Reported by minoki.
> 
> (cherry-picked from commit 674afcd4e21d0cf64de3219d347557a0aed8ecc7)
> 
> The `ceil` (`floor`) math function implementation calculates (|x| +
> 2^52) - 2^52 for its argument to determine the fractional part of x , so
Typo: s/x ,/x,/
> it will be rounded to the nearest integer and its sign is restored.
> After that, if the original value is < (>) than the result, the -1 (1)
> is subtracted from it. Take a look at the `ceil()` case. The result of
> the operation `-1 - (-1)` is +0 for FP arithmetic, against -0 expected
> as a result.
> 
> This patch changes the `- (-1)` operation to `+ 1` and restores sign
> after it again.
> 
> NB: Since in DUALNUM mode on x86/x64 all results are tried to be
> converted to integers the sign of 0 is neglected.
Typo: s/integers/integers,/
> 
> Sergey Kaplun:
> * added the description and the test for the problem
> 
> Part of tarantool/tarantool#9145
> ---
> 
> Branch: https://github.com/tarantool/luajit/tree/skaplun/lj-859-math-ceil-sign
> Tarantool PR: https://github.com/tarantool/tarantool/pull/9326
> Related issues:
> * https://github.com/LuaJIT/LuaJIT/issues/859
> * https://github.com/tarantool/tarantool/issues/9145
> 
>  src/vm_x64.dasc                               | 13 ++++++------
>  src/vm_x86.dasc                               | 13 ++++++------
>  .../lj-859-math-ceil-sign.test.lua            | 20 +++++++++++++++++++
>  3 files changed, 32 insertions(+), 14 deletions(-)
>  create mode 100644 test/tarantool-tests/lj-859-math-ceil-sign.test.lua
> 
> diff --git a/src/vm_x64.dasc b/src/vm_x64.dasc
> index 399dfcbf..fc4c6259 100644
> --- a/src/vm_x64.dasc
> +++ b/src/vm_x64.dasc
> @@ -400,9 +400,6 @@
>  |.macro sseconst_1, reg, tmp		// Synthesize 1.0.
>  |  sseconst_hi reg, tmp, 3ff00000
>  |.endmacro
> -|.macro sseconst_m1, reg, tmp		// Synthesize -1.0.
> -|  sseconst_hi reg, tmp, bff00000
> -|.endmacro
>  |.macro sseconst_2p52, reg, tmp		// Synthesize 2^52.
>  |  sseconst_hi reg, tmp, 43300000
>  |.endmacro
> @@ -2598,15 +2595,17 @@ static void build_subroutines(BuildCtx *ctx)
>    |  addsd xmm1, xmm3			// (|x| + 2^52) - 2^52
>    |  subsd xmm1, xmm3
>    |  orpd xmm1, xmm2			// Merge sign bit back in.
> +  |  sseconst_1 xmm3, RD
>    |  .if mode == 1		// ceil(x)?
> -  |    sseconst_m1 xmm2, RD		// Must subtract -1 to preserve -0.
>    |    cmpsd xmm0, xmm1, 6		// x > result?
> +  |    andpd xmm0, xmm3
> +  |    addsd xmm1, xmm0			// If yes, add 1.
> +  |    orpd xmm1, xmm2			// Merge sign bit back in (again).
>    |  .else			// floor(x)?
> -  |    sseconst_1 xmm2, RD
>    |    cmpsd xmm0, xmm1, 1		// x < result?
> +  |    andpd xmm0, xmm3
> +  |    subsd xmm1, xmm0			// If yes, subtract 1.
>    |  .endif
> -  |  andpd xmm0, xmm2
> -  |  subsd xmm1, xmm0			// If yes, subtract +-1.
>    |.endif
>    |  movaps xmm0, xmm1
>    |1:
> diff --git a/src/vm_x86.dasc b/src/vm_x86.dasc
> index 9fa9a3f7..05a8267b 100644
> --- a/src/vm_x86.dasc
> +++ b/src/vm_x86.dasc
> @@ -533,9 +533,6 @@
>  |.macro sseconst_1, reg, tmp		// Synthesize 1.0.
>  |  sseconst_hi reg, tmp, 3ff00000
>  |.endmacro
> -|.macro sseconst_m1, reg, tmp		// Synthesize -1.0.
> -|  sseconst_hi reg, tmp, bff00000
> -|.endmacro
>  |.macro sseconst_2p52, reg, tmp		// Synthesize 2^52.
>  |  sseconst_hi reg, tmp, 43300000
>  |.endmacro
> @@ -3089,15 +3086,17 @@ static void build_subroutines(BuildCtx *ctx)
>    |  addsd xmm1, xmm3			// (|x| + 2^52) - 2^52
>    |  subsd xmm1, xmm3
>    |  orpd xmm1, xmm2			// Merge sign bit back in.
> +  |  sseconst_1 xmm3, RDa
>    |  .if mode == 1		// ceil(x)?
> -  |    sseconst_m1 xmm2, RDa		// Must subtract -1 to preserve -0.
>    |    cmpsd xmm0, xmm1, 6		// x > result?
> +  |    andpd xmm0, xmm3
> +  |    addsd xmm1, xmm0			// If yes, add 1.
> +  |    orpd xmm1, xmm2			// Merge sign bit back in (again).
>    |  .else			// floor(x)?
> -  |    sseconst_1 xmm2, RDa
>    |    cmpsd xmm0, xmm1, 1		// x < result?
> +  |    andpd xmm0, xmm3
> +  |    subsd xmm1, xmm0			// If yes, subtract 1.
>    |  .endif
> -  |  andpd xmm0, xmm2
> -  |  subsd xmm1, xmm0			// If yes, subtract +-1.
>    |.endif
>    |  movaps xmm0, xmm1
>    |1:
> diff --git a/test/tarantool-tests/lj-859-math-ceil-sign.test.lua b/test/tarantool-tests/lj-859-math-ceil-sign.test.lua
> new file mode 100644
> index 00000000..df0ca329
> --- /dev/null
> +++ b/test/tarantool-tests/lj-859-math-ceil-sign.test.lua
> @@ -0,0 +1,20 @@
> +local tap = require('tap')
> +
> +-- Test file to demonstrate the incorrect LuaJIT's behaviour
> +-- for `math.ceil(x)` when argument `x`: -1 < x < -0.5.
> +-- See also https://github.com/LuaJIT/LuaJIT/issues/859.
> +
> +local test = tap.test('lj-859-math-ceil-sign')
> +
> +test:plan(1)
> +
> +local IS_DUALNUM = tostring(tonumber('-0')) ~= tostring(-0)
> +local IS_X86_64 = jit.arch == 'x86' or jit.arch == 'x64'
> +
> +-- Use `tostirng()` to compare sign of the returned value.
Typo: s/sign/the sign/
> +-- Take any value from the mentioned range. Chosen one is
Typo: s/Chosen/The chosen/
> +-- mentioned in the commit message.
> +test:ok((IS_DUALNUM and IS_X86_64) or tostring(math.ceil(-0.9)) == '-0',
Nit: maybe we should precalculate the predicate before the `test:ok` call?
Or, at least the `IS_DUALNUM and IS_X86_64`, as it is essentially a skipcond.
> +        'correct zero sign')
> +
> +test:done(true)
> -- 
> 2.42.0
> 

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

* Re: [Tarantool-patches] [PATCH luajit] x86/x64: Fix math.ceil(-0.9) result sign.
  2023-11-07  9:44 ` Maxim Kokryashkin via Tarantool-patches
@ 2023-11-07 10:21   ` Sergey Kaplun via Tarantool-patches
  2023-11-07 10:50     ` Maxim Kokryashkin via Tarantool-patches
  0 siblings, 1 reply; 8+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2023-11-07 10:21 UTC (permalink / raw)
  To: Maxim Kokryashkin; +Cc: tarantool-patches

Hi, Maxim!
Thanks for the review!
Fixed typos and force-pushed the branch.

On 07.11.23, Maxim Kokryashkin wrote:
> Hi, Sergey!
> Thanks for the patch!
> LGTM, except for a few nits below.
> 
> On Thu, Nov 02, 2023 at 03:36:16PM +0300, Sergey Kaplun wrote:
> > From: Mike Pall <mike>
> > 
> > Reported by minoki.
> > 
> > (cherry-picked from commit 674afcd4e21d0cf64de3219d347557a0aed8ecc7)
> > 
> > The `ceil` (`floor`) math function implementation calculates (|x| +
> > 2^52) - 2^52 for its argument to determine the fractional part of x , so
> Typo: s/x ,/x,/

Fixed, thanks!

> > it will be rounded to the nearest integer and its sign is restored.
> > After that, if the original value is < (>) than the result, the -1 (1)
> > is subtracted from it. Take a look at the `ceil()` case. The result of
> > the operation `-1 - (-1)` is +0 for FP arithmetic, against -0 expected
> > as a result.
> > 
> > This patch changes the `- (-1)` operation to `+ 1` and restores sign
> > after it again.
> > 
> > NB: Since in DUALNUM mode on x86/x64 all results are tried to be
> > converted to integers the sign of 0 is neglected.
> Typo: s/integers/integers,/

Fixed!

> > 
> > Sergey Kaplun:
> > * added the description and the test for the problem
> > 
> > Part of tarantool/tarantool#9145
> > ---
> > 
> > Branch: https://github.com/tarantool/luajit/tree/skaplun/lj-859-math-ceil-sign
> > Tarantool PR: https://github.com/tarantool/tarantool/pull/9326
> > Related issues:
> > * https://github.com/LuaJIT/LuaJIT/issues/859
> > * https://github.com/tarantool/tarantool/issues/9145
> > 
> >  src/vm_x64.dasc                               | 13 ++++++------
> >  src/vm_x86.dasc                               | 13 ++++++------
> >  .../lj-859-math-ceil-sign.test.lua            | 20 +++++++++++++++++++
> >  3 files changed, 32 insertions(+), 14 deletions(-)
> >  create mode 100644 test/tarantool-tests/lj-859-math-ceil-sign.test.lua
> > 
> > diff --git a/src/vm_x64.dasc b/src/vm_x64.dasc
> > index 399dfcbf..fc4c6259 100644
> > --- a/src/vm_x64.dasc
> > +++ b/src/vm_x64.dasc
> > @@ -400,9 +400,6 @@
> >  |.macro sseconst_1, reg, tmp		// Synthesize 1.0.
> >  |  sseconst_hi reg, tmp, 3ff00000
> >  |.endmacro
> > -|.macro sseconst_m1, reg, tmp		// Synthesize -1.0.
> > -|  sseconst_hi reg, tmp, bff00000
> > -|.endmacro
> >  |.macro sseconst_2p52, reg, tmp		// Synthesize 2^52.
> >  |  sseconst_hi reg, tmp, 43300000
> >  |.endmacro
> > @@ -2598,15 +2595,17 @@ static void build_subroutines(BuildCtx *ctx)
> >    |  addsd xmm1, xmm3			// (|x| + 2^52) - 2^52
> >    |  subsd xmm1, xmm3
> >    |  orpd xmm1, xmm2			// Merge sign bit back in.
> > +  |  sseconst_1 xmm3, RD
> >    |  .if mode == 1		// ceil(x)?
> > -  |    sseconst_m1 xmm2, RD		// Must subtract -1 to preserve -0.
> >    |    cmpsd xmm0, xmm1, 6		// x > result?
> > +  |    andpd xmm0, xmm3
> > +  |    addsd xmm1, xmm0			// If yes, add 1.
> > +  |    orpd xmm1, xmm2			// Merge sign bit back in (again).
> >    |  .else			// floor(x)?
> > -  |    sseconst_1 xmm2, RD
> >    |    cmpsd xmm0, xmm1, 1		// x < result?
> > +  |    andpd xmm0, xmm3
> > +  |    subsd xmm1, xmm0			// If yes, subtract 1.
> >    |  .endif
> > -  |  andpd xmm0, xmm2
> > -  |  subsd xmm1, xmm0			// If yes, subtract +-1.
> >    |.endif
> >    |  movaps xmm0, xmm1
> >    |1:
> > diff --git a/src/vm_x86.dasc b/src/vm_x86.dasc
> > index 9fa9a3f7..05a8267b 100644
> > --- a/src/vm_x86.dasc
> > +++ b/src/vm_x86.dasc
> > @@ -533,9 +533,6 @@
> >  |.macro sseconst_1, reg, tmp		// Synthesize 1.0.
> >  |  sseconst_hi reg, tmp, 3ff00000
> >  |.endmacro
> > -|.macro sseconst_m1, reg, tmp		// Synthesize -1.0.
> > -|  sseconst_hi reg, tmp, bff00000
> > -|.endmacro
> >  |.macro sseconst_2p52, reg, tmp		// Synthesize 2^52.
> >  |  sseconst_hi reg, tmp, 43300000
> >  |.endmacro
> > @@ -3089,15 +3086,17 @@ static void build_subroutines(BuildCtx *ctx)
> >    |  addsd xmm1, xmm3			// (|x| + 2^52) - 2^52
> >    |  subsd xmm1, xmm3
> >    |  orpd xmm1, xmm2			// Merge sign bit back in.
> > +  |  sseconst_1 xmm3, RDa
> >    |  .if mode == 1		// ceil(x)?
> > -  |    sseconst_m1 xmm2, RDa		// Must subtract -1 to preserve -0.
> >    |    cmpsd xmm0, xmm1, 6		// x > result?
> > +  |    andpd xmm0, xmm3
> > +  |    addsd xmm1, xmm0			// If yes, add 1.
> > +  |    orpd xmm1, xmm2			// Merge sign bit back in (again).
> >    |  .else			// floor(x)?
> > -  |    sseconst_1 xmm2, RDa
> >    |    cmpsd xmm0, xmm1, 1		// x < result?
> > +  |    andpd xmm0, xmm3
> > +  |    subsd xmm1, xmm0			// If yes, subtract 1.
> >    |  .endif
> > -  |  andpd xmm0, xmm2
> > -  |  subsd xmm1, xmm0			// If yes, subtract +-1.
> >    |.endif
> >    |  movaps xmm0, xmm1
> >    |1:
> > diff --git a/test/tarantool-tests/lj-859-math-ceil-sign.test.lua b/test/tarantool-tests/lj-859-math-ceil-sign.test.lua
> > new file mode 100644
> > index 00000000..df0ca329
> > --- /dev/null
> > +++ b/test/tarantool-tests/lj-859-math-ceil-sign.test.lua
> > @@ -0,0 +1,20 @@
> > +local tap = require('tap')
> > +
> > +-- Test file to demonstrate the incorrect LuaJIT's behaviour
> > +-- for `math.ceil(x)` when argument `x`: -1 < x < -0.5.
> > +-- See also https://github.com/LuaJIT/LuaJIT/issues/859.
> > +
> > +local test = tap.test('lj-859-math-ceil-sign')
> > +
> > +test:plan(1)
> > +
> > +local IS_DUALNUM = tostring(tonumber('-0')) ~= tostring(-0)
> > +local IS_X86_64 = jit.arch == 'x86' or jit.arch == 'x64'
> > +
> > +-- Use `tostirng()` to compare sign of the returned value.
> Typo: s/sign/the sign/

Fixed.

> > +-- Take any value from the mentioned range. Chosen one is
> Typo: s/Chosen/The chosen/

Fixed.

> > +-- mentioned in the commit message.
> > +test:ok((IS_DUALNUM and IS_X86_64) or tostring(math.ceil(-0.9)) == '-0',
> Nit: maybe we should precalculate the predicate before the `test:ok` call?
> Or, at least the `IS_DUALNUM and IS_X86_64`, as it is essentially a skipcond.

I preferred the following way to accent in one place when the test is
skipped (in the test itself).

Ignoring for now.

> > +        'correct zero sign')
> > +
> > +test:done(true)
> > -- 
> > 2.42.0
> > 

See the iterative patch below, branch is force-pushed.

===================================================================
diff --git a/test/tarantool-tests/lj-859-math-ceil-sign.test.lua b/test/tarantool-tests/lj-859-math-ceil-sign.test.lua
index df0ca329..831b6480 100644
--- a/test/tarantool-tests/lj-859-math-ceil-sign.test.lua
+++ b/test/tarantool-tests/lj-859-math-ceil-sign.test.lua
@@ -11,8 +11,8 @@ test:plan(1)
 local IS_DUALNUM = tostring(tonumber('-0')) ~= tostring(-0)
 local IS_X86_64 = jit.arch == 'x86' or jit.arch == 'x64'
 
--- Use `tostirng()` to compare sign of the returned value.
--- Take any value from the mentioned range. Chosen one is
+-- Use `tostirng()` to compare the sign of the returned value.
+-- Take any value from the mentioned range. The chosen one is
 -- mentioned in the commit message.
 test:ok((IS_DUALNUM and IS_X86_64) or tostring(math.ceil(-0.9)) == '-0',
         'correct zero sign')
===================================================================

-- 
Best regards,
Sergey Kaplun

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

* Re: [Tarantool-patches]  [PATCH luajit] x86/x64: Fix math.ceil(-0.9) result sign.
  2023-11-07 10:21   ` Sergey Kaplun via Tarantool-patches
@ 2023-11-07 10:50     ` Maxim Kokryashkin via Tarantool-patches
  0 siblings, 0 replies; 8+ messages in thread
From: Maxim Kokryashkin via Tarantool-patches @ 2023-11-07 10:50 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

[-- Attachment #1: Type: text/plain, Size: 7210 bytes --]


Hi!
Thanks for the fixes!
LGTM now.
 
 
--
Best regards,
Maxim Kokryashkin
 
  
>Вторник, 7 ноября 2023, 13:26 +03:00 от Sergey Kaplun <skaplun@tarantool.org>:
> 
>Hi, Maxim!
>Thanks for the review!
>Fixed typos and force-pushed the branch.
>
>On 07.11.23, Maxim Kokryashkin wrote:
>> Hi, Sergey!
>> Thanks for the patch!
>> LGTM, except for a few nits below.
>>
>> On Thu, Nov 02, 2023 at 03:36:16PM +0300, Sergey Kaplun wrote:
>> > From: Mike Pall <mike>
>> >
>> > Reported by minoki.
>> >
>> > (cherry-picked from commit 674afcd4e21d0cf64de3219d347557a0aed8ecc7)
>> >
>> > The `ceil` (`floor`) math function implementation calculates (|x| +
>> > 2^52) - 2^52 for its argument to determine the fractional part of x , so
>> Typo: s/x ,/x,/
>
>Fixed, thanks!
>
>> > it will be rounded to the nearest integer and its sign is restored.
>> > After that, if the original value is < (>) than the result, the -1 (1)
>> > is subtracted from it. Take a look at the `ceil()` case. The result of
>> > the operation `-1 - (-1)` is +0 for FP arithmetic, against -0 expected
>> > as a result.
>> >
>> > This patch changes the `- (-1)` operation to `+ 1` and restores sign
>> > after it again.
>> >
>> > NB: Since in DUALNUM mode on x86/x64 all results are tried to be
>> > converted to integers the sign of 0 is neglected.
>> Typo: s/integers/integers,/
>
>Fixed!
>
>> >
>> > Sergey Kaplun:
>> > * added the description and the test for the problem
>> >
>> > Part of tarantool/tarantool#9145
>> > ---
>> >
>> > Branch:  https://github.com/tarantool/luajit/tree/skaplun/lj-859-math-ceil-sign
>> > Tarantool PR:  https://github.com/tarantool/tarantool/pull/9326
>> > Related issues:
>> > *  https://github.com/LuaJIT/LuaJIT/issues/859
>> > *  https://github.com/tarantool/tarantool/issues/9145
>> >
>> > src/vm_x64.dasc | 13 ++++++------
>> > src/vm_x86.dasc | 13 ++++++------
>> > .../lj-859-math-ceil-sign.test.lua | 20 +++++++++++++++++++
>> > 3 files changed, 32 insertions(+), 14 deletions(-)
>> > create mode 100644 test/tarantool-tests/lj-859-math-ceil-sign.test.lua
>> >
>> > diff --git a/src/vm_x64.dasc b/src/vm_x64.dasc
>> > index 399dfcbf..fc4c6259 100644
>> > --- a/src/vm_x64.dasc
>> > +++ b/src/vm_x64.dasc
>> > @@ -400,9 +400,6 @@
>> > |.macro sseconst_1, reg, tmp // Synthesize 1.0.
>> > | sseconst_hi reg, tmp, 3ff00000
>> > |.endmacro
>> > -|.macro sseconst_m1, reg, tmp // Synthesize -1.0.
>> > -| sseconst_hi reg, tmp, bff00000
>> > -|.endmacro
>> > |.macro sseconst_2p52, reg, tmp // Synthesize 2^52.
>> > | sseconst_hi reg, tmp, 43300000
>> > |.endmacro
>> > @@ -2598,15 +2595,17 @@ static void build_subroutines(BuildCtx *ctx)
>> > | addsd xmm1, xmm3 // (|x| + 2^52) - 2^52
>> > | subsd xmm1, xmm3
>> > | orpd xmm1, xmm2 // Merge sign bit back in.
>> > + | sseconst_1 xmm3, RD
>> > | .if mode == 1 // ceil(x)?
>> > - | sseconst_m1 xmm2, RD // Must subtract -1 to preserve -0.
>> > | cmpsd xmm0, xmm1, 6 // x > result?
>> > + | andpd xmm0, xmm3
>> > + | addsd xmm1, xmm0 // If yes, add 1.
>> > + | orpd xmm1, xmm2 // Merge sign bit back in (again).
>> > | .else // floor(x)?
>> > - | sseconst_1 xmm2, RD
>> > | cmpsd xmm0, xmm1, 1 // x < result?
>> > + | andpd xmm0, xmm3
>> > + | subsd xmm1, xmm0 // If yes, subtract 1.
>> > | .endif
>> > - | andpd xmm0, xmm2
>> > - | subsd xmm1, xmm0 // If yes, subtract +-1.
>> > |.endif
>> > | movaps xmm0, xmm1
>> > |1:
>> > diff --git a/src/vm_x86.dasc b/src/vm_x86.dasc
>> > index 9fa9a3f7..05a8267b 100644
>> > --- a/src/vm_x86.dasc
>> > +++ b/src/vm_x86.dasc
>> > @@ -533,9 +533,6 @@
>> > |.macro sseconst_1, reg, tmp // Synthesize 1.0.
>> > | sseconst_hi reg, tmp, 3ff00000
>> > |.endmacro
>> > -|.macro sseconst_m1, reg, tmp // Synthesize -1.0.
>> > -| sseconst_hi reg, tmp, bff00000
>> > -|.endmacro
>> > |.macro sseconst_2p52, reg, tmp // Synthesize 2^52.
>> > | sseconst_hi reg, tmp, 43300000
>> > |.endmacro
>> > @@ -3089,15 +3086,17 @@ static void build_subroutines(BuildCtx *ctx)
>> > | addsd xmm1, xmm3 // (|x| + 2^52) - 2^52
>> > | subsd xmm1, xmm3
>> > | orpd xmm1, xmm2 // Merge sign bit back in.
>> > + | sseconst_1 xmm3, RDa
>> > | .if mode == 1 // ceil(x)?
>> > - | sseconst_m1 xmm2, RDa // Must subtract -1 to preserve -0.
>> > | cmpsd xmm0, xmm1, 6 // x > result?
>> > + | andpd xmm0, xmm3
>> > + | addsd xmm1, xmm0 // If yes, add 1.
>> > + | orpd xmm1, xmm2 // Merge sign bit back in (again).
>> > | .else // floor(x)?
>> > - | sseconst_1 xmm2, RDa
>> > | cmpsd xmm0, xmm1, 1 // x < result?
>> > + | andpd xmm0, xmm3
>> > + | subsd xmm1, xmm0 // If yes, subtract 1.
>> > | .endif
>> > - | andpd xmm0, xmm2
>> > - | subsd xmm1, xmm0 // If yes, subtract +-1.
>> > |.endif
>> > | movaps xmm0, xmm1
>> > |1:
>> > diff --git a/test/tarantool-tests/lj-859-math-ceil-sign.test.lua b/test/tarantool-tests/lj-859-math-ceil-sign.test.lua
>> > new file mode 100644
>> > index 00000000..df0ca329
>> > --- /dev/null
>> > +++ b/test/tarantool-tests/lj-859-math-ceil-sign.test.lua
>> > @@ -0,0 +1,20 @@
>> > +local tap = require('tap')
>> > +
>> > +-- Test file to demonstrate the incorrect LuaJIT's behaviour
>> > +-- for `math.ceil(x)` when argument `x`: -1 < x < -0.5.
>> > +-- See also  https://github.com/LuaJIT/LuaJIT/issues/859 .
>> > +
>> > +local test = tap.test('lj-859-math-ceil-sign')
>> > +
>> > +test:plan(1)
>> > +
>> > +local IS_DUALNUM = tostring(tonumber('-0')) ~= tostring(-0)
>> > +local IS_X86_64 = jit.arch == 'x86' or jit.arch == 'x64'
>> > +
>> > +-- Use `tostirng()` to compare sign of the returned value.
>> Typo: s/sign/the sign/
>
>Fixed.
>
>> > +-- Take any value from the mentioned range. Chosen one is
>> Typo: s/Chosen/The chosen/
>
>Fixed.
>
>> > +-- mentioned in the commit message.
>> > +test:ok((IS_DUALNUM and IS_X86_64) or tostring(math.ceil(-0.9)) == '-0',
>> Nit: maybe we should precalculate the predicate before the `test:ok` call?
>> Or, at least the `IS_DUALNUM and IS_X86_64`, as it is essentially a skipcond.
>
>I preferred the following way to accent in one place when the test is
>skipped (in the test itself).
>
>Ignoring for now.
>
>> > + 'correct zero sign')
>> > +
>> > +test:done(true)
>> > --
>> > 2.42.0
>> >
>
>See the iterative patch below, branch is force-pushed.
>
>===================================================================
>diff --git a/test/tarantool-tests/lj-859-math-ceil-sign.test.lua b/test/tarantool-tests/lj-859-math-ceil-sign.test.lua
>index df0ca329..831b6480 100644
>--- a/test/tarantool-tests/lj-859-math-ceil-sign.test.lua
>+++ b/test/tarantool-tests/lj-859-math-ceil-sign.test.lua
>@@ -11,8 +11,8 @@ test:plan(1)
> local IS_DUALNUM = tostring(tonumber('-0')) ~= tostring(-0)
> local IS_X86_64 = jit.arch == 'x86' or jit.arch == 'x64'
> 
>--- Use `tostirng()` to compare sign of the returned value.
>--- Take any value from the mentioned range. Chosen one is
>+-- Use `tostirng()` to compare the sign of the returned value.
>+-- Take any value from the mentioned range. The chosen one is
> -- mentioned in the commit message.
> test:ok((IS_DUALNUM and IS_X86_64) or tostring(math.ceil(-0.9)) == '-0',
>         'correct zero sign')
>===================================================================
>
>--
>Best regards,
>Sergey Kaplun
 

[-- Attachment #2: Type: text/html, Size: 9421 bytes --]

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

* Re: [Tarantool-patches] [PATCH luajit] x86/x64: Fix math.ceil(-0.9) result sign.
  2023-11-02 12:36 [Tarantool-patches] [PATCH luajit] x86/x64: Fix math.ceil(-0.9) result sign Sergey Kaplun via Tarantool-patches
  2023-11-07  9:44 ` Maxim Kokryashkin via Tarantool-patches
@ 2023-11-09 13:26 ` Sergey Bronnikov via Tarantool-patches
  2023-11-09 14:32   ` Sergey Kaplun via Tarantool-patches
  2023-11-23  6:31 ` Igor Munkin via Tarantool-patches
  2 siblings, 1 reply; 8+ messages in thread
From: Sergey Bronnikov via Tarantool-patches @ 2023-11-09 13:26 UTC (permalink / raw)
  To: Sergey Kaplun, Maxim Kokryashkin; +Cc: tarantool-patches

Hi, Sergey

thanks for the patch! LGTM

see a minor comment below

On 11/2/23 15:36, Sergey Kaplun wrote:


<snipped>

> +++ b/test/tarantool-tests/lj-859-math-ceil-sign.test.lua
> @@ -0,0 +1,20 @@
> +local tap = require('tap')
> +
> +-- Test file to demonstrate the incorrect LuaJIT's behaviour
> +-- for `math.ceil(x)` when argument `x`: -1 < x < -0.5.
> +-- See also https://github.com/LuaJIT/LuaJIT/issues/859.
> +
> +local test = tap.test('lj-859-math-ceil-sign')
> +
> +test:plan(1)
> +
> +local IS_DUALNUM = tostring(tonumber('-0')) ~= tostring(-0)
> +local IS_X86_64 = jit.arch == 'x86' or jit.arch == 'x64'
> +
> +-- Use `tostirng()` to compare sign of the returned value.

tostirng -> tostring


> +-- Take any value from the mentioned range. Chosen one is
> +-- mentioned in the commit message.
> +test:ok((IS_DUALNUM and IS_X86_64) or tostring(math.ceil(-0.9)) == '-0',
> +        'correct zero sign')
> +
> +test:done(true)

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

* Re: [Tarantool-patches] [PATCH luajit] x86/x64: Fix math.ceil(-0.9) result sign.
  2023-11-09 13:26 ` Sergey Bronnikov via Tarantool-patches
@ 2023-11-09 14:32   ` Sergey Kaplun via Tarantool-patches
  2023-11-09 16:04     ` Sergey Bronnikov via Tarantool-patches
  0 siblings, 1 reply; 8+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2023-11-09 14:32 UTC (permalink / raw)
  To: Sergey Bronnikov; +Cc: tarantool-patches

Hi, Sergey!
Thanks for the review!
Fixed your comment inline, see the iterative patch below.
Branch is rebased and force-pushed.

===================================================================
diff --git a/test/tarantool-tests/lj-859-math-ceil-sign.test.lua b/test/tarantool-tests/lj-859-math-ceil-sign.test.lua
index 831b6480..a67de888 100644
--- a/test/tarantool-tests/lj-859-math-ceil-sign.test.lua
+++ b/test/tarantool-tests/lj-859-math-ceil-sign.test.lua
@@ -11,7 +11,7 @@ test:plan(1)
 local IS_DUALNUM = tostring(tonumber('-0')) ~= tostring(-0)
 local IS_X86_64 = jit.arch == 'x86' or jit.arch == 'x64'
 
--- Use `tostirng()` to compare the sign of the returned value.
+-- Use `tostring()` to compare the sign of the returned value.
 -- Take any value from the mentioned range. The chosen one is
 -- mentioned in the commit message.
 test:ok((IS_DUALNUM and IS_X86_64) or tostring(math.ceil(-0.9)) == '-0',
===================================================================

-- 
Best regards,
Sergey Kaplun

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

* Re: [Tarantool-patches] [PATCH luajit] x86/x64: Fix math.ceil(-0.9) result sign.
  2023-11-09 14:32   ` Sergey Kaplun via Tarantool-patches
@ 2023-11-09 16:04     ` Sergey Bronnikov via Tarantool-patches
  0 siblings, 0 replies; 8+ messages in thread
From: Sergey Bronnikov via Tarantool-patches @ 2023-11-09 16:04 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches


On 11/9/23 17:32, Sergey Kaplun wrote:
> Hi, Sergey!
> Thanks for the review!
> Fixed your comment inline, see the iterative patch below.
> Branch is rebased and force-pushed.
Thanks! LGTM
>

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

* Re: [Tarantool-patches] [PATCH luajit] x86/x64: Fix math.ceil(-0.9) result sign.
  2023-11-02 12:36 [Tarantool-patches] [PATCH luajit] x86/x64: Fix math.ceil(-0.9) result sign Sergey Kaplun via Tarantool-patches
  2023-11-07  9:44 ` Maxim Kokryashkin via Tarantool-patches
  2023-11-09 13:26 ` Sergey Bronnikov via Tarantool-patches
@ 2023-11-23  6:31 ` Igor Munkin via Tarantool-patches
  2 siblings, 0 replies; 8+ messages in thread
From: Igor Munkin via Tarantool-patches @ 2023-11-23  6:31 UTC (permalink / raw)
  To: Sergey Kaplun; +Cc: tarantool-patches

Sergey,

I've checked the patchset into all long-term branches in
tarantool/luajit and bumped a new version in master, release/2.11 and
release/2.10.

On 02.11.23, Sergey Kaplun via Tarantool-patches wrote:
> From: Mike Pall <mike>
> 
> Reported by minoki.
> 
> (cherry-picked from commit 674afcd4e21d0cf64de3219d347557a0aed8ecc7)
> 
> The `ceil` (`floor`) math function implementation calculates (|x| +
> 2^52) - 2^52 for its argument to determine the fractional part of x , so
> it will be rounded to the nearest integer and its sign is restored.
> After that, if the original value is < (>) than the result, the -1 (1)
> is subtracted from it. Take a look at the `ceil()` case. The result of
> the operation `-1 - (-1)` is +0 for FP arithmetic, against -0 expected
> as a result.
> 
> This patch changes the `- (-1)` operation to `+ 1` and restores sign
> after it again.
> 
> NB: Since in DUALNUM mode on x86/x64 all results are tried to be
> converted to integers the sign of 0 is neglected.
> 
> Sergey Kaplun:
> * added the description and the test for the problem
> 
> Part of tarantool/tarantool#9145
> ---
> 
> Branch: https://github.com/tarantool/luajit/tree/skaplun/lj-859-math-ceil-sign
> Tarantool PR: https://github.com/tarantool/tarantool/pull/9326
> Related issues:
> * https://github.com/LuaJIT/LuaJIT/issues/859
> * https://github.com/tarantool/tarantool/issues/9145
> 
>  src/vm_x64.dasc                               | 13 ++++++------
>  src/vm_x86.dasc                               | 13 ++++++------
>  .../lj-859-math-ceil-sign.test.lua            | 20 +++++++++++++++++++
>  3 files changed, 32 insertions(+), 14 deletions(-)
>  create mode 100644 test/tarantool-tests/lj-859-math-ceil-sign.test.lua
> 

<snipped>

> -- 
> 2.42.0
> 

-- 
Best regards,
IM

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

end of thread, other threads:[~2023-11-23  6:37 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-02 12:36 [Tarantool-patches] [PATCH luajit] x86/x64: Fix math.ceil(-0.9) result sign Sergey Kaplun via Tarantool-patches
2023-11-07  9:44 ` Maxim Kokryashkin via Tarantool-patches
2023-11-07 10:21   ` Sergey Kaplun via Tarantool-patches
2023-11-07 10:50     ` Maxim Kokryashkin via Tarantool-patches
2023-11-09 13:26 ` Sergey Bronnikov via Tarantool-patches
2023-11-09 14:32   ` Sergey Kaplun via Tarantool-patches
2023-11-09 16:04     ` Sergey Bronnikov via Tarantool-patches
2023-11-23  6:31 ` Igor Munkin 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