|
| 1 | +local tap = require('tap') |
| 2 | +-- Test file to demonstrate the incorrect JIT assembling of |
| 3 | +-- `IR_SLOAD` with typecheck and conversion to integer from |
| 4 | +-- number. |
| 5 | +-- See also https://github.com/LuaJIT/LuaJIT/issues/917. |
| 6 | +local test = tap.test('lj-917-arm64-sload-typecheck-conversion'):skipcond({ |
| 7 | + ['Test requires JIT enabled'] = not jit.status(), |
| 8 | +}) |
| 9 | + |
| 10 | +test:plan(1) |
| 11 | + |
| 12 | +jit.opt.start('hotloop=1') |
| 13 | + |
| 14 | +local results = {} |
| 15 | + |
| 16 | +-- Use the following mathematics on a huge number not fitting into |
| 17 | +-- an int to be sure that all 3 control numbers (start, stop, |
| 18 | +-- step) of the loop should be non-integers to avoid fallback to |
| 19 | +-- the `lj_vmeta_for()` and narrowing in the `lj_meta_for()` |
| 20 | +-- (see <src/vm_arm64.dasm> for details). |
| 21 | +local NOT_INT = 2 ^ 32 |
| 22 | + |
| 23 | +-- The interesting for us SLOAD is the loading of the start index: |
| 24 | +-- | 0006 x28 > int SLOAD #4 TCI |
| 25 | +-- |
| 26 | +-- Which results in the following mcode before the patch: |
| 27 | +-- | ldr x28, [x3, #16] |
| 28 | +-- | cmp x2, x28, lsr #32 |
| 29 | +-- | bls 0x62d2fda0 ->0 |
| 30 | +-- | ; here missing the move to d31 |
| 31 | +-- | fcvtzs w28, d31 |
| 32 | +-- | scvtf d30, w28 |
| 33 | +-- | fcmp d30, d31 |
| 34 | +-- | bne 0x62d2fda0 ->0 |
| 35 | +-- |
| 36 | +-- Instead of the expected: |
| 37 | +-- | ldr x28, [x3, #16] |
| 38 | +-- | cmp x2, x28, lsr #32 |
| 39 | +-- | bls 0x7bacfda0 ->0 |
| 40 | +-- | fmov d31, x28 |
| 41 | +-- | fcvtzs w28, d31 |
| 42 | +-- | scvtf d30, w28 |
| 43 | +-- | fcmp d30, d31 |
| 44 | +-- | bne 0x7bacfda0 ->0 |
| 45 | + |
| 46 | +-- At this moment d31 contains the value of the `step`, so `step` |
| 47 | +-- should be >= `stop` to obtain inconsistency (the too early loop |
| 48 | +-- end with the last `i` value equals to `step`). |
| 49 | +-- The resulting loop is: |
| 50 | +-- | for i = -4, -1, 1 do |
| 51 | +for i = -4 + NOT_INT * 0, -1 + NOT_INT * 0, 1 + NOT_INT * 0 do |
| 52 | + results[-i] = true |
| 53 | +end |
| 54 | + |
| 55 | +-- Expected {true, true, true, true}, since -4 is a start. |
| 56 | +test:samevalues(results, 'correct SLOAD TC assembling') |
| 57 | + |
| 58 | +test:done(true) |
0 commit comments