[Tarantool-patches] [PATCH luajit v4 4/4] Fix IR_RENAME snapshot number. Follow-up fix for a32aeadc.
Maksim Kokryashkin
max.kokryashkin at gmail.com
Mon May 15 12:16:22 MSK 2023
From: Mike Pall <mike>
Reported by Victor Bombi, analyzed by XmiliaH. Thanks!
(cherry-picked from commit bf51d3535109c4745bfbbe19a5587a9eac00259a)
If the `snapalloc` flag is set, then the allocation has not
occurred yet, meaning that rename is applied to the next
snapshot. Otherwise, refs are already allocated and rename
is applied to the current snapshot.
Maxim Kokryashkin:
* added the description and the test for the problem
Part of tarantool/tarantool#7745
Part of tarantool/tarantool#8069
---
src/lj_asm.c | 9 ++-
.../lj-688-snap-ir-rename.test.lua | 60 +++++++++++++++++++
2 files changed, 68 insertions(+), 1 deletion(-)
create mode 100644 test/tarantool-tests/lj-688-snap-ir-rename.test.lua
diff --git a/src/lj_asm.c b/src/lj_asm.c
index f7c40fea..9bbfb2bf 100644
--- a/src/lj_asm.c
+++ b/src/lj_asm.c
@@ -682,7 +682,14 @@ static void ra_rename(ASMState *as, Reg down, Reg up)
RA_DBGX((as, "rename $f $r $r", regcost_ref(as->cost[up]), down, up));
emit_movrr(as, ir, down, up); /* Backwards codegen needs inverse move. */
if (!ra_hasspill(IR(ref)->s)) { /* Add the rename to the IR. */
- ra_addrename(as, down, ref, as->snapno);
+ /*
+ ** The rename is effective at the subsequent (already emitted) exit
+ ** branch. This is for the current snapshot (as->snapno). Except if we
+ ** haven't yet allocated any refs for the snapshot (as->snapalloc == 1),
+ ** then it belongs to the next snapshot.
+ ** See also the discussion at asm_snap_checkrename().
+ */
+ ra_addrename(as, down, ref, as->snapno + as->snapalloc);
}
}
diff --git a/test/tarantool-tests/lj-688-snap-ir-rename.test.lua b/test/tarantool-tests/lj-688-snap-ir-rename.test.lua
new file mode 100644
index 00000000..f626cfb6
--- /dev/null
+++ b/test/tarantool-tests/lj-688-snap-ir-rename.test.lua
@@ -0,0 +1,60 @@
+local tap = require('tap')
+local test = tap.test('lj-688-snap-ir-rename'):skipcond({
+ ['Test requires JIT enabled'] = not jit.status(),
+})
+test:plan(1)
+
+jit.opt.start('hotloop=1')
+
+-- IR for the loop below looks like the following
+-- before the patch:
+--
+-- 0021 ------------ LOOP ------------
+-- .... SNAP #6 [ ---- ---- 0019 false 0007 ]
+-- 0022 > num NE 0019 +1.1
+-- .... SNAP #7 [ ---- ---- 0019 false 0007 ]
+-- 0023 rbp > int CONV 0019 int.num
+-- 0024 > int ABC 0013 0023
+-- 0025 p32 AREF 0015 0023
+-- 0026 xmm6 > num ALOAD 0025
+-- .... SNAP #8 [ ---- ---- 0019 false ---- ]
+-- 0027 > num ULE 0026 +0
+-- 0028 xmm7 + num ADD 0019 +1
+-- .... SNAP #9 [ ---- ---- 0019 false ]
+-- 0029 > num LT 0028 +5
+-- 0030 xmm7 num PHI 0019 0028
+-- 0031 xmm6 nil RENAME 0019 #8
+-- ---- TRACE 1 stop -> loop
+--
+-- RENAME instruction is applied to the 8th snapshot, when it
+-- should be applied to the 9th. After the patch that line looks
+-- the following way:
+--
+-- 0031 xmm6 nil RENAME 0019 #9
+
+-- XXX: Note, that reproducer below won't fail on ARM/ARM64
+-- even before the patch, because `IR_RENAME` is not emitted
+-- for any of the instructions produced.
+-- Although it is possible to achieve the same faulty behavior
+-- before the patch on ARM/ARM64, it requires a more complex
+-- reproducer. Since the code affected by the patch is
+-- platform-agnostic, there is no real necessity to test it
+-- against ARM/ARM64 separately.
+--
+-- See also https://drive.google.com/file/d/1iYkFx3F0DOtB9o9ykWfCEm-OdlJNCCL0/view?usp=share_link
+
+
+local vals = {-0.1, 0.1, -0.1, 0.1}
+local i = 1
+local _
+while i < 5 do
+ assert(i ~= 1.1)
+ local l1 = vals[i]
+ _ = l1 > 0
+ i = i + 1
+end
+
+test:ok(true, 'IR_RENAME is fine')
+-- `test:check() and 0 or 1` is replaced with just test:check()
+-- here, because otherwise, it affects the renaming process.
+os.exit(test:check())
--
2.39.2 (Apple Git-143)
More information about the Tarantool-patches
mailing list