Commit bd7d425d authored by Deepti Gandluri's avatar Deepti Gandluri Committed by Commit Bot

[wasm] Fix Int64-lowering to handle non-const index for I64Atomic ops

Bug: chromium:925244
Change-Id: If9c00f85b1dece93057b541bf0fe1b0a05b81ceb
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1565032
Commit-Queue: Deepti Gandluri <gdeepti@chromium.org>
Reviewed-by: 's avatarBen Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60795}
parent b47449d5
......@@ -119,6 +119,7 @@ int GetReturnCountAfterLowering(Signature<MachineRepresentation>* signature) {
void Int64Lowering::LowerWord64AtomicBinop(Node* node, const Operator* op) {
DCHECK_EQ(5, node->InputCount());
LowerMemoryBaseAndIndex(node);
Node* value = node->InputAt(2);
node->ReplaceInput(2, GetReplacementLow(value));
node->InsertInput(zone(), 3, GetReplacementHigh(value));
......@@ -143,9 +144,6 @@ int Int64Lowering::GetParameterCountAfterLowering(
void Int64Lowering::GetIndexNodes(Node* index, Node*& index_low,
Node*& index_high) {
if (HasReplacementLow(index)) {
index = GetReplacementLow(index);
}
#if defined(V8_TARGET_LITTLE_ENDIAN)
index_low = index;
index_high = graph()->NewNode(machine()->Int32Add(), index,
......@@ -179,6 +177,7 @@ void Int64Lowering::LowerNode(Node* node) {
}
if (rep == MachineRepresentation::kWord64) {
LowerMemoryBaseAndIndex(node);
Node* base = node->InputAt(0);
Node* index = node->InputAt(1);
Node* index_low;
......@@ -228,6 +227,7 @@ void Int64Lowering::LowerNode(Node* node) {
// a new store node to store the high word. The effect and control edges
// are copied from the original store to the new store node, the effect
// edge of the original store is redirected to the new store.
LowerMemoryBaseAndIndex(node);
Node* base = node->InputAt(0);
Node* index = node->InputAt(1);
Node* index_low;
......@@ -900,6 +900,7 @@ void Int64Lowering::LowerNode(Node* node) {
DCHECK_EQ(5, node->InputCount());
MachineRepresentation rep = AtomicStoreRepresentationOf(node->op());
if (rep == MachineRepresentation::kWord64) {
LowerMemoryBaseAndIndex(node);
Node* value = node->InputAt(2);
node->ReplaceInput(2, GetReplacementLow(value));
node->InsertInput(zone(), 3, GetReplacementHigh(value));
......@@ -930,6 +931,7 @@ void Int64Lowering::LowerNode(Node* node) {
case IrOpcode::kWord64AtomicCompareExchange: {
MachineType type = AtomicOpType(node->op());
if (type == MachineType::Uint64()) {
LowerMemoryBaseAndIndex(node);
Node* old_value = node->InputAt(2);
Node* new_value = node->InputAt(3);
node->ReplaceInput(2, GetReplacementLow(old_value));
......@@ -1051,6 +1053,19 @@ void Int64Lowering::ReplaceNodeWithProjections(Node* node) {
ReplaceNode(node, low_node, high_node);
}
void Int64Lowering::LowerMemoryBaseAndIndex(Node* node) {
DCHECK(node != nullptr);
// Low word only replacements for memory operands for 32-bit address space.
Node* base = node->InputAt(0);
Node* index = node->InputAt(1);
if (HasReplacementLow(base)) {
node->ReplaceInput(0, GetReplacementLow(base));
}
if (HasReplacementLow(index)) {
node->ReplaceInput(1, GetReplacementLow(index));
}
}
} // namespace compiler
} // namespace internal
} // namespace v8
......@@ -61,6 +61,7 @@ class V8_EXPORT_PRIVATE Int64Lowering {
void PreparePhiReplacement(Node* phi);
void GetIndexNodes(Node* index, Node*& index_low, Node*& index_high);
void ReplaceNodeWithProjections(Node* node);
void LowerMemoryBaseAndIndex(Node* node);
struct NodeState {
Node* node;
......
......@@ -541,14 +541,23 @@ void RunNonConstIndexTest(ExecutionTier execution_tier, WasmOpcode wasm_op,
static_cast<uint32_t>(r.builder().ReadMemory(&memory[0])));
}
// Test a set of Narrow operations
#define TEST_OPERATION(Name) \
WASM_EXEC_TEST(I64AtomicConstIndex##Name) { \
WASM_EXEC_TEST(I64AtomicConstIndex##Name##Narrow) { \
RunNonConstIndexTest(execution_tier, kExprI64Atomic##Name##32U, Name); \
}
OPERATION_LIST(TEST_OPERATION)
#undef TEST_OPERATION
WASM_EXEC_TEST(I64AtomicNonConstIndexCompareExchange) {
// Test a set of Regular operations
#define TEST_OPERATION(Name) \
WASM_EXEC_TEST(I64AtomicConstIndex##Name) { \
RunNonConstIndexTest(execution_tier, kExprI64Atomic##Name, Name); \
}
OPERATION_LIST(TEST_OPERATION)
#undef TEST_OPERATION
WASM_EXEC_TEST(I64AtomicNonConstIndexCompareExchangeNarrow) {
EXPERIMENTAL_FLAG_SCOPE(threads);
WasmRunner<uint32_t, uint64_t, uint64_t> r(execution_tier);
uint64_t* memory =
......@@ -567,6 +576,25 @@ WASM_EXEC_TEST(I64AtomicNonConstIndexCompareExchange) {
static_cast<uint16_t>(r.builder().ReadMemory(&memory[0])));
}
WASM_EXEC_TEST(I64AtomicNonConstIndexCompareExchange) {
EXPERIMENTAL_FLAG_SCOPE(threads);
WasmRunner<uint32_t, uint64_t, uint64_t> r(execution_tier);
uint64_t* memory =
r.builder().AddMemoryElems<uint64_t>(kWasmPageSize / sizeof(uint64_t));
r.builder().SetHasSharedMemory();
BUILD(r, WASM_I32_CONVERT_I64(WASM_ATOMICS_TERNARY_OP(
kExprI64AtomicCompareExchange,
WASM_I64_EQ(WASM_I64V(1), WASM_I64V(0)), WASM_GET_LOCAL(0),
WASM_GET_LOCAL(1), MachineRepresentation::kWord16)));
uint64_t initial = 4444333322221111, local = 0x9999888877776666;
r.builder().WriteMemory(&memory[0], initial);
CHECK_EQ(static_cast<uint32_t>(initial), r.Call(initial, local));
CHECK_EQ(CompareExchange(initial, initial, local),
r.builder().ReadMemory(&memory[0]));
}
WASM_EXEC_TEST(I64AtomicNonConstIndexLoad8U) {
EXPERIMENTAL_FLAG_SCOPE(threads);
WasmRunner<uint32_t> r(execution_tier);
......
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