diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index efbf69d3de3..e0c654ab447 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -1365,6 +1365,7 @@ BinaryenExpressionRef BinaryenAtomicLoad(BinaryenModuleRef module, Builder(*(Module*)module) .makeAtomicLoad(bytes, offset, + bytes, (Expression*)ptr, Type(type), getMemoryName(module, memoryName), @@ -1382,6 +1383,7 @@ BinaryenExpressionRef BinaryenAtomicStore(BinaryenModuleRef module, Builder(*(Module*)module) .makeAtomicStore(bytes, offset, + bytes, (Expression*)ptr, (Expression*)value, Type(type), diff --git a/src/parser/contexts.h b/src/parser/contexts.h index 4f9786c0a51..bc2190298cf 100644 --- a/src/parser/contexts.h +++ b/src/parser/contexts.h @@ -2270,8 +2270,9 @@ struct ParseDefsCtx : TypeParserCtx, 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( @@ -2289,8 +2290,9 @@ struct ParseDefsCtx : TypeParserCtx, 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)); diff --git a/src/tools/wasm-split/instrumenter.cpp b/src/tools/wasm-split/instrumenter.cpp index 92861a8729a..79298a0d775 100644 --- a/src/tools/wasm-split/instrumenter.cpp +++ b/src/tools/wasm-split/instrumenter.cpp @@ -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, @@ -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, diff --git a/src/wasm-builder.h b/src/wasm-builder.h index cd73babb6ca..33f568b01ff 100644 --- a/src/wasm-builder.h +++ b/src/wasm-builder.h @@ -386,6 +386,7 @@ class Builder { } Load* makeAtomicLoad(unsigned bytes, Address offset, + unsigned align, Expression* ptr, Type type, Name memory, @@ -393,7 +394,8 @@ class Builder { 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; } @@ -448,6 +450,7 @@ class Builder { } Store* makeAtomicStore(unsigned bytes, Address offset, + unsigned align, Expression* ptr, Expression* value, Type type, @@ -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; } diff --git a/src/wasm-ir-builder.h b/src/wasm-ir-builder.h index 82b7fc68450..21256ab171f 100644 --- a/src/wasm-ir-builder.h +++ b/src/wasm-ir-builder.h @@ -155,10 +155,18 @@ class IRBuilder : public UnifiedExpressionVisitor> { 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, diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index c1fe77ee309..6c6acce380f 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -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) \ diff --git a/src/wasm/wasm-ir-builder.cpp b/src/wasm/wasm-ir-builder.cpp index 8704359302e..6caf9de1e12 100644 --- a/src/wasm/wasm-ir-builder.cpp +++ b/src/wasm/wasm-ir-builder.cpp @@ -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{}; } diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 5b1f0c7f4ed..a7c4b947ea1 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -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) {