From 01a569e1365f0f2cccc70fe94691f989c1ab83c2 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Fri, 24 Jan 2025 10:59:09 -0800 Subject: [PATCH 1/3] fix --- src/passes/GlobalTypeOptimization.cpp | 12 ++++++++++++ test/lit/passes/gto-removals.wast | 24 ++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/src/passes/GlobalTypeOptimization.cpp b/src/passes/GlobalTypeOptimization.cpp index b2ba23b0feb..3d006468fc7 100644 --- a/src/passes/GlobalTypeOptimization.cpp +++ b/src/passes/GlobalTypeOptimization.cpp @@ -22,6 +22,7 @@ // * Fields that are never read from can be removed entirely. // +#include "ir/eh-utils.h" #include "ir/localize.h" #include "ir/module-utils.h" #include "ir/ordering.h" @@ -453,6 +454,8 @@ struct GlobalTypeOptimization : public Pass { return std::make_unique(parent); } + bool needEHFixups = false; + void visitStructNew(StructNew* curr) { if (curr->type == Type::unreachable) { return; @@ -476,6 +479,8 @@ struct GlobalTypeOptimization : public Pass { ChildLocalizer localizer( curr, getFunction(), *getModule(), getPassOptions()); replaceCurrent(localizer.getReplacement()); + // Adding a block here requires EH fixups. + needEHFixups = true; // Remove and reorder operands. Index removed = 0; @@ -519,6 +524,7 @@ struct GlobalTypeOptimization : public Pass { getFunction(), getModule(), getPassOptions()); + needEHFixups = true; Expression* replacement = builder.makeDrop(builder.makeRefAs(RefAsNonNull, flipped)); if (curr->order == MemoryOrder::SeqCst) { @@ -545,6 +551,12 @@ struct GlobalTypeOptimization : public Pass { curr->index = newIndex; } + void visitFunction(Function* curr) { + if (needEHFixups) { + EHUtils::handleBlockNestedPops(curr, *getModule()); + } + } + private: Index getNewIndex(HeapType type, Index index) { auto iter = parent.indexesAfterRemovals.find(type); diff --git a/test/lit/passes/gto-removals.wast b/test/lit/passes/gto-removals.wast index 6ab126611ea..85cf2660de2 100644 --- a/test/lit/passes/gto-removals.wast +++ b/test/lit/passes/gto-removals.wast @@ -1627,3 +1627,27 @@ ) ) ) + +;; A struct with a pop, which requires EH fixups to avoid popping in a nested +;; block. +(module + ( type $i32 (func (param i32))) + + (type $struct (struct (field (mut i32)))) + + (tag $tag (type $i32) (param i32)) + + (func $func + (try + (do + ) + (catch $tag + (drop + (struct.new $struct + (pop i32) + ) + ) + ) + ) + ) +) From 6a2e45ffd960b5bb3db726cfb4d0cb0303eac27b Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Fri, 24 Jan 2025 10:59:36 -0800 Subject: [PATCH 2/3] test --- test/lit/passes/gto-removals.wast | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/test/lit/passes/gto-removals.wast b/test/lit/passes/gto-removals.wast index 85cf2660de2..bf168d84ff8 100644 --- a/test/lit/passes/gto-removals.wast +++ b/test/lit/passes/gto-removals.wast @@ -1633,10 +1633,38 @@ (module ( type $i32 (func (param i32))) + ;; CHECK: (rec + ;; CHECK-NEXT: (type $struct (struct)) (type $struct (struct (field (mut i32)))) + ;; CHECK: (type $1 (func)) + + ;; CHECK: (type $i32 (func (param i32))) + + ;; CHECK: (tag $tag (type $i32) (param i32)) (tag $tag (type $i32) (param i32)) + ;; CHECK: (func $func (type $1) + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (try + ;; CHECK-NEXT: (do + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (catch $tag + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (pop i32) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result (ref $struct)) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (struct.new_default $struct) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) (func $func (try (do From fc4bc0a3e33f87954740798a4ee188f600a857a9 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Fri, 24 Jan 2025 11:01:39 -0800 Subject: [PATCH 3/3] typo --- test/lit/passes/gto-removals.wast | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/lit/passes/gto-removals.wast b/test/lit/passes/gto-removals.wast index bf168d84ff8..e02430a3634 100644 --- a/test/lit/passes/gto-removals.wast +++ b/test/lit/passes/gto-removals.wast @@ -1631,7 +1631,7 @@ ;; A struct with a pop, which requires EH fixups to avoid popping in a nested ;; block. (module - ( type $i32 (func (param i32))) + (type $i32 (func (param i32))) ;; CHECK: (rec ;; CHECK-NEXT: (type $struct (struct))