Skip to content

Commit e775682

Browse files
authored
No atomic float operations (#1693)
SafeHeap was emitting them, but it looks like they are invalid according to the wasm-threads spec. Fixes emscripten-core/emscripten#7208
1 parent f7db9e9 commit e775682

File tree

3 files changed

+150
-1130
lines changed

3 files changed

+150
-1130
lines changed

src/passes/SafeHeap.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,10 @@ struct SafeHeap : public Pass {
152152
}
153153
}
154154

155+
bool isPossibleAtomicOperation(Index align, Index bytes, bool shared, Type type) {
156+
return align == bytes && shared && isIntegerType(type);
157+
}
158+
155159
void addGlobals(Module* module) {
156160
// load funcs
157161
Load load;
@@ -168,8 +172,10 @@ struct SafeHeap : public Pass {
168172
if (align > bytes) continue;
169173
for (auto isAtomic : { true, false }) {
170174
load.isAtomic = isAtomic;
171-
if (isAtomic && align != bytes) continue;
172-
if (isAtomic && !module->memory.shared) continue;
175+
if (isAtomic &&
176+
!isPossibleAtomicOperation(align, bytes, module->memory.shared, type)) {
177+
continue;
178+
}
173179
addLoadFunc(load, module);
174180
}
175181
}
@@ -189,8 +195,10 @@ struct SafeHeap : public Pass {
189195
if (align > bytes) continue;
190196
for (auto isAtomic : { true, false }) {
191197
store.isAtomic = isAtomic;
192-
if (isAtomic && align != bytes) continue;
193-
if (isAtomic && !module->memory.shared) continue;
198+
if (isAtomic &&
199+
!isPossibleAtomicOperation(align, bytes, module->memory.shared, valueType)) {
200+
continue;
201+
}
194202
addStoreFunc(store, module);
195203
}
196204
}

src/wasm/wasm-validator.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,10 @@ void FunctionValidator::visitLoad(Load* curr) {
502502
validateMemBytes(curr->bytes, curr->type, curr);
503503
validateAlignment(curr->align, curr->type, curr->bytes, curr->isAtomic, curr);
504504
shouldBeEqualOrFirstIsUnreachable(curr->ptr->type, i32, curr, "load pointer type must be i32");
505-
if (curr->isAtomic) shouldBeFalse(curr->signed_, curr, "atomic loads must be unsigned");
505+
if (curr->isAtomic) {
506+
shouldBeFalse(curr->signed_, curr, "atomic loads must be unsigned");
507+
shouldBeTrue(isIntegerType(curr->type), curr, "atomic loads must be of integers");
508+
}
506509
}
507510

508511
void FunctionValidator::visitStore(Store* curr) {
@@ -513,6 +516,9 @@ void FunctionValidator::visitStore(Store* curr) {
513516
shouldBeEqualOrFirstIsUnreachable(curr->ptr->type, i32, curr, "store pointer type must be i32");
514517
shouldBeUnequal(curr->value->type, none, curr, "store value type must not be none");
515518
shouldBeEqualOrFirstIsUnreachable(curr->value->type, curr->valueType, curr, "store value type must match");
519+
if (curr->isAtomic) {
520+
shouldBeTrue(isIntegerType(curr->valueType), curr, "atomic stores must be of integers");
521+
}
516522
}
517523

518524
void FunctionValidator::visitAtomicRMW(AtomicRMW* curr) {

0 commit comments

Comments
 (0)