Skip to content
Draft
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 @@ -1400,15 +1400,15 @@ BinaryenExpressionRef BinaryenAtomicCmpxchg(BinaryenModuleRef module,
BinaryenExpressionRef replacement,
BinaryenType type,
const char* memoryName) {
return static_cast<Expression*>(
Builder(*(Module*)module)
.makeAtomicCmpxchg(bytes,
offset,
(Expression*)ptr,
(Expression*)expected,
(Expression*)replacement,
Type(type),
getMemoryName(module, memoryName)));
return Builder(*(Module*)module)
.makeAtomicCmpxchg(bytes,
offset,
(Expression*)ptr,
(Expression*)expected,
(Expression*)replacement,
Type(type),
getMemoryName(module, memoryName),
MemoryOrder::SeqCst);
}
BinaryenExpressionRef BinaryenAtomicWait(BinaryenModuleRef module,
BinaryenExpressionRef ptr,
Expand Down
4 changes: 4 additions & 0 deletions src/ir/properties.h
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,10 @@ inline MemoryOrder getMemoryOrder(Expression* curr) {
if (auto* rmw = curr->dynCast<AtomicRMW>()) {
return rmw->order;
}
// TODO: this wasn't here before?
if (auto* cmpxchg = curr->dynCast<AtomicCmpxchg>()) {
return cmpxchg->order;
}
if (curr->is<AtomicWait>() || curr->is<AtomicNotify>() ||
curr->is<AtomicFence>()) {
return MemoryOrder::SeqCst;
Expand Down
16 changes: 11 additions & 5 deletions src/parser/contexts.h
Original file line number Diff line number Diff line change
Expand Up @@ -579,8 +579,13 @@ struct NullInstrParserCtx {
MemoryOrder) {
return Ok{};
}
Result<> makeAtomicCmpxchg(
Index, const std::vector<Annotation>&, Type, int, MemoryIdxT*, MemargT) {
Result<> makeAtomicCmpxchg(Index,
const std::vector<Annotation>&,
Type,
int,
MemoryIdxT*,
MemargT,
MemoryOrder) {
return Ok{};
}
Result<> makeAtomicWait(
Expand Down Expand Up @@ -2288,11 +2293,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.makeAtomicCmpxchg(bytes, memarg.offset, type, *m));
return withLoc(
pos, irBuilder.makeAtomicCmpxchg(bytes, memarg.offset, type, *m, order));
}

Result<> makeAtomicWait(Index pos,
Expand Down
13 changes: 11 additions & 2 deletions src/parser/parsers.h
Original file line number Diff line number Diff line change
Expand Up @@ -1839,10 +1839,19 @@ Result<> makeAtomicCmpxchg(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.makeAtomicCmpxchg(
pos, annotations, type, bytes, mem.getPtr(), *arg);
return ctx.makeAtomicCmpxchg(pos,
annotations,
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 @@ -676,6 +676,7 @@ struct PrintExpressionContents
}
restoreNormalColor(o);
printMemoryName(curr->memory, o, wasm);
printMemoryOrder(curr->order);
if (curr->offset) {
o << " offset=" << curr->offset;
}
Expand Down
10 changes: 8 additions & 2 deletions src/tools/fuzzing/fuzzing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4775,8 +4775,14 @@ Expression* TranslateToFuzzReader::makeAtomic(Type type) {
} else {
auto* expected = make(type);
auto* replacement = make(type);
return builder.makeAtomicCmpxchg(
bytes, offset, ptr, expected, replacement, type, wasm.memories[0]->name);
return builder.makeAtomicCmpxchg(bytes,
offset,
ptr,
expected,
replacement,
type,
wasm.memories[0]->name,
MemoryOrder::SeqCst);
}
}

Expand Down
6 changes: 4 additions & 2 deletions src/wasm-builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -486,16 +486,18 @@ class Builder {
Expression* expected,
Expression* replacement,
Type type,
Name memory) {
Name memory,
MemoryOrder order) {
auto* ret = wasm.allocator.alloc<AtomicCmpxchg>();
ret->bytes = bytes;
ret->offset = offset;
ret->ptr = ptr;
ret->expected = expected;
ret->replacement = replacement;
ret->type = type;
ret->finalize();
ret->memory = memory;
ret->order = order;
ret->finalize();
return ret;
}
SIMDExtract*
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 @@ -385,6 +385,7 @@ DELEGATE_FIELD_CHILD(AtomicCmpxchg, expected)
DELEGATE_FIELD_CHILD(AtomicCmpxchg, ptr)
DELEGATE_FIELD_INT(AtomicCmpxchg, bytes)
DELEGATE_FIELD_ADDRESS(AtomicCmpxchg, offset)
DELEGATE_FIELD_INT(AtomicCmpxchg, order)
DELEGATE_FIELD_NAME_KIND(AtomicCmpxchg, memory, ModuleItemKind::Memory)
DELEGATE_FIELD_CASE_END(AtomicCmpxchg)

Expand Down
4 changes: 2 additions & 2 deletions src/wasm-ir-builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,8 @@ class IRBuilder : public UnifiedExpressionVisitor<IRBuilder, Result<>> {
Type type,
Name mem,
MemoryOrder order);
Result<>
makeAtomicCmpxchg(unsigned bytes, Address offset, Type type, Name mem);
Result<> makeAtomicCmpxchg(
unsigned bytes, Address offset, Type type, Name mem, MemoryOrder order);
Result<> makeAtomicWait(Type type, Address offset, Name mem);
Result<> makeAtomicNotify(Address offset, Name mem);
Result<> makeAtomicFence();
Expand Down
1 change: 1 addition & 0 deletions src/wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -1051,6 +1051,7 @@ class AtomicCmpxchg : public SpecificExpression<Expression::AtomicCmpxchgId> {
Expression* expected;
Expression* replacement;
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 @@ -3747,31 +3747,38 @@ Result<> WasmBinaryReader::readInst() {

case BinaryConsts::I32AtomicCmpxchg: {
auto [mem, align, offset, memoryOrder] = getRMWMemarg();
return builder.makeAtomicCmpxchg(4, offset, Type::i32, mem);
return builder.makeAtomicCmpxchg(
4, offset, Type::i32, mem, memoryOrder);
}
case BinaryConsts::I32AtomicCmpxchg8U: {
auto [mem, align, offset, memoryOrder] = getRMWMemarg();
return builder.makeAtomicCmpxchg(1, offset, Type::i32, mem);
return builder.makeAtomicCmpxchg(
1, offset, Type::i32, mem, memoryOrder);
}
case BinaryConsts::I32AtomicCmpxchg16U: {
auto [mem, align, offset, memoryOrder] = getRMWMemarg();
return builder.makeAtomicCmpxchg(2, offset, Type::i32, mem);
return builder.makeAtomicCmpxchg(
2, offset, Type::i32, mem, memoryOrder);
}
case BinaryConsts::I64AtomicCmpxchg: {
auto [mem, align, offset, memoryOrder] = getRMWMemarg();
return builder.makeAtomicCmpxchg(8, offset, Type::i64, mem);
return builder.makeAtomicCmpxchg(
8, offset, Type::i64, mem, memoryOrder);
}
case BinaryConsts::I64AtomicCmpxchg8U: {
auto [mem, align, offset, memoryOrder] = getRMWMemarg();
return builder.makeAtomicCmpxchg(1, offset, Type::i64, mem);
return builder.makeAtomicCmpxchg(
1, offset, Type::i64, mem, memoryOrder);
}
case BinaryConsts::I64AtomicCmpxchg16U: {
auto [mem, align, offset, memoryOrder] = getRMWMemarg();
return builder.makeAtomicCmpxchg(2, offset, Type::i64, mem);
return builder.makeAtomicCmpxchg(
2, offset, Type::i64, mem, memoryOrder);
}
case BinaryConsts::I64AtomicCmpxchg32U: {
auto [mem, align, offset, memoryOrder] = getRMWMemarg();
return builder.makeAtomicCmpxchg(4, offset, Type::i64, mem);
return builder.makeAtomicCmpxchg(
4, offset, Type::i64, mem, memoryOrder);
}
case BinaryConsts::I32AtomicWait: {
auto [mem, align, offset, memoryOrder] = getAtomicMemarg();
Expand Down
16 changes: 10 additions & 6 deletions src/wasm/wasm-ir-builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1518,15 +1518,19 @@ Result<> IRBuilder::makeAtomicRMW(AtomicRMWOp op,
return Ok{};
}

Result<> IRBuilder::makeAtomicCmpxchg(unsigned bytes,
Address offset,
Type type,
Name mem) {
Result<> IRBuilder::makeAtomicCmpxchg(
unsigned bytes, Address offset, Type type, Name mem, MemoryOrder order) {
AtomicCmpxchg curr;
curr.memory = mem;
CHECK_ERR(ChildPopper{*this}.visitAtomicCmpxchg(&curr, type));
push(builder.makeAtomicCmpxchg(
bytes, offset, curr.ptr, curr.expected, curr.replacement, type, mem));
push(builder.makeAtomicCmpxchg(bytes,
offset,
curr.ptr,
curr.expected,
curr.replacement,
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 @@ -587,7 +587,7 @@ void BinaryInstWriter::visitAtomicCmpxchg(AtomicCmpxchg* curr) {
curr->bytes,
curr->offset,
curr->memory,
MemoryOrder::SeqCst,
curr->order,
/*isRMW=*/true);
}

Expand Down
22 changes: 22 additions & 0 deletions src/wasm/wasm-validator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1238,6 +1238,28 @@ void FunctionValidator::visitAtomicCmpxchg(AtomicCmpxchg* 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 cmpxchg should be impossible unless there's a bug in the
// parser.
case MemoryOrder::Unordered: {
shouldBeUnequal(curr->order,
MemoryOrder::Unordered,
curr,
"Atomic cmpxchg can't be unordered");
break;
}
case MemoryOrder::SeqCst:
break;
}

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