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
2 changes: 2 additions & 0 deletions src/binaryen-c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1365,6 +1365,7 @@ BinaryenExpressionRef BinaryenAtomicLoad(BinaryenModuleRef module,
Builder(*(Module*)module)
.makeAtomicLoad(bytes,
offset,
bytes,
(Expression*)ptr,
Type(type),
getMemoryName(module, memoryName),
Expand All @@ -1382,6 +1383,7 @@ BinaryenExpressionRef BinaryenAtomicStore(BinaryenModuleRef module,
Builder(*(Module*)module)
.makeAtomicStore(bytes,
offset,
bytes,
(Expression*)ptr,
(Expression*)value,
Type(type),
Expand Down
10 changes: 6 additions & 4 deletions src/parser/contexts.h
Original file line number Diff line number Diff line change
Expand Up @@ -2270,8 +2270,9 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx>, AnnotationParserCtx {
auto m = getMemory(pos, mem);
CHECK_ERR(m);
if (isAtomic) {
return withLoc(
pos, irBuilder.makeAtomicLoad(bytes, memarg.offset, type, *m, order));
return withLoc(pos,
irBuilder.makeAtomicLoad(
bytes, memarg.offset, memarg.align, type, *m, order));
}
return withLoc(pos,
irBuilder.makeLoad(
Expand All @@ -2289,8 +2290,9 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx>, AnnotationParserCtx {
auto m = getMemory(pos, mem);
CHECK_ERR(m);
if (isAtomic) {
return withLoc(
pos, irBuilder.makeAtomicStore(bytes, memarg.offset, type, *m, order));
return withLoc(pos,
irBuilder.makeAtomicStore(
bytes, memarg.offset, memarg.align, type, *m, order));
}
return withLoc(
pos, irBuilder.makeStore(bytes, memarg.offset, memarg.align, type, *m));
Expand Down
2 changes: 2 additions & 0 deletions src/tools/wasm-split/instrumenter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ void Instrumenter::instrumentFuncs() {
func->body = builder.makeSequence(
builder.makeAtomicStore(1,
funcIdx,
/*align=*/1,
builder.makeConstPtr(0, Type::i32),
builder.makeConst(uint32_t(1)),
Type::i32,
Expand Down Expand Up @@ -290,6 +291,7 @@ void Instrumenter::addProfileExport(size_t numFuncs) {
MulInt32, getFuncIdx(), builder.makeConst(uint32_t(4)))),
builder.makeAtomicLoad(1,
0,
/*align=*/1,
getFuncIdx(),
Type::i32,
loadMemoryName,
Expand Down
7 changes: 5 additions & 2 deletions src/wasm-builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -386,14 +386,16 @@ class Builder {
}
Load* makeAtomicLoad(unsigned bytes,
Address offset,
unsigned align,
Expression* ptr,
Type type,
Name memory,
MemoryOrder order) {
assert(order != MemoryOrder::Unordered &&
"Atomic loads can't be unordered");

Load* load = makeLoad(bytes, false, offset, bytes, ptr, type, memory);
// this part is wrong
Load* load = makeLoad(bytes, false, offset, align, ptr, type, memory);
load->order = order;
return load;
}
Expand Down Expand Up @@ -448,6 +450,7 @@ class Builder {
}
Store* makeAtomicStore(unsigned bytes,
Address offset,
unsigned align,
Expression* ptr,
Expression* value,
Type type,
Expand All @@ -456,7 +459,7 @@ class Builder {
assert(order != MemoryOrder::Unordered &&
"Atomic stores can't be unordered");

Store* store = makeStore(bytes, offset, bytes, ptr, value, type, memory);
Store* store = makeStore(bytes, offset, align, ptr, value, type, memory);
store->order = order;
return store;
}
Expand Down
16 changes: 12 additions & 4 deletions src/wasm-ir-builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,10 +155,18 @@ class IRBuilder : public UnifiedExpressionVisitor<IRBuilder, Result<>> {
Name mem);
Result<> makeStore(
unsigned bytes, Address offset, unsigned align, Type type, Name mem);
Result<> makeAtomicLoad(
unsigned bytes, Address offset, Type type, Name mem, MemoryOrder order);
Result<> makeAtomicStore(
unsigned bytes, Address offset, Type type, Name mem, MemoryOrder order);
Result<> makeAtomicLoad(unsigned bytes,
Address offset,
unsigned align,
Type type,
Name mem,
MemoryOrder order);
Result<> makeAtomicStore(unsigned bytes,
Address offset,
unsigned align,
Type type,
Name mem,
MemoryOrder order);
Result<> makeAtomicRMW(AtomicRMWOp op,
unsigned bytes,
Address offset,
Expand Down
35 changes: 21 additions & 14 deletions src/wasm/wasm-binary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3641,66 +3641,73 @@ Result<> WasmBinaryReader::readInst() {
case BinaryConsts::I32AtomicLoad8U: {
// TODO: pass align through for validation.
auto [mem, align, offset, memoryOrder] = getAtomicMemarg();
return builder.makeAtomicLoad(1, offset, Type::i32, mem, memoryOrder);
return builder.makeAtomicLoad(
1, offset, align, Type::i32, mem, memoryOrder);
}
case BinaryConsts::I32AtomicLoad16U: {
auto [mem, align, offset, memoryOrder] = getAtomicMemarg();
return builder.makeAtomicLoad(2, offset, Type::i32, mem, memoryOrder);
return builder.makeAtomicLoad(
2, offset, align, Type::i32, mem, memoryOrder);
}
case BinaryConsts::I32AtomicLoad: {
auto [mem, align, offset, memoryOrder] = getAtomicMemarg();
return builder.makeAtomicLoad(4, offset, Type::i32, mem, memoryOrder);
return builder.makeAtomicLoad(
4, offset, align, Type::i32, mem, memoryOrder);
}
case BinaryConsts::I64AtomicLoad8U: {
auto [mem, align, offset, memoryOrder] = getAtomicMemarg();
return builder.makeAtomicLoad(1, offset, Type::i64, mem, memoryOrder);
return builder.makeAtomicLoad(
1, offset, align, Type::i64, mem, memoryOrder);
}
case BinaryConsts::I64AtomicLoad16U: {
auto [mem, align, offset, memoryOrder] = getAtomicMemarg();
return builder.makeAtomicLoad(2, offset, Type::i64, mem, memoryOrder);
return builder.makeAtomicLoad(
2, offset, align, Type::i64, mem, memoryOrder);
}
case BinaryConsts::I64AtomicLoad32U: {
auto [mem, align, offset, memoryOrder] = getAtomicMemarg();
return builder.makeAtomicLoad(4, offset, Type::i64, mem, memoryOrder);
return builder.makeAtomicLoad(
4, offset, align, Type::i64, mem, memoryOrder);
}
case BinaryConsts::I64AtomicLoad: {
auto [mem, align, offset, memoryOrder] = getAtomicMemarg();
return builder.makeAtomicLoad(8, offset, Type::i64, mem, memoryOrder);
return builder.makeAtomicLoad(
8, offset, align, Type::i64, mem, memoryOrder);
}
case BinaryConsts::I32AtomicStore8: {
auto [mem, align, offset, memoryOrder] = getAtomicMemarg();
return builder.makeAtomicStore(
1, offset, Type::i32, mem, memoryOrder);
1, offset, align, Type::i32, mem, memoryOrder);
}
case BinaryConsts::I32AtomicStore16: {
auto [mem, align, offset, memoryOrder] = getAtomicMemarg();
return builder.makeAtomicStore(
2, offset, Type::i32, mem, memoryOrder);
2, offset, align, Type::i32, mem, memoryOrder);
}
case BinaryConsts::I32AtomicStore: {
auto [mem, align, offset, memoryOrder] = getAtomicMemarg();
return builder.makeAtomicStore(
4, offset, Type::i32, mem, memoryOrder);
4, offset, align, Type::i32, mem, memoryOrder);
}
case BinaryConsts::I64AtomicStore8: {
auto [mem, align, offset, memoryOrder] = getAtomicMemarg();
return builder.makeAtomicStore(
1, offset, Type::i64, mem, memoryOrder);
1, offset, align, Type::i64, mem, memoryOrder);
}
case BinaryConsts::I64AtomicStore16: {
auto [mem, align, offset, memoryOrder] = getAtomicMemarg();
return builder.makeAtomicStore(
2, offset, Type::i64, mem, memoryOrder);
2, offset, align, Type::i64, mem, memoryOrder);
}
case BinaryConsts::I64AtomicStore32: {
auto [mem, align, offset, memoryOrder] = getAtomicMemarg();
return builder.makeAtomicStore(
4, offset, Type::i64, mem, memoryOrder);
4, offset, align, Type::i64, mem, memoryOrder);
}
case BinaryConsts::I64AtomicStore: {
auto [mem, align, offset, memoryOrder] = getAtomicMemarg();
return builder.makeAtomicStore(
8, offset, Type::i64, mem, memoryOrder);
8, offset, align, Type::i64, mem, memoryOrder);
}

#define RMW(op) \
Expand Down
21 changes: 15 additions & 6 deletions src/wasm/wasm-ir-builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1484,23 +1484,32 @@ Result<> IRBuilder::makeStore(
return Ok{};
}

Result<> IRBuilder::makeAtomicLoad(
unsigned bytes, Address offset, Type type, Name mem, MemoryOrder order) {
Result<> IRBuilder::makeAtomicLoad(unsigned bytes,
Address offset,
unsigned align,
Type type,
Name mem,
MemoryOrder order) {
Load curr;
curr.memory = mem;
CHECK_ERR(visitLoad(&curr));
push(builder.makeAtomicLoad(bytes, offset, curr.ptr, type, mem, order));
push(
builder.makeAtomicLoad(bytes, offset, align, curr.ptr, type, mem, order));
return Ok{};
}

Result<> IRBuilder::makeAtomicStore(
unsigned bytes, Address offset, Type type, Name mem, MemoryOrder order) {
Result<> IRBuilder::makeAtomicStore(unsigned bytes,
Address offset,
unsigned align,
Type type,
Name mem,
MemoryOrder order) {
Store curr;
curr.memory = mem;
curr.valueType = type;
CHECK_ERR(visitStore(&curr));
push(builder.makeAtomicStore(
bytes, offset, curr.ptr, curr.value, type, mem, order));
bytes, offset, align, curr.ptr, curr.value, type, mem, order));
return Ok{};
}

Expand Down
6 changes: 2 additions & 4 deletions src/wasm/wasm-validator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4319,10 +4319,8 @@ void FunctionValidator::validateOffset(Address offset,
void FunctionValidator::validateAlignment(
size_t align, Type type, Index bytes, bool isAtomic, Expression* curr) {
if (isAtomic) {
shouldBeEqual(align,
(size_t)bytes,
curr,
"atomic accesses must have natural alignment");
shouldBeEqual(
align, (size_t)bytes, curr, "atomic alignment must be natural");
return;
}
switch (align) {
Expand Down
Loading