From 79f6c73c565ab5f3c6f71bdb7f3ba57ad1fd8615 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Fri, 22 May 2026 21:32:19 -0700 Subject: [PATCH] Fix refinalization for --gufa-cast-all In #8747 we refactored GUFA's `replaceCurrent` to set `optimized = true` and removed the now-redundant `optimized = true` at all the call sites. But we were too aggressive and removed an `optimized = true` in `Adder`, which had a separate `replaceCurrent` that did not set `optimized = true`. This caused a regression where we no longer refinalized after adding casts, but the regression was not caught by any tests. Fix the bug and add a test that depends on refinalization after adding casts. --- src/passes/GUFA.cpp | 1 + test/lit/passes/gufa-cast-all.wast | 41 ++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/passes/GUFA.cpp b/src/passes/GUFA.cpp index addba6b7ee3..533c033524e 100644 --- a/src/passes/GUFA.cpp +++ b/src/passes/GUFA.cpp @@ -388,6 +388,7 @@ struct GUFAOptimizer if (oracleType.isRef() && oracleType != curr->type && Type::isSubType(oracleType, curr->type)) { replaceCurrent(Builder(*getModule()).makeRefCast(curr, oracleType)); + optimized = true; } } }; diff --git a/test/lit/passes/gufa-cast-all.wast b/test/lit/passes/gufa-cast-all.wast index bffd88e7714..a1675982f08 100644 --- a/test/lit/passes/gufa-cast-all.wast +++ b/test/lit/passes/gufa-cast-all.wast @@ -454,3 +454,44 @@ ) ) ) + +(module + ;; CHECK: (type $struct (struct)) + (type $struct (struct)) + + ;; CHECK: (type $1 (func (result (ref $struct)))) + + ;; CHECK: (global $g (mut (ref null $struct)) (struct.new_default $struct)) + (global $g (mut (ref null $struct)) (struct.new $struct)) + + ;; CHECK: (func $test (type $1) (result (ref $struct)) + ;; CHECK-NEXT: (ref.cast (ref (exact $struct)) + ;; CHECK-NEXT: (block $block (result (ref (exact $struct))) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.cast (ref (exact $struct)) + ;; CHECK-NEXT: (br_on_cast $block (ref (exact $struct)) (ref (exact $struct)) + ;; CHECK-NEXT: (ref.cast (ref (exact $struct)) + ;; CHECK-NEXT: (global.get $g) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $test (result (ref $struct)) + (block $block (result (ref $struct)) + (drop + (br_on_cast $block (ref null $struct) (ref $struct) + ;; This will be cast to (ref (exact $struct)). We must refinalize to + ;; update the br_on_cast output to (ref (exact $struct)) as well to + ;; maintain the validation condition that the cast output is a subtype + ;; of its input. + (global.get $g) + ) + ) + (unreachable) + ) + ) +)