Commit f996d50d authored by Ng Zhi An's avatar Ng Zhi An Committed by Commit Bot

[wasm-simd] Fix lowering of load transform

Load transform nodes can be effect inputs, so we need to update the node
in place. Otherwise, if a load transform node is both an value and an
effect input, only the value input will be updated with replacements,
the effect input will still be the unlowered load transform node.
This is because DefaultLowering only lowers value inputs.

This is consistent with normal loads in the scalar lowering,
and also how int64 does it.

Bug: v8:10984,v8:10507
Change-Id: I04b0f0b1cff95e39589de979ecae6cb4b085a3cf
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2453861Reviewed-by: 's avatarBill Budge <bbudge@chromium.org>
Commit-Queue: Zhi An Ng <zhin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70391}
parent 3499b856
...@@ -617,39 +617,54 @@ void SimdScalarLowering::LowerLoadTransformOp(Node* node, SimdType type) { ...@@ -617,39 +617,54 @@ void SimdScalarLowering::LowerLoadTransformOp(Node* node, SimdType type) {
Node* base = node->InputAt(0); Node* base = node->InputAt(0);
Node* index = node->InputAt(1); Node* index = node->InputAt(1);
int num_lanes = NumLanes(type); int num_lanes = NumLanes(type);
Node** rep_nodes = zone()->NewArray<Node*>(num_lanes); Node** reps = zone()->NewArray<Node*>(num_lanes);
Node* effect_input = node->InputAt(2); Node* effect_input = node->InputAt(2);
Node* control_input = node->InputAt(3); Node* control_input = node->InputAt(3);
// This node is also used as effect input into other nodes, so we need to
// change this node in place.
reps[0] = node;
NodeProperties::ChangeOp(reps[0], load_op);
if (type != load_type) { if (type != load_type) {
// We load a smaller lane size, then extend to a larger lane size. So use // We load a smaller lane size, then extend to a larger lane size. So use
// the smaller lane size to calculte the index nodes for loads, but only // the smaller lane size to calculte the index nodes for loads, but only
// actually load half of those lanes. // actually load half of those lanes.
Node** indices = zone()->NewArray<Node*>(num_lanes * 2); Node** indices = zone()->NewArray<Node*>(num_lanes * 2);
GetIndexNodes(index, indices, load_type); GetIndexNodes(index, indices, load_type);
for (int i = num_lanes - 1; i >= 0; --i) {
rep_nodes[i] = graph()->NewNode(load_op, base, indices[i], effect_input,
control_input);
effect_input = rep_nodes[i];
// Load operations are Word32 nodes, change them to Word64. reps[0]->ReplaceInput(1, indices[0]);
if (params.transformation == LoadTransformation::kS128Load32x2S) {
rep_nodes[i] = for (int i = num_lanes - 1; i > 0; --i) {
graph()->NewNode(machine()->ChangeInt32ToInt64(), rep_nodes[i]); reps[i] = graph()->NewNode(load_op, base, indices[i], effect_input,
} else if (params.transformation == LoadTransformation::kS128Load32x2U) { control_input);
rep_nodes[i] = effect_input = reps[i];
graph()->NewNode(machine()->ChangeUint32ToUint64(), rep_nodes[i]);
}
} }
} else { } else {
// Load splat, load from the same index for every lane. // Load splat, load from the same index for every lane.
for (int i = num_lanes - 1; i >= 0; --i) { for (int i = num_lanes - 1; i > 0; --i) {
rep_nodes[i] = reps[i] =
graph()->NewNode(load_op, base, index, effect_input, control_input); graph()->NewNode(load_op, base, index, effect_input, control_input);
effect_input = rep_nodes[i]; effect_input = reps[i];
} }
} }
ReplaceNode(node, rep_nodes, num_lanes);
// Update the effect input, completing the effect chain.
reps[0]->ReplaceInput(2, reps[1]);
// Special case, the load nodes need to be sign extended, and we do it here so
// the loop above can connect all the effect edges correctly.
if (params.transformation == LoadTransformation::kS128Load32x2S) {
for (int i = 0; i < num_lanes; ++i) {
reps[i] = graph()->NewNode(machine()->ChangeInt32ToInt64(), reps[i]);
}
} else if (params.transformation == LoadTransformation::kS128Load32x2U) {
for (int i = 0; i < num_lanes; ++i) {
reps[i] = graph()->NewNode(machine()->ChangeUint32ToUint64(), reps[i]);
}
}
ReplaceNode(node, reps, num_lanes);
} }
void SimdScalarLowering::LowerStoreOp(Node* node) { void SimdScalarLowering::LowerStoreOp(Node* node) {
......
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