Commit 8628ec4d authored by Clemens Backes's avatar Clemens Backes Committed by V8 LUCI CQ

[liftoff] Fix SIMD stack moves

Moves between stack slots are rare; they mostly happen for tail calls
or for multi-return blocks. The bug exists since a long time, but was
only uncovered by the fuzzer now.

R=ahaas@chromium.org

Bug: chromium:1289678
Change-Id: Ibb0917717c6b7a468f5fcbb01be34267ba06a449
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3406749Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78736}
parent 8cefcc4c
......@@ -1160,17 +1160,15 @@ void LiftoffAssembler::StoreCallerFrameSlot(LiftoffRegister src,
void LiftoffAssembler::MoveStackValue(uint32_t dst_offset, uint32_t src_offset,
ValueKind kind) {
if (needs_gp_reg_pair(kind)) {
liftoff::MoveStackValue(this,
liftoff::GetHalfStackSlot(src_offset, kLowWord),
liftoff::GetHalfStackSlot(dst_offset, kLowWord));
liftoff::MoveStackValue(this,
liftoff::GetHalfStackSlot(src_offset, kHighWord),
liftoff::GetHalfStackSlot(dst_offset, kHighWord));
} else {
DCHECK_EQ(0, element_size_bytes(kind) % kSystemPointerSize);
int words = element_size_bytes(kind) / kSystemPointerSize;
DCHECK_LE(1, words);
do {
liftoff::MoveStackValue(this, liftoff::GetStackSlot(src_offset),
liftoff::GetStackSlot(dst_offset));
}
dst_offset -= kSystemPointerSize;
src_offset -= kSystemPointerSize;
} while (--words);
}
void LiftoffAssembler::Move(Register dst, Register src, ValueKind kind) {
......
......@@ -875,13 +875,21 @@ void LiftoffAssembler::MoveStackValue(uint32_t dst_offset, uint32_t src_offset,
DCHECK_NE(dst_offset, src_offset);
Operand dst = liftoff::GetStackSlot(dst_offset);
Operand src = liftoff::GetStackSlot(src_offset);
if (element_size_log2(kind) == 2) {
movl(kScratchRegister, src);
movl(dst, kScratchRegister);
} else {
DCHECK_EQ(3, element_size_log2(kind));
movq(kScratchRegister, src);
movq(dst, kScratchRegister);
switch (element_size_log2(kind)) {
case 2:
movl(kScratchRegister, src);
movl(dst, kScratchRegister);
break;
case 3:
movq(kScratchRegister, src);
movq(dst, kScratchRegister);
break;
case 4:
Movdqu(kScratchDoubleReg, src);
Movdqu(dst, kScratchDoubleReg);
break;
default:
UNREACHABLE();
}
}
......
......@@ -1548,6 +1548,7 @@
'regress/wasm/regress-1284980': [SKIP],
'regress/wasm/regress-1286253': [SKIP],
'regress/wasm/regress-1283395': [SKIP],
'regress/wasm/regress-1289678': [SKIP],
}], # no_simd_hardware == True
##############################################################################
......
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
const builder = new WasmModuleBuilder();
builder.addType(makeSig([], [kWasmS128, kWasmF64, kWasmS128, kWasmF64, kWasmF64, kWasmF32, kWasmF64, kWasmS128, kWasmF32]));
builder.addFunction('foo', kSig_v_v)
.addBody([
kExprBlock, /* sig */ 0, // block
kExprF64Const, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // f64.const
kExprI32Const, 0x00, // i32.const
kSimdPrefix, kExprI8x16Splat, // i8x16.splat
kExprF64Const, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // f64.const
kExprI32Const, 0x00, // i32.const
kSimdPrefix, kExprI8x16Splat, // i8x16.splat
kExprF64Const, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // f64.const
kExprF64Const, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // f64.const
kExprF32Const, 0x00, 0x00, 0x00, 0x00, // f32.const
kExprF64Const, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // f64.const
kExprI32Const, 0x00, // i32.const
kSimdPrefix, kExprI8x16Splat, // i8x16.splat
kExprF32Const, 0x00, 0x00, 0x00, 0x00, // f32.const
kExprBr, 0, // br depth=0
kExprUnreachable, // unreachable
kExprEnd, // end
kExprUnreachable, // unreachable
]);
builder.toModule();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment