Commit 3b55a6c8 authored by Milad Farazmand's avatar Milad Farazmand Committed by Commit Bot

[wasm-simd] Fix LoadTransform on BE architectures

LoadTransform cannot efficiently be executed on BE machines as a
single operation since loaded bytes need to be reversed to
match BE ordering before any operations can take place.

This CL divides LoadTransform into separate "load" and "operation"
nodes on BE machines.

Change-Id: Idc3f66d7f17647c189c75593e8906f8645448006
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2050811
Commit-Queue: Milad Farazmand <miladfar@ca.ibm.com>
Reviewed-by: 's avatarZhi An Ng <zhin@chromium.org>
Reviewed-by: 's avatarDeepti Gandluri <gdeepti@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66264}
parent e09484d4
...@@ -3742,7 +3742,38 @@ LoadKind GetLoadKind(MachineGraph* mcgraph, MachineType memtype, ...@@ -3742,7 +3742,38 @@ LoadKind GetLoadKind(MachineGraph* mcgraph, MachineType memtype,
} }
} // namespace } // namespace
Node* WasmGraphBuilder::LoadTransform(MachineType memtype, #if defined(V8_TARGET_BIG_ENDIAN)
Node* WasmGraphBuilder::LoadTransformBigEndian(
MachineType memtype, wasm::LoadTransformationKind transform, Node* value) {
Node* result;
LoadTransformation transformation = GetLoadTransformation(memtype, transform);
switch (transformation) {
case LoadTransformation::kS8x16LoadSplat: {
result = graph()->NewNode(mcgraph()->machine()->I8x16Splat(), value);
break;
}
case LoadTransformation::kS16x8LoadSplat: {
result = graph()->NewNode(mcgraph()->machine()->I16x8Splat(), value);
break;
}
case LoadTransformation::kS32x4LoadSplat: {
result = graph()->NewNode(mcgraph()->machine()->I32x4Splat(), value);
break;
}
case LoadTransformation::kS64x2LoadSplat: {
result = graph()->NewNode(mcgraph()->machine()->I64x2Splat(), value);
break;
}
default:
UNREACHABLE();
}
return result;
}
#endif
Node* WasmGraphBuilder::LoadTransform(wasm::ValueType type, MachineType memtype,
wasm::LoadTransformationKind transform, wasm::LoadTransformationKind transform,
Node* index, uint32_t offset, Node* index, uint32_t offset,
uint32_t alignment, uint32_t alignment,
...@@ -3751,6 +3782,16 @@ Node* WasmGraphBuilder::LoadTransform(MachineType memtype, ...@@ -3751,6 +3782,16 @@ Node* WasmGraphBuilder::LoadTransform(MachineType memtype,
has_simd_ = true; has_simd_ = true;
} }
Node* load;
#if defined(V8_TARGET_BIG_ENDIAN)
// LoadTransform cannot efficiently be executed on BE machines as a
// single operation since loaded bytes need to be reversed first,
// therefore we divide them into separate "load" and "operation" nodes.
load = LoadMem(type, memtype, index, offset, alignment, position);
load = LoadTransformBigEndian(memtype, transform, load);
USE(GetLoadKind);
#else
// Wasm semantics throw on OOB. Introduce explicit bounds check and // Wasm semantics throw on OOB. Introduce explicit bounds check and
// conditioning when not using the trap handler. // conditioning when not using the trap handler.
index = BoundsCheckMem(wasm::ValueTypes::MemSize(memtype), index, offset, index = BoundsCheckMem(wasm::ValueTypes::MemSize(memtype), index, offset,
...@@ -3759,16 +3800,13 @@ Node* WasmGraphBuilder::LoadTransform(MachineType memtype, ...@@ -3759,16 +3800,13 @@ Node* WasmGraphBuilder::LoadTransform(MachineType memtype,
LoadTransformation transformation = GetLoadTransformation(memtype, transform); LoadTransformation transformation = GetLoadTransformation(memtype, transform);
LoadKind load_kind = GetLoadKind(mcgraph(), memtype, use_trap_handler()); LoadKind load_kind = GetLoadKind(mcgraph(), memtype, use_trap_handler());
Node* load = SetEffect(graph()->NewNode( load = SetEffect(graph()->NewNode(
mcgraph()->machine()->LoadTransform(load_kind, transformation), mcgraph()->machine()->LoadTransform(load_kind, transformation),
MemBuffer(offset), index, effect(), control())); MemBuffer(offset), index, effect(), control()));
if (load_kind == LoadKind::kProtected) { if (load_kind == LoadKind::kProtected) {
SetSourcePosition(load, position); SetSourcePosition(load, position);
} }
#if defined(V8_TARGET_BIG_ENDIAN)
load = BuildChangeEndiannessLoad(load, memtype, wasm::ValueType::kWasmS128);
#endif #endif
if (FLAG_trace_wasm_memory) { if (FLAG_trace_wasm_memory) {
......
...@@ -283,7 +283,12 @@ class WasmGraphBuilder { ...@@ -283,7 +283,12 @@ class WasmGraphBuilder {
Node* LoadMem(wasm::ValueType type, MachineType memtype, Node* index, Node* LoadMem(wasm::ValueType type, MachineType memtype, Node* index,
uint32_t offset, uint32_t alignment, uint32_t offset, uint32_t alignment,
wasm::WasmCodePosition position); wasm::WasmCodePosition position);
Node* LoadTransform(MachineType memtype, #if defined(V8_TARGET_BIG_ENDIAN)
Node* LoadTransformBigEndian(MachineType memtype,
wasm::LoadTransformationKind transform,
Node* value);
#endif
Node* LoadTransform(wasm::ValueType type, MachineType memtype,
wasm::LoadTransformationKind transform, Node* index, wasm::LoadTransformationKind transform, Node* index,
uint32_t offset, uint32_t alignment, uint32_t offset, uint32_t alignment,
wasm::WasmCodePosition position); wasm::WasmCodePosition position);
......
...@@ -397,8 +397,9 @@ class WasmGraphBuildingInterface { ...@@ -397,8 +397,9 @@ class WasmGraphBuildingInterface {
LoadTransformationKind transform, LoadTransformationKind transform,
const MemoryAccessImmediate<validate>& imm, const MemoryAccessImmediate<validate>& imm,
const Value& index, Value* result) { const Value& index, Value* result) {
result->node = BUILD(LoadTransform, type.mem_type(), transform, index.node, result->node =
imm.offset, imm.alignment, decoder->position()); BUILD(LoadTransform, type.value_type(), type.mem_type(), transform,
index.node, imm.offset, imm.alignment, decoder->position());
} }
void StoreMem(FullDecoder* decoder, StoreType type, void StoreMem(FullDecoder* decoder, StoreType type,
......
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