diff options
author | Alon Zakai <azakai@google.com> | 2021-07-22 09:11:12 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-22 09:11:12 -0700 |
commit | 556381b41aa95b56a77e9217afb2e2d7ecb230f5 (patch) | |
tree | 8bd8f1dd5083427e6c2024ea7af25ae487247b68 /src/passes/StackIR.cpp | |
parent | ed97c68294a8d95c57972eae22906cc0bea1aae8 (diff) | |
download | binaryen-556381b41aa95b56a77e9217afb2e2d7ecb230f5.tar.gz binaryen-556381b41aa95b56a77e9217afb2e2d7ecb230f5.tar.bz2 binaryen-556381b41aa95b56a77e9217afb2e2d7ecb230f5.zip |
[Wasm GC] Avoid dangerous StackIR opts on GC (#4007)
removeUnneededBlocks() can force us to use a local when we
load the emitted wasm, which can't work for something nondefaultable
like an RTT.
For now, just don't run that optimization if GC is enabled. Eventually,
perhaps we'll want to enable this optimization in a different way.
Diffstat (limited to 'src/passes/StackIR.cpp')
-rw-r--r-- | src/passes/StackIR.cpp | 44 |
1 files changed, 40 insertions, 4 deletions
diff --git a/src/passes/StackIR.cpp b/src/passes/StackIR.cpp index fbb990fe0..a3d9442bf 100644 --- a/src/passes/StackIR.cpp +++ b/src/passes/StackIR.cpp @@ -51,10 +51,14 @@ class StackIROptimizer { Function* func; PassOptions& passOptions; StackIR& insts; + FeatureSet features; public: - StackIROptimizer(Function* func, PassOptions& passOptions) - : func(func), passOptions(passOptions), insts(*func->stackIR.get()) { + StackIROptimizer(Function* func, + PassOptions& passOptions, + FeatureSet features) + : func(func), passOptions(passOptions), insts(*func->stackIR.get()), + features(features) { assert(func->stackIR); } @@ -65,7 +69,39 @@ public: if (passOptions.optimizeLevel >= 3 || passOptions.shrinkLevel >= 1) { local2Stack(); } - removeUnneededBlocks(); + // Removing unneeded blocks is dangerous with GC, as if we do this: + // + // (call + // (rtt) + // (block + // (nop) + // (i32) + // ) + // ) + // === remove inner block ==> + // (call + // (rtt) + // (nop) + // (i32) + // ) + // + // Then we end up with a nop that forces us to emit this during load: + // + // (call + // (block + // (local.set + // (rtt) + // ) + // (nop) + // (local.get) + // ) + // (i32) + // ) + // + // However, that is not valid as an rtt cannot be set to a local. + if (!features.hasGC()) { + removeUnneededBlocks(); + } dce(); } @@ -340,7 +376,7 @@ struct OptimizeStackIR : public WalkerPass<PostWalker<OptimizeStackIR>> { if (!func->stackIR) { return; } - StackIROptimizer(func, getPassOptions()).run(); + StackIROptimizer(func, getPassOptions(), getModule()->features).run(); } }; |