@@ -127,9 +127,12 @@ struct CodeFolding : public WalkerPass<ControlFlowWalker<CodeFolding>> {
127127 if (curr->condition || curr->value ) {
128128 unoptimizables.insert (curr->name );
129129 } else {
130- // we can only optimize if we are at the end of the parent block
130+ // we can only optimize if we are at the end of the parent block,
131+ // and if the parent block does not return a value (we can't move
132+ // elements out of it if there is a value being returned)
131133 Block* parent = controlFlowStack.back ()->dynCast <Block>();
132- if (parent && curr == parent->list .back ()) {
134+ if (parent && curr == parent->list .back () &&
135+ !isConcreteWasmType (parent->list .back ()->type )) {
133136 breakTails[curr->name ].push_back (Tail (curr, parent));
134137 } else {
135138 unoptimizables.insert (curr->name );
@@ -168,8 +171,13 @@ struct CodeFolding : public WalkerPass<ControlFlowWalker<CodeFolding>> {
168171 }
169172
170173 void visitBlock (Block* curr) {
174+ if (curr->list .empty ()) return ;
171175 if (!curr->name .is ()) return ;
172176 if (unoptimizables.count (curr->name ) > 0 ) return ;
177+ // we can't optimize a fallthrough value
178+ if (isConcreteWasmType (curr->list .back ()->type )) {
179+ return ;
180+ }
173181 auto iter = breakTails.find (curr->name );
174182 if (iter == breakTails.end ()) return ;
175183 // looks promising
@@ -376,8 +384,14 @@ struct CodeFolding : public WalkerPass<ControlFlowWalker<CodeFolding>> {
376384 if (!tail.isFallthrough ()) {
377385 tail.block ->list .push_back (last);
378386 }
379- // the block type may change if we removed final values
380- tail.block ->finalize ();
387+ // the block type may change if we removed unreachable stuff,
388+ // but in general it should remain the same, as if it had a
389+ // forced type it should remain, *and*, we don't have a
390+ // fallthrough value (we would never get here), so a concrete
391+ // type was not from that. I.e., any type on the block is
392+ // either forced and/or from breaks with a value, so the
393+ // type cannot be changed by moving code out.
394+ tail.block ->finalize (tail.block ->type );
381395 }
382396 // since we managed a merge, then it might open up more opportunities later
383397 anotherPass = true ;
0 commit comments