From: Mike Pall <mike>
Thanks to Peter Cawley.
(cherry picked from commit 05fbdf565c700365d22e38f11478101a0d92a23e)
To reproduce the issue we need to assemble `IR_SLOAD` with
`IRSLOAD_TYPECHECK` flag set. Also, this IR shouldn't be used later and
be not pri, not any number, not any integer type. For GC64 mode, we get
the following mcode for this typecheck only variant of the IR:
| 55557f6bffc9 mov rdi, [rdx+0x4]
| 55557f6bffcd sar rdi, 0x2f
| 55557f6bffd1 cmp edi, -0x0b
| 55557f6bffd4 jnz 0x55557f6b0010 ->0
This 0x4 addition is excess and crucial:
We got the invalid irtype value to compare (due wrong addressing) -- so
the assertion guard is always failed and we always exit from the trace.
This patch removes this addition.
Sergey Kaplun:
* added the description and the test for the problem
Part of tarantool/tarantool#7230
---
Branch:
https://github.com/tarantool/luajit/tree/skaplun/lj-350-fix-sload-typecheck-full-ciIssues:
*
https://github.com/tarantool/tarantool/issues/7230*
https://github.com/LuaJIT/LuaJIT/pull/350Tarantool PR:
https://github.com/tarantool/tarantool/pull/7995 src/lj_asm_x86.h | 2 +-
.../lj-350-sload-typecheck.test.lua | 42 +++++++++++++++++++
.../lj-408-tonumber-cdata-record.test.lua | 10 -----
3 files changed, 43 insertions(+), 11 deletions(-)
create mode 100644 test/tarantool-tests/lj-350-sload-typecheck.test.lua
diff --git a/src/lj_asm_x86.h b/src/lj_asm_x86.h
index 8a4d4025..8efda8e5 100644
--- a/src/lj_asm_x86.h
+++ b/src/lj_asm_x86.h
@@ -1759,7 +1759,7 @@ static void asm_sload(ASMState *as, IRIns *ir)
emit_i8(as, irt_toitype(t));
emit_rr(as, XO_ARITHi8, XOg_CMP, tmp);
emit_shifti(as, XOg_SAR|REX_64, tmp, 47);
- emit_rmro(as, XO_MOV, tmp|REX_64, base, ofs+4);
+ emit_rmro(as, XO_MOV, tmp|REX_64, base, ofs);
#else
} else {
emit_i8(as, irt_toitype(t));
diff --git a/test/tarantool-tests/lj-350-sload-typecheck.test.lua b/test/tarantool-tests/lj-350-sload-typecheck.test.lua
new file mode 100644
index 00000000..6ffc61fb
--- /dev/null
+++ b/test/tarantool-tests/lj-350-sload-typecheck.test.lua
@@ -0,0 +1,42 @@
+local tap = require('tap')
+local traceinfo = require('jit.util').traceinfo
+
+-- Test file to demonstrate the incorrect GC64 JIT asembling
+-- `IR_SLOAD`.
+-- See also
https://github.com/LuaJIT/LuaJIT/pull/350.
+local test = tap.test('lj-350-sload-typecheck')
+
+test:plan(1)
+
+-- Contains only IR_SLOAD after recording.
+local function sload(arg)
+ return arg
+end
+
+local tab_arg = {}
+
+-- Reset JIT, remove any other traces.
+jit.off()
+jit.flush()
+
+assert(not traceinfo(1), 'no traces compiled after flush')
+
+-- Try to executed compiled trace wiht IR_SLOAD, if emitted mcode