From fa978fc0dd1d1188144fe27e4f26176969b08039 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 14 Jul 2026 13:38:01 -0700 Subject: [PATCH 1/4] test --- src/cfg/cfg-traversal.h | 4 ++- src/passes/ConstraintAnalysis.cpp | 8 ++++-- test/lit/passes/constraint-analysis-cont.wast | 26 +++++++++++++++++++ 3 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 test/lit/passes/constraint-analysis-cont.wast diff --git a/src/cfg/cfg-traversal.h b/src/cfg/cfg-traversal.h index ca5021e9696..10abd9e4f0a 100644 --- a/src/cfg/cfg-traversal.h +++ b/src/cfg/cfg-traversal.h @@ -452,11 +452,13 @@ struct CFGWalker : public PostWalker { } auto handlerBlocks = BranchUtils::getUniqueTargets(*currp); // Add branches to the targets. + auto* last = self->currBasicBlock; for (auto target : handlerBlocks) { if (target) { - self->branches[target].push_back(self->currBasicBlock); + self->branches[target].push_back(last); } } + self->link(last, self->startBasicBlock()); // we might fall through } static bool isReturnCall(Expression* curr) { diff --git a/src/passes/ConstraintAnalysis.cpp b/src/passes/ConstraintAnalysis.cpp index 78d9e71df51..56747697f35 100644 --- a/src/passes/ConstraintAnalysis.cpp +++ b/src/passes/ConstraintAnalysis.cpp @@ -57,8 +57,11 @@ struct Info { BasicBlockConstraintMap startConstraints; void dump(Function* func) { - std::cout << "Info{" << actions.size() << ", " << brancher << ", " - << startConstraints << "}\n"; + std::cout << "Info{" << actions.size(); + if (brancher) { + std::cout << ", " << *brancher; + } + std::cout << ", " << startConstraints << "}\n"; } }; @@ -123,6 +126,7 @@ struct ConstraintAnalysis // Flow infos around until we have inferred all we can about the constraints // in each location. void flow() { + dumpCFG("waka"); // Start from the entry as the only reachable block. That block has incoming // values - defaults - for each var. entry->contents.startConstraints.setReachable(); diff --git a/test/lit/passes/constraint-analysis-cont.wast b/test/lit/passes/constraint-analysis-cont.wast new file mode 100644 index 00000000000..0522a073d6c --- /dev/null +++ b/test/lit/passes/constraint-analysis-cont.wast @@ -0,0 +1,26 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. + +;; RUN: wasm-opt %s --constraint-analysis -all -S -o - | filecheck %s + +(module + (type $func (func)) + (type $cont (cont $func)) + + (tag $tag (type $func)) + + (func $func (param $cont (ref $cont)) + ;; Nothing to optimize here, but we should not hit an assert while handling + ;; the resume and then the br. + (block $out + (drop + (block $in (result (ref $cont)) + (resume $cont (on $tag $in) + (local.get $cont) + ) + (br $out) + ) + ) + ) + ) +) + From 4c56c8e53e0a08b3f5b9473d3db2eafd5108d4e4 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 14 Jul 2026 14:00:35 -0700 Subject: [PATCH 2/4] test --- test/lit/passes/constraint-analysis-cont.wast | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/lit/passes/constraint-analysis-cont.wast b/test/lit/passes/constraint-analysis-cont.wast index 0522a073d6c..8a52eb520ae 100644 --- a/test/lit/passes/constraint-analysis-cont.wast +++ b/test/lit/passes/constraint-analysis-cont.wast @@ -3,11 +3,26 @@ ;; RUN: wasm-opt %s --constraint-analysis -all -S -o - | filecheck %s (module + ;; CHECK: (type $func (func)) (type $func (func)) + ;; CHECK: (type $cont (cont $func)) (type $cont (cont $func)) + ;; CHECK: (tag $tag (type $func)) (tag $tag (type $func)) + ;; CHECK: (func $func (type $2) (param $cont (ref $cont)) + ;; CHECK-NEXT: (block $out + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block $in (result (ref $cont)) + ;; CHECK-NEXT: (resume $cont (on $tag $in) + ;; CHECK-NEXT: (local.get $cont) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $out) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) (func $func (param $cont (ref $cont)) ;; Nothing to optimize here, but we should not hit an assert while handling ;; the resume and then the br. From 7512d014cac91d7f4bf261a01a51abe849d45c9b Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 14 Jul 2026 14:07:42 -0700 Subject: [PATCH 3/4] fix --- src/passes/ConstraintAnalysis.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/passes/ConstraintAnalysis.cpp b/src/passes/ConstraintAnalysis.cpp index 56747697f35..356e6e035b1 100644 --- a/src/passes/ConstraintAnalysis.cpp +++ b/src/passes/ConstraintAnalysis.cpp @@ -126,7 +126,6 @@ struct ConstraintAnalysis // Flow infos around until we have inferred all we can about the constraints // in each location. void flow() { - dumpCFG("waka"); // Start from the entry as the only reachable block. That block has incoming // values - defaults - for each var. entry->contents.startConstraints.setReachable(); From faf1d22a4fd5b533c8eca7854efa12d0c88f5d4b Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 14 Jul 2026 14:11:23 -0700 Subject: [PATCH 4/4] test --- test/lit/passes/constraint-analysis-cont.wast | 39 ++++++++++++++++++- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/test/lit/passes/constraint-analysis-cont.wast b/test/lit/passes/constraint-analysis-cont.wast index 8a52eb520ae..206597a28df 100644 --- a/test/lit/passes/constraint-analysis-cont.wast +++ b/test/lit/passes/constraint-analysis-cont.wast @@ -12,30 +12,65 @@ (tag $tag (type $func)) ;; CHECK: (func $func (type $2) (param $cont (ref $cont)) + ;; CHECK-NEXT: (local $x i32) ;; CHECK-NEXT: (block $out ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block $in (result (ref $cont)) ;; CHECK-NEXT: (resume $cont (on $tag $in) ;; CHECK-NEXT: (local.get $cont) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: (br $out) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $func (param $cont (ref $cont)) - ;; Nothing to optimize here, but we should not hit an assert while handling - ;; the resume and then the br. + (local $x i32) + (block $out (drop (block $in (result (ref $cont)) (resume $cont (on $tag $in) (local.get $cont) ) + ;; This might or might not be reached, depending on if the resume branches + ;; to $in. + (local.set $x + (i32.const 1) + ) (br $out) ) ) ) + + ;; We cannot be sure if x is 0 or 1, so nothing is optimized here. + (drop + (i32.eq + (local.get $x) + (i32.const 0) + ) + ) + (drop + (i32.eq + (local.get $x) + (i32.const 1) + ) + ) ) )