Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions src/binaryen-c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1382,15 +1382,15 @@ BinaryenExpressionRef BinaryenAtomicRMW(BinaryenModuleRef module,
BinaryenExpressionRef value,
BinaryenType type,
const char* memoryName) {
return static_cast<Expression*>(
Builder(*(Module*)module)
.makeAtomicRMW(AtomicRMWOp(op),
bytes,
offset,
(Expression*)ptr,
(Expression*)value,
Type(type),
getMemoryName(module, memoryName)));
return Builder(*(Module*)module)
.makeAtomicRMW(AtomicRMWOp(op),
bytes,
offset,
(Expression*)ptr,
(Expression*)value,
Type(type),
getMemoryName(module, memoryName),
MemoryOrder::SeqCst);
}
BinaryenExpressionRef BinaryenAtomicCmpxchg(BinaryenModuleRef module,
BinaryenIndex bytes,
Expand Down
7 changes: 5 additions & 2 deletions src/ir/properties.h
Original file line number Diff line number Diff line change
Expand Up @@ -507,8 +507,11 @@ inline MemoryOrder getMemoryOrder(Expression* curr) {
if (auto* store = curr->dynCast<Store>()) {
return store->order;
}
if (curr->is<AtomicRMW>() || curr->is<AtomicWait>() ||
curr->is<AtomicNotify>() || curr->is<AtomicFence>()) {
if (auto* rmw = curr->dynCast<AtomicRMW>()) {
return rmw->order;
}
if (curr->is<AtomicWait>() || curr->is<AtomicNotify>() ||
curr->is<AtomicFence>()) {
return MemoryOrder::SeqCst;
}
return MemoryOrder::Unordered;
Expand Down
10 changes: 6 additions & 4 deletions src/parser/contexts.h
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,8 @@ struct NullInstrParserCtx {
Type,
int,
MemoryIdxT*,
MemargT) {
MemargT,
MemoryOrder) {
return Ok{};
}
Result<> makeAtomicCmpxchg(
Expand Down Expand Up @@ -2274,11 +2275,12 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx>, AnnotationParserCtx {
Type type,
int bytes,
Name* mem,
Memarg memarg) {
Memarg memarg,
MemoryOrder order) {
auto m = getMemory(pos, mem);
CHECK_ERR(m);
return withLoc(pos,
irBuilder.makeAtomicRMW(op, bytes, memarg.offset, type, *m));
return withLoc(
pos, irBuilder.makeAtomicRMW(op, bytes, memarg.offset, type, *m, order));
}

Result<> makeAtomicCmpxchg(Index pos,
Expand Down
14 changes: 12 additions & 2 deletions src/parser/parsers.h
Original file line number Diff line number Diff line change
Expand Up @@ -1815,10 +1815,20 @@ Result<> makeAtomicRMW(Ctx& ctx,
uint8_t bytes) {
auto mem = maybeMemidx(ctx);
CHECK_ERR(mem);

auto maybeOrder = maybeMemOrder(ctx);
CHECK_ERR(maybeOrder);

auto arg = memarg(ctx, bytes);
CHECK_ERR(arg);
return ctx.makeAtomicRMW(
pos, annotations, op, type, bytes, mem.getPtr(), *arg);
return ctx.makeAtomicRMW(pos,
annotations,
op,
type,
bytes,
mem.getPtr(),
*arg,
maybeOrder ? *maybeOrder : MemoryOrder::SeqCst);
}

template<typename Ctx>
Expand Down
1 change: 1 addition & 0 deletions src/passes/Print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,7 @@ struct PrintExpressionContents
}
restoreNormalColor(o);
printMemoryName(curr->memory, o, wasm);
printMemoryOrder(curr->order);
if (curr->offset) {
o << " offset=" << curr->offset;
}
Expand Down
3 changes: 2 additions & 1 deletion src/tools/fuzzing/fuzzing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4770,7 +4770,8 @@ Expression* TranslateToFuzzReader::makeAtomic(Type type) {
ptr,
value,
type,
wasm.memories[0]->name);
wasm.memories[0]->name,
MemoryOrder::SeqCst);
} else {
auto* expected = make(type);
auto* replacement = make(type);
Expand Down
6 changes: 4 additions & 2 deletions src/wasm-builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -466,16 +466,18 @@ class Builder {
Expression* ptr,
Expression* value,
Type type,
Name memory) {
Name memory,
MemoryOrder order) {
auto* ret = wasm.allocator.alloc<AtomicRMW>();
ret->op = op;
ret->bytes = bytes;
ret->offset = offset;
ret->ptr = ptr;
ret->value = value;
ret->type = type;
ret->finalize();
ret->memory = memory;
ret->order = order;
ret->finalize();
return ret;
}
AtomicCmpxchg* makeAtomicCmpxchg(unsigned bytes,
Expand Down
1 change: 1 addition & 0 deletions src/wasm-delegations-fields.def
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,7 @@ DELEGATE_FIELD_CHILD(AtomicRMW, ptr)
DELEGATE_FIELD_INT(AtomicRMW, op)
DELEGATE_FIELD_INT(AtomicRMW, bytes)
DELEGATE_FIELD_ADDRESS(AtomicRMW, offset)
DELEGATE_FIELD_INT(AtomicRMW, order)
DELEGATE_FIELD_NAME_KIND(AtomicRMW, memory, ModuleItemKind::Memory)
DELEGATE_FIELD_CASE_END(AtomicRMW)

Expand Down
8 changes: 6 additions & 2 deletions src/wasm-ir-builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,12 @@ class IRBuilder : public UnifiedExpressionVisitor<IRBuilder, Result<>> {
unsigned bytes, Address offset, Type type, Name mem, MemoryOrder order);
Result<> makeAtomicStore(
unsigned bytes, Address offset, Type type, Name mem, MemoryOrder order);
Result<> makeAtomicRMW(
AtomicRMWOp op, unsigned bytes, Address offset, Type type, Name mem);
Result<> makeAtomicRMW(AtomicRMWOp op,
unsigned bytes,
Address offset,
Type type,
Name mem,
MemoryOrder order);
Result<>
makeAtomicCmpxchg(unsigned bytes, Address offset, Type type, Name mem);
Result<> makeAtomicWait(Type type, Address offset, Name mem);
Expand Down
1 change: 1 addition & 0 deletions src/wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -1035,6 +1035,7 @@ class AtomicRMW : public SpecificExpression<Expression::AtomicRMWId> {
Expression* ptr;
Expression* value;
Name memory;
MemoryOrder order = MemoryOrder::SeqCst;

void finalize();
};
Expand Down
21 changes: 14 additions & 7 deletions src/wasm/wasm-binary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3704,31 +3704,38 @@ Result<> WasmBinaryReader::readInst() {
#define RMW(op) \
case BinaryConsts::I32AtomicRMW##op: { \
auto [mem, align, offset, memoryOrder] = getRMWMemarg(); \
return builder.makeAtomicRMW(RMW##op, 4, offset, Type::i32, mem); \
return builder.makeAtomicRMW( \
RMW##op, 4, offset, Type::i32, mem, memoryOrder); \
} \
case BinaryConsts::I32AtomicRMW##op##8U: { \
auto [mem, align, offset, memoryOrder] = getRMWMemarg(); \
return builder.makeAtomicRMW(RMW##op, 1, offset, Type::i32, mem); \
return builder.makeAtomicRMW( \
RMW##op, 1, offset, Type::i32, mem, memoryOrder); \
} \
case BinaryConsts::I32AtomicRMW##op##16U: { \
auto [mem, align, offset, memoryOrder] = getRMWMemarg(); \
return builder.makeAtomicRMW(RMW##op, 2, offset, Type::i32, mem); \
return builder.makeAtomicRMW( \
RMW##op, 2, offset, Type::i32, mem, memoryOrder); \
} \
case BinaryConsts::I64AtomicRMW##op: { \
auto [mem, align, offset, memoryOrder] = getRMWMemarg(); \
return builder.makeAtomicRMW(RMW##op, 8, offset, Type::i64, mem); \
return builder.makeAtomicRMW( \
RMW##op, 8, offset, Type::i64, mem, memoryOrder); \
} \
case BinaryConsts::I64AtomicRMW##op##8U: { \
auto [mem, align, offset, memoryOrder] = getRMWMemarg(); \
return builder.makeAtomicRMW(RMW##op, 1, offset, Type::i64, mem); \
return builder.makeAtomicRMW( \
RMW##op, 1, offset, Type::i64, mem, memoryOrder); \
} \
case BinaryConsts::I64AtomicRMW##op##16U: { \
auto [mem, align, offset, memoryOrder] = getRMWMemarg(); \
return builder.makeAtomicRMW(RMW##op, 2, offset, Type::i64, mem); \
return builder.makeAtomicRMW( \
RMW##op, 2, offset, Type::i64, mem, memoryOrder); \
} \
case BinaryConsts::I64AtomicRMW##op##32U: { \
auto [mem, align, offset, memoryOrder] = getRMWMemarg(); \
return builder.makeAtomicRMW(RMW##op, 4, offset, Type::i64, mem); \
return builder.makeAtomicRMW( \
RMW##op, 4, offset, Type::i64, mem, memoryOrder); \
}

RMW(Add);
Expand Down
12 changes: 8 additions & 4 deletions src/wasm/wasm-ir-builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1503,14 +1503,18 @@ Result<> IRBuilder::makeAtomicStore(
return Ok{};
}

Result<> IRBuilder::makeAtomicRMW(
AtomicRMWOp op, unsigned bytes, Address offset, Type type, Name mem) {
Result<> IRBuilder::makeAtomicRMW(AtomicRMWOp op,
unsigned bytes,
Address offset,
Type type,
Name mem,
MemoryOrder order) {
AtomicRMW curr;
curr.memory = mem;
curr.type = type;
CHECK_ERR(visitAtomicRMW(&curr));
push(
builder.makeAtomicRMW(op, bytes, offset, curr.ptr, curr.value, type, mem));
push(builder.makeAtomicRMW(
op, bytes, offset, curr.ptr, curr.value, type, mem, order));
return Ok{};
}

Expand Down
2 changes: 1 addition & 1 deletion src/wasm/wasm-stack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,7 @@ void BinaryInstWriter::visitAtomicRMW(AtomicRMW* curr) {
curr->bytes,
curr->offset,
curr->memory,
MemoryOrder::SeqCst,
curr->order,
/*isRMW=*/true);
}

Expand Down
53 changes: 43 additions & 10 deletions src/wasm/wasm-validator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1108,11 +1108,17 @@ void FunctionValidator::visitLoad(Load* curr) {
curr,
"Atomic load should be i32 or i64");
}
if (curr->order == MemoryOrder::AcqRel) {
shouldBeTrue(getModule()->features.hasRelaxedAtomics(),
curr,
"Acquire/release operations require relaxed atomics "
"[--enable-relaxed-atomics]");
switch (curr->order) {
case MemoryOrder::AcqRel: {
shouldBeTrue(getModule()->features.hasRelaxedAtomics(),
curr,
"Acquire/release operations require relaxed atomics "
"[--enable-relaxed-atomics]");
break;
}
case MemoryOrder::Unordered:
case MemoryOrder::SeqCst:
break;
}
if (curr->type == Type::v128) {
shouldBeTrue(getModule()->features.hasSIMD(),
Expand Down Expand Up @@ -1147,11 +1153,17 @@ void FunctionValidator::visitStore(Store* curr) {
curr,
"Atomic store should be i32 or i64");
}
if (curr->order == MemoryOrder::AcqRel) {
shouldBeTrue(getModule()->features.hasRelaxedAtomics(),
curr,
"Acquire/release operations require relaxed atomics "
"[--enable-relaxed-atomics]");
switch (curr->order) {
case MemoryOrder::AcqRel: {
shouldBeTrue(getModule()->features.hasRelaxedAtomics(),
curr,
"Acquire/release operations require relaxed atomics "
"[--enable-relaxed-atomics]");
break;
}
case MemoryOrder::Unordered:
case MemoryOrder::SeqCst:
break;
}
if (curr->valueType == Type::v128) {
shouldBeTrue(getModule()->features.hasSIMD(),
Expand Down Expand Up @@ -1185,6 +1197,27 @@ void FunctionValidator::visitAtomicRMW(AtomicRMW* curr) {
shouldBeTrue(getModule()->features.hasAtomics(),
curr,
"Atomic operations require threads [--enable-threads]");

switch (curr->order) {
case MemoryOrder::AcqRel: {
shouldBeTrue(getModule()->features.hasRelaxedAtomics(),
curr,
"Acquire/release operations require relaxed atomics "
"[--enable-relaxed-atomics]");
break;
}
// Unordered RMW should be impossible unless there's a bug in the parser.
case MemoryOrder::Unordered: {
shouldBeUnequal(curr->order,
MemoryOrder::Unordered,
curr,
"Atomic RMW can't be unordered");
break;
}
case MemoryOrder::SeqCst:
break;
}

validateMemBytes(curr->bytes, curr->type, curr);
shouldBeEqualOrFirstIsUnreachable(
curr->ptr->type,
Expand Down
Loading
Loading