Skip to content

Commit

Permalink
wazevo: fuzz, fix load_splat with offset values > 12 bits (#1817)
Browse files Browse the repository at this point in the history
Signed-off-by: Edoardo Vacchi <evacchi@users.noreply.github.com>
  • Loading branch information
evacchi authored Oct 25, 2023
1 parent e3e5b99 commit a5d1b12
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 14 deletions.
13 changes: 10 additions & 3 deletions internal/engine/wazevo/backend/isa/arm64/lower_mem.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,11 +245,11 @@ func (m *machine) lowerLoadSplat(ptr ssa.Value, offset uint32, lane ssa.VecLane,
}
amode := m.lowerToAddressMode(ptr, offset, opSize)
rd := operandNR(m.compiler.VRegOf(ret))
m.lowerLoadSplatFromAddressMode(rd, amode, lane)
m.lowerLoadSplatFromAddressMode(rd, amode, opSize, lane)
}

// lowerLoadSplatFromAddressMode is extracted from lowerLoadSplat for testing.
func (m *machine) lowerLoadSplatFromAddressMode(rd operand, amode addressMode, lane ssa.VecLane) {
func (m *machine) lowerLoadSplatFromAddressMode(rd operand, amode addressMode, opSize byte, lane ssa.VecLane) {
tmpReg := operandNR(m.compiler.AllocateVReg(ssa.TypeI64))

// vecLoad1R has offset address mode (base+imm) only for post index, so the only addressing mode
Expand All @@ -259,10 +259,17 @@ func (m *machine) lowerLoadSplatFromAddressMode(rd operand, amode addressMode, l
add := m.allocateInstr()
add.asALU(aluOpAdd, tmpReg, operandNR(amode.rn), operandNR(amode.rm), true)
m.insert(add)
case addressModeKindRegSignedImm9, addressModeKindRegUnsignedImm12:
case addressModeKindRegSignedImm9:
add := m.allocateInstr()
add.asALU(aluOpAdd, tmpReg, operandNR(amode.rn), operandImm12(uint16(amode.imm), 0), true)
m.insert(add)
case addressModeKindRegUnsignedImm12:
offsetReg := operandNR(m.compiler.AllocateVReg(ssa.TypeI64))
m.load64bitConst(amode.imm, offsetReg.nr())

add := m.allocateInstr()
m.insert(add)
add.asALU(aluOpAdd, tmpReg, operandNR(amode.rn), offsetReg, true)
default:
panic("unsupported address mode for LoadSplat")
}
Expand Down
16 changes: 5 additions & 11 deletions internal/engine/wazevo/backend/isa/arm64/lower_mem_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -866,16 +866,10 @@ ld1r {x10.4s}, [x100?]
`,
},
{
amode: addressMode{kind: addressModeKindRegUnsignedImm12, rn: v0VReg, imm: 42},
amode: addressMode{kind: addressModeKindRegUnsignedImm12, rn: v0VReg, imm: 15616},
expected: `
add x100?, d0, #0x2a
ld1r {x10.4s}, [x100?]
`,
},
{
amode: addressMode{kind: addressModeKindRegSignedImm9, rn: v0VReg, imm: 42},
expected: `
add x100?, d0, #0x2a
movz x101?, #0x3d00, lsl 0
add x100?, d0, x101?
ld1r {x10.4s}, [x100?]
`,
},
Expand All @@ -893,7 +887,7 @@ ld1r {x10.4s}, [x100?]
ctx.vRegCounter = int(nextVReg.ID()) - 1
positiveTests[tc.amode.kind] = true

m.lowerLoadSplatFromAddressMode(operandNR(x10VReg), tc.amode, ssa.VecLaneI32x4)
m.lowerLoadSplatFromAddressMode(operandNR(x10VReg), tc.amode, 32, ssa.VecLaneI32x4)
require.Equal(t, tc.expected, "\n"+formatEmittedInstructionsInCurrentBlock(m)+"\n")
})
}
Expand All @@ -910,7 +904,7 @@ ld1r {x10.4s}, [x100?]

t.Run("address mode "+strconv.Itoa(k), func(t *testing.T) {
err := require.CapturePanic(func() {
m.lowerLoadSplatFromAddressMode(operandNR(x10VReg), addressMode{kind: amk}, ssa.VecLaneI32x4)
m.lowerLoadSplatFromAddressMode(operandNR(x10VReg), addressMode{kind: amk}, 32, ssa.VecLaneI32x4)
})
require.Contains(t, err.Error(), "unsupported address mode for LoadSplat")
})
Expand Down
19 changes: 19 additions & 0 deletions internal/integration_test/fuzzcases/fuzzcases_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -647,3 +647,22 @@ func Test1812(t *testing.T) {
}, res)
})
}

// Test1817 tests that v128.store uses the right memory layout.
func Test1817(t *testing.T) {
if !platform.CompilerSupported() {
return
}
run(t, func(t *testing.T, r wazero.Runtime) {
mod, err := r.Instantiate(ctx, getWasmBinary(t, "1817"))
require.NoError(t, err)
m := mod.(*wasm.ModuleInstance)
_, err = m.ExportedFunction("").Call(ctx)
require.NoError(t, err)
buf, ok := m.Memory().Read(15616, 16)
require.True(t, ok)
require.Equal(t, []uint8{0, 0, 0, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, buf)
require.Equal(t, uint64(0x8000000080000000), m.Globals[0].Val)
require.Equal(t, uint64(0x8000000080000000), m.Globals[0].ValHi)
})
}
Binary file not shown.
13 changes: 13 additions & 0 deletions internal/integration_test/fuzzcases/testdata/1817.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
(module
(memory (;0;) 1 1)
(func (;0;)
i32.const 0
v128.const i32x4 0x80000000 0x80000000 0x80000000 0x80000000
v128.store32_lane offset=15616 align=2 1
i32.const 0
v128.load32_splat offset=15616 align=2
global.set 0
)
(global (;0;) (mut v128) v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
(export "" (func 0))
)

0 comments on commit a5d1b12

Please sign in to comment.