diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/GlobalTypeOptimization.cpp | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/src/passes/GlobalTypeOptimization.cpp b/src/passes/GlobalTypeOptimization.cpp index 0baecdf43..b2ba23b0f 100644 --- a/src/passes/GlobalTypeOptimization.cpp +++ b/src/passes/GlobalTypeOptimization.cpp @@ -514,13 +514,23 @@ struct GlobalTypeOptimization : public Pass { // operations here: the trap on a null ref happens after the value, // which might have side effects. Builder builder(*getModule()); - auto flipped = getResultOfFirst(curr->ref, - builder.makeDrop(curr->value), - getFunction(), - getModule(), - getPassOptions()); - replaceCurrent( - builder.makeDrop(builder.makeRefAs(RefAsNonNull, flipped))); + auto* flipped = getResultOfFirst(curr->ref, + builder.makeDrop(curr->value), + getFunction(), + getModule(), + getPassOptions()); + Expression* replacement = + builder.makeDrop(builder.makeRefAs(RefAsNonNull, flipped)); + if (curr->order == MemoryOrder::SeqCst) { + // If the removed set is sequentially consistent, we must insert a + // seqcst fence to preserve the effect on the global order of seqcst + // operations. No fence is necessary for release sets because there + // are no reads for them to synchronize with given that we are + // removing the field. + replacement = + builder.makeSequence(replacement, builder.makeAtomicFence()); + } + replaceCurrent(replacement); } } |