Re: Probably a bug in LuaJIT x86

  • From: Mike Pall <mikelj-1808@xxxxxxx>
  • To: luajit@xxxxxxxxxxxxx
  • Date: Thu, 16 Aug 2018 22:54:20 +0200

Egor Skriptunoff wrote:

Ok, I replaced ffi.typeof("uint32_t[?]") with ffi.typeof("int32_t[?]").
And 0xDEADBEEF with 0xEADBEEF.
Now all the datatypes are signed and all the constants are inside signed
int32 range.
The bug didn't disappear: a pair of unequal numbers is printed under LuaJIT
x86.

But the addition is still done with a double intermediate numeric
type. So for step i=32 this results in

  -951886476 + -1203853324 = -2155739800

... which is not in range for an int32_t. So the result of the
conversion from double to int32_t is undefined and happens to be
-2147483648 (bit pattern 0x80000000) on x86 in interpreter mode.

See also: https://github.com/LuaJIT/LuaJIT/pull/415

This discusses the related problem with conversions from doubles
to 64 bit integers. There's a general mismatch of user
expectations, architectural differences, undefined semantics and
performance considerations.

This is an open problem and I do not have a good solution.

And, anyone, please read it carefully and try to understand the
whole discussion there _before_ suggestion another seemingly
'simple' solution. I'm pretty sure there is none or I'd use it.

[Note that C has similar pitfalls in its numeric tower. But its
type system uses many more intermediate numeric types, whereas
LuaJIT has only one (a double) and the FFI adds two more (int64_t
and uint64_t). One consequence is that implicit FP to int
conversions are uncommon in C, but very common in LuaJIT.]

--Mike

Other related posts: