Commit 76debfda authored by Ng Zhi An's avatar Ng Zhi An Committed by Commit Bot

[wasm-simd][liftoff] Fix I64x2Mul

The I64x2Mul overwrote the lhs/rhs if they are the same as dst. So when
deciding if we need temporaries, we should not only check the
cache_state, but whether they alias dst or not.

Bug: chromium:1088273
Change-Id: I82efa9b45e0a3d321a06efde60971ce95b21490f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2225796
Commit-Queue: Zhi An Ng <zhin@chromium.org>
Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68114}
parent 6dca4f96
......@@ -2500,15 +2500,18 @@ void LiftoffAssembler::emit_i64x2_mul(LiftoffRegister dst, LiftoffRegister lhs,
QwNeonRegister tmp1 = left;
QwNeonRegister tmp2 = right;
if (cache_state()->is_used(lhs) && cache_state()->is_used(rhs)) {
LiftoffRegList used_plus_dst =
cache_state()->used_registers | LiftoffRegList::ForRegs(dst);
if (used_plus_dst.has(lhs) && used_plus_dst.has(rhs)) {
tmp1 = temps.AcquireQ();
// We only have 1 scratch Q register, so acquire another ourselves.
LiftoffRegList pinned = LiftoffRegList::ForRegs(dst);
LiftoffRegister unused_pair = GetUnusedRegister(kFpRegPair, pinned);
tmp2 = liftoff::GetSimd128Register(unused_pair);
} else if (cache_state()->is_used(lhs)) {
} else if (used_plus_dst.has(lhs)) {
tmp1 = temps.AcquireQ();
} else if (cache_state()->is_used(rhs)) {
} else if (used_plus_dst.has(rhs)) {
tmp2 = temps.AcquireQ();
}
......
// Copyright 2020 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.
// This test exercises the I64x2Mul logic in Liftoff, hence the flags.
// Flags: --wasm-staging --experimental-wasm-simd --liftoff --no-wasm-tier-up
load('test/mjsunit/wasm/wasm-module-builder.js');
const builder = new WasmModuleBuilder();
builder.addMemory(16, 32, false, true);
builder.addGlobal(kWasmI32, 0);
builder.addType(makeSig([kWasmI32, kWasmI32, kWasmI32], [kWasmI32]));
builder.addType(makeSig([], []));
// Generate function 1 (out of 3).
builder.addFunction(undefined, 0 /* sig */)
.addLocals({f32_count: 10})
.addBodyWithEnd([
// signature: i_iii
// body:
kExprI32Const, 0x80, 0x01, // i32.const
kSimdPrefix, kExprI8x16Splat, // i8x16.splat
kExprI32Const, 0x92, 0x01, // i32.const
kSimdPrefix, kExprI8x16Splat, // i8x16.splat
kSimdPrefix, kExprI64x2Mul, 0x01, // i64x2.mul
kSimdPrefix, kExprI16x8ExtractLaneU, 0x00, // i16x8.extract_lane_u
kExprEnd, // end @19
]);
builder.addExport('main', 0);
const instance = builder.instantiate();
assertEquals(instance.exports.main(1, 2, 3), 18688);
......@@ -474,6 +474,7 @@ let kExprI8x16Splat = 0x0f;
let kExprI16x8Splat = 0x10;
let kExprI32x4Splat = 0x11;
let kExprF32x4Splat = 0x13;
let kExprI16x8ExtractLaneU = 0x19;
let kExprI8x16LtU = 0x26;
let kExprI8x16LeU = 0x2a;
let kExprI32x4Eq = 0x37;
......@@ -482,6 +483,7 @@ let kExprV8x16AllTrue = 0x63;
let kExprI8x16Add = 0x6e;
let kExprI16x8ShrS = [0x8c, 01];
let kExprV32x4AnyTrue = 0xa2;
let kExprI64x2Mul = 0xd5;
let kExprF32x4Min = 0xe8;
// Compilation hint constants.
......
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