Skip to content

Commit be62412

Browse files
Add relaxed memory ordering for exchange / compare-exchange instructions (#8231)
Part of #8165 wasm::Properties::getMemoryOrder previously returned Unordered for compare-exchange instructions (unlike other atomic operations which returned SeqCst pre-relaxed atomics). After this PR it returns its real memory ordering.
1 parent 31ddd22 commit be62412

File tree

16 files changed

+1353
-38
lines changed

16 files changed

+1353
-38
lines changed

scripts/test/generate-atomic-spec-test.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,20 @@ class Template:
8686
Template(op="i64.atomic.rmw8.xor_u", value_type=ValueType.i64, args=2, should_drop=True, bin=b"\xfe\x3e"),
8787
Template(op="i64.atomic.rmw16.xor_u", value_type=ValueType.i64, args=2, should_drop=True, bin=b"\xfe\x3f"),
8888
Template(op="i64.atomic.rmw32.xor_u", value_type=ValueType.i64, args=2, should_drop=True, bin=b"\xfe\x40"),
89+
Template(op="i32.atomic.rmw.xchg", value_type=ValueType.i32, args=2, should_drop=True, bin=b"\xfe\x41"),
90+
Template(op="i64.atomic.rmw.xchg", value_type=ValueType.i64, args=2, should_drop=True, bin=b"\xfe\x42"),
91+
Template(op="i32.atomic.rmw8.xchg_u", value_type=ValueType.i32, args=2, should_drop=True, bin=b"\xfe\x43"),
92+
Template(op="i32.atomic.rmw16.xchg_u", value_type=ValueType.i32, args=2, should_drop=True, bin=b"\xfe\x44"),
93+
Template(op="i64.atomic.rmw8.xchg_u", value_type=ValueType.i64, args=2, should_drop=True, bin=b"\xfe\x45"),
94+
Template(op="i64.atomic.rmw16.xchg_u", value_type=ValueType.i64, args=2, should_drop=True, bin=b"\xfe\x46"),
95+
Template(op="i64.atomic.rmw32.xchg_u", value_type=ValueType.i64, args=2, should_drop=True, bin=b"\xfe\x47"),
96+
Template(op="i32.atomic.rmw.cmpxchg", value_type=ValueType.i32, args=3, should_drop=True, bin=b"\xfe\x48"),
97+
Template(op="i64.atomic.rmw.cmpxchg", value_type=ValueType.i64, args=3, should_drop=True, bin=b"\xfe\x49"),
98+
Template(op="i32.atomic.rmw8.cmpxchg_u", value_type=ValueType.i32, args=3, should_drop=True, bin=b"\xfe\x4a"),
99+
Template(op="i32.atomic.rmw16.cmpxchg_u", value_type=ValueType.i32, args=3, should_drop=True, bin=b"\xfe\x4b"),
100+
Template(op="i64.atomic.rmw8.cmpxchg_u", value_type=ValueType.i64, args=3, should_drop=True, bin=b"\xfe\x4c"),
101+
Template(op="i64.atomic.rmw16.cmpxchg_u", value_type=ValueType.i64, args=3, should_drop=True, bin=b"\xfe\x4d"),
102+
Template(op="i64.atomic.rmw32.cmpxchg_u", value_type=ValueType.i64, args=3, should_drop=True, bin=b"\xfe\x4e"),
89103
]
90104

91105

src/binaryen-c.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1400,15 +1400,15 @@ BinaryenExpressionRef BinaryenAtomicCmpxchg(BinaryenModuleRef module,
14001400
BinaryenExpressionRef replacement,
14011401
BinaryenType type,
14021402
const char* memoryName) {
1403-
return static_cast<Expression*>(
1404-
Builder(*(Module*)module)
1405-
.makeAtomicCmpxchg(bytes,
1406-
offset,
1407-
(Expression*)ptr,
1408-
(Expression*)expected,
1409-
(Expression*)replacement,
1410-
Type(type),
1411-
getMemoryName(module, memoryName)));
1403+
return Builder(*(Module*)module)
1404+
.makeAtomicCmpxchg(bytes,
1405+
offset,
1406+
(Expression*)ptr,
1407+
(Expression*)expected,
1408+
(Expression*)replacement,
1409+
Type(type),
1410+
getMemoryName(module, memoryName),
1411+
MemoryOrder::SeqCst);
14121412
}
14131413
BinaryenExpressionRef BinaryenAtomicWait(BinaryenModuleRef module,
14141414
BinaryenExpressionRef ptr,

src/ir/properties.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,9 @@ inline MemoryOrder getMemoryOrder(Expression* curr) {
510510
if (auto* rmw = curr->dynCast<AtomicRMW>()) {
511511
return rmw->order;
512512
}
513+
if (auto* cmpxchg = curr->dynCast<AtomicCmpxchg>()) {
514+
return cmpxchg->order;
515+
}
513516
if (curr->is<AtomicWait>() || curr->is<AtomicNotify>() ||
514517
curr->is<AtomicFence>()) {
515518
return MemoryOrder::SeqCst;

src/parser/contexts.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -579,8 +579,13 @@ struct NullInstrParserCtx {
579579
MemoryOrder) {
580580
return Ok{};
581581
}
582-
Result<> makeAtomicCmpxchg(
583-
Index, const std::vector<Annotation>&, Type, int, MemoryIdxT*, MemargT) {
582+
Result<> makeAtomicCmpxchg(Index,
583+
const std::vector<Annotation>&,
584+
Type,
585+
int,
586+
MemoryIdxT*,
587+
MemargT,
588+
MemoryOrder) {
584589
return Ok{};
585590
}
586591
Result<> makeAtomicWait(
@@ -2288,11 +2293,12 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx>, AnnotationParserCtx {
22882293
Type type,
22892294
int bytes,
22902295
Name* mem,
2291-
Memarg memarg) {
2296+
Memarg memarg,
2297+
MemoryOrder order) {
22922298
auto m = getMemory(pos, mem);
22932299
CHECK_ERR(m);
2294-
return withLoc(pos,
2295-
irBuilder.makeAtomicCmpxchg(bytes, memarg.offset, type, *m));
2300+
return withLoc(
2301+
pos, irBuilder.makeAtomicCmpxchg(bytes, memarg.offset, type, *m, order));
22962302
}
22972303

22982304
Result<> makeAtomicWait(Index pos,

src/parser/parsers.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1839,10 +1839,19 @@ Result<> makeAtomicCmpxchg(Ctx& ctx,
18391839
uint8_t bytes) {
18401840
auto mem = maybeMemidx(ctx);
18411841
CHECK_ERR(mem);
1842+
1843+
auto maybeOrder = maybeMemOrder(ctx);
1844+
CHECK_ERR(maybeOrder);
1845+
18421846
auto arg = memarg(ctx, bytes);
18431847
CHECK_ERR(arg);
1844-
return ctx.makeAtomicCmpxchg(
1845-
pos, annotations, type, bytes, mem.getPtr(), *arg);
1848+
return ctx.makeAtomicCmpxchg(pos,
1849+
annotations,
1850+
type,
1851+
bytes,
1852+
mem.getPtr(),
1853+
*arg,
1854+
maybeOrder ? *maybeOrder : MemoryOrder::SeqCst);
18461855
}
18471856

18481857
template<typename Ctx>

src/passes/Print.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,7 @@ struct PrintExpressionContents
676676
}
677677
restoreNormalColor(o);
678678
printMemoryName(curr->memory, o, wasm);
679+
printMemoryOrder(curr->order);
679680
if (curr->offset) {
680681
o << " offset=" << curr->offset;
681682
}

src/tools/fuzzing/fuzzing.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4775,8 +4775,14 @@ Expression* TranslateToFuzzReader::makeAtomic(Type type) {
47754775
} else {
47764776
auto* expected = make(type);
47774777
auto* replacement = make(type);
4778-
return builder.makeAtomicCmpxchg(
4779-
bytes, offset, ptr, expected, replacement, type, wasm.memories[0]->name);
4778+
return builder.makeAtomicCmpxchg(bytes,
4779+
offset,
4780+
ptr,
4781+
expected,
4782+
replacement,
4783+
type,
4784+
wasm.memories[0]->name,
4785+
MemoryOrder::SeqCst);
47804786
}
47814787
}
47824788

src/wasm-builder.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -486,16 +486,18 @@ class Builder {
486486
Expression* expected,
487487
Expression* replacement,
488488
Type type,
489-
Name memory) {
489+
Name memory,
490+
MemoryOrder order) {
490491
auto* ret = wasm.allocator.alloc<AtomicCmpxchg>();
491492
ret->bytes = bytes;
492493
ret->offset = offset;
493494
ret->ptr = ptr;
494495
ret->expected = expected;
495496
ret->replacement = replacement;
496497
ret->type = type;
497-
ret->finalize();
498498
ret->memory = memory;
499+
ret->order = order;
500+
ret->finalize();
499501
return ret;
500502
}
501503
SIMDExtract*

src/wasm-delegations-fields.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,7 @@ DELEGATE_FIELD_CHILD(AtomicCmpxchg, expected)
385385
DELEGATE_FIELD_CHILD(AtomicCmpxchg, ptr)
386386
DELEGATE_FIELD_INT(AtomicCmpxchg, bytes)
387387
DELEGATE_FIELD_ADDRESS(AtomicCmpxchg, offset)
388+
DELEGATE_FIELD_INT(AtomicCmpxchg, order)
388389
DELEGATE_FIELD_NAME_KIND(AtomicCmpxchg, memory, ModuleItemKind::Memory)
389390
DELEGATE_FIELD_CASE_END(AtomicCmpxchg)
390391

src/wasm-ir-builder.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,8 @@ class IRBuilder : public UnifiedExpressionVisitor<IRBuilder, Result<>> {
166166
Type type,
167167
Name mem,
168168
MemoryOrder order);
169-
Result<>
170-
makeAtomicCmpxchg(unsigned bytes, Address offset, Type type, Name mem);
169+
Result<> makeAtomicCmpxchg(
170+
unsigned bytes, Address offset, Type type, Name mem, MemoryOrder order);
171171
Result<> makeAtomicWait(Type type, Address offset, Name mem);
172172
Result<> makeAtomicNotify(Address offset, Name mem);
173173
Result<> makeAtomicFence();

0 commit comments

Comments
 (0)