[wasm-simd][scalar-lowering] Fix signature with lowered Simd

Functions with Simd128 in their signature will be lowered to 4 Word32.
Later for Int64 lowering, it needs to use the lowered signature.
Otherwise we will have weird parameter and signature mismatch, since it
expects Parameter[1] to be == signature()->GetParam(0).

Bug: v8:10507
Change-Id: Ia9417ecd46c1768344ed1fb3ebfe4e8dd9c3e397
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2432626
Commit-Queue: Zhi An Ng <zhin@chromium.org>
Reviewed-by: Bill Budge <bbudge@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70185}
This commit is contained in:
Ng Zhi An 2020-09-28 16:34:51 -07:00 committed by Commit Bot
parent 78391a4450
commit c84b85cc30
3 changed files with 70 additions and 9 deletions

View File

@ -4365,15 +4365,17 @@ CallDescriptor* WasmGraphBuilder::GetI64AtomicWaitCallDescriptor() {
return i64_atomic_wait_descriptor_;
}
void WasmGraphBuilder::LowerInt64(CallOrigin origin) {
void WasmGraphBuilder::LowerInt64(Signature<MachineRepresentation>* sig) {
if (mcgraph()->machine()->Is64()) return;
Int64Lowering r(mcgraph()->graph(), mcgraph()->machine(), mcgraph()->common(),
mcgraph()->zone(),
CreateMachineSignature(mcgraph()->zone(), sig_, origin),
std::move(lowering_special_case_));
mcgraph()->zone(), sig, std::move(lowering_special_case_));
r.LowerGraph();
}
void WasmGraphBuilder::LowerInt64(CallOrigin origin) {
LowerInt64(CreateMachineSignature(mcgraph()->zone(), sig_, origin));
}
void WasmGraphBuilder::SimdScalarLoweringForTesting() {
SimdScalarLowering(mcgraph(), CreateMachineSignature(mcgraph()->zone(), sig_,
kCalledFromWasm))
@ -7580,15 +7582,47 @@ bool BuildGraphForWasmFunction(AccountingAllocator* allocator,
// Lower SIMD first, i64x2 nodes will be lowered to int64 nodes, then int64
// lowering will take care of them.
auto sig = CreateMachineSignature(mcgraph->zone(), func_body.sig,
WasmGraphBuilder::kCalledFromWasm);
if (builder.has_simd() &&
(!CpuFeatures::SupportsWasmSimd128() || env->lower_simd)) {
SimdScalarLowering(
mcgraph, CreateMachineSignature(mcgraph->zone(), func_body.sig,
WasmGraphBuilder::kCalledFromWasm))
.LowerGraph();
SimdScalarLowering(mcgraph, sig).LowerGraph();
// SimdScalarLowering changes all v128 to 4 i32, so update the machine
// signature for the call to LowerInt64.
size_t return_count = 0;
size_t param_count = 0;
for (auto ret : sig->returns()) {
return_count += ret == MachineRepresentation::kSimd128 ? 4 : 1;
}
for (auto param : sig->parameters()) {
param_count += param == MachineRepresentation::kSimd128 ? 4 : 1;
}
Signature<MachineRepresentation>::Builder sig_builder(
mcgraph->zone(), return_count, param_count);
for (auto ret : sig->returns()) {
if (ret == MachineRepresentation::kSimd128) {
for (int i = 0; i < 4; ++i) {
sig_builder.AddReturn(MachineRepresentation::kWord32);
}
} else {
sig_builder.AddReturn(ret);
}
}
for (auto param : sig->parameters()) {
if (param == MachineRepresentation::kSimd128) {
for (int i = 0; i < 4; ++i) {
sig_builder.AddParam(MachineRepresentation::kWord32);
}
} else {
sig_builder.AddParam(param);
}
}
sig = sig_builder.Build();
}
builder.LowerInt64(WasmWrapperGraphBuilder::kCalledFromWasm);
builder.LowerInt64(sig);
if (func_index >= FLAG_trace_wasm_ast_start &&
func_index < FLAG_trace_wasm_ast_end) {

View File

@ -361,6 +361,9 @@ class WasmGraphBuilder {
enum CallOrigin { kCalledFromWasm, kCalledFromJS };
// Overload for when we want to provide a specific signature, rather than
// build one using sig_, for example after scalar lowering.
V8_EXPORT_PRIVATE void LowerInt64(Signature<MachineRepresentation>* sig);
V8_EXPORT_PRIVATE void LowerInt64(CallOrigin origin);
V8_EXPORT_PRIVATE void SimdScalarLoweringForTesting();

View File

@ -249,6 +249,30 @@ WASM_SIMD_TEST(AnyTrue_DifferentShapes) {
}
}
WASM_SIMD_TEST(V128_I64_PARAMS) {
// This test exercises interaction between simd and int64 lowering. The
// parameter indices were not correctly lowered because simd lowered a v128 in
// the function signature into 4 word32, and int64 was still treating it as 1
// parameter.
WasmRunner<uint64_t, uint64_t> r(execution_tier, lower_simd);
FunctionSig::Builder builder(r.zone(), 1, 2);
builder.AddParam(kWasmS128);
builder.AddParam(kWasmI64);
builder.AddReturn(kWasmS128);
FunctionSig* sig = builder.Build();
WasmFunctionCompiler& fn = r.NewFunction(sig);
// Build a function that has both V128 and I64 arguments.
BUILD(fn,
WASM_SIMD_I64x2_REPLACE_LANE(0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
BUILD(r, WASM_SIMD_I64x2_EXTRACT_LANE(
0, WASM_SIMD_I64x2_SPLAT(WASM_GET_LOCAL(0))));
CHECK_EQ(0, r.Call(0));
}
} // namespace test_run_wasm_simd
} // namespace wasm
} // namespace internal