Skip to content

Commit debd246

Browse files
authored
Fix BranchUtils::operateOnScopeNameUsesAndSentValues() on BrOn (#6995)
BrOn does not always send a value. This is an odd asymmetry in the wasm spec, where br_on_null does not send the null on the branch (which makes sense, but the asymmetry does mean we need to special-case it).
1 parent 930034f commit debd246

File tree

2 files changed

+56
-10
lines changed

2 files changed

+56
-10
lines changed

src/ir/branch-utils.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,8 @@ void operateOnScopeNameUsesAndSentValues(Expression* expr, T func) {
108108
} else if (auto* sw = expr->dynCast<Switch>()) {
109109
func(name, sw->value);
110110
} else if (auto* br = expr->dynCast<BrOn>()) {
111-
func(name, br->ref);
111+
// A value may not be sent (e.g. BrOnNull does *not* send a null).
112+
func(name, br->getSentType() != Type::none ? br->ref : nullptr);
112113
} else if (expr->is<TryTable>()) {
113114
// The values are supplied by throwing instructions, so we are unable to
114115
// know what they will be here.

test/lit/passes/gufa-refs.wast

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6058,15 +6058,17 @@
60586058
)
60596059

60606060
(module
6061+
;; CHECK: (type $0 (func (result i64 nullref i32)))
6062+
60616063
;; CHECK: (type $array (sub (array (mut i8))))
60626064
(type $array (sub (array (mut i8))))
60636065

6064-
;; CHECK: (type $1 (func))
6066+
;; CHECK: (type $2 (func))
60656067

60666068
;; CHECK: (global $global (ref null $array) (array.new_fixed $array 0))
60676069
(global $global (ref null $array) (array.new_fixed $array 0))
60686070

6069-
;; CHECK: (func $test (type $1)
6071+
;; CHECK: (func $test-set-bottom (type $2)
60706072
;; CHECK-NEXT: (block ;; (replaces unreachable ArraySet we can't emit)
60716073
;; CHECK-NEXT: (drop
60726074
;; CHECK-NEXT: (ref.cast nullref
@@ -6082,15 +6084,58 @@
60826084
;; CHECK-NEXT: (unreachable)
60836085
;; CHECK-NEXT: )
60846086
;; CHECK-NEXT: )
6085-
(func $test
6087+
(func $test-set-bottom
60866088
;; We should not error on sets to bottom types, even if they are cast from
60876089
;; valid values.
60886090
(array.set $array
6089-
(ref.cast nullref
6090-
(global.get $global)
6091-
)
6092-
(i32.const 0)
6093-
(i32.const 0)
6094-
)
6091+
(ref.cast nullref
6092+
(global.get $global)
6093+
)
6094+
(i32.const 0)
6095+
(i32.const 0)
6096+
)
6097+
)
6098+
6099+
;; CHECK: (func $loop-tuple-br_on (type $2)
6100+
;; CHECK-NEXT: (tuple.drop 3
6101+
;; CHECK-NEXT: (loop $loop (type $0) (result i64 nullref i32)
6102+
;; CHECK-NEXT: (drop
6103+
;; CHECK-NEXT: (block
6104+
;; CHECK-NEXT: (drop
6105+
;; CHECK-NEXT: (br_on_null $loop
6106+
;; CHECK-NEXT: (ref.null none)
6107+
;; CHECK-NEXT: )
6108+
;; CHECK-NEXT: )
6109+
;; CHECK-NEXT: (unreachable)
6110+
;; CHECK-NEXT: )
6111+
;; CHECK-NEXT: )
6112+
;; CHECK-NEXT: (tuple.make 3
6113+
;; CHECK-NEXT: (i64.const 1)
6114+
;; CHECK-NEXT: (ref.null none)
6115+
;; CHECK-NEXT: (i32.const 2)
6116+
;; CHECK-NEXT: )
6117+
;; CHECK-NEXT: )
6118+
;; CHECK-NEXT: )
6119+
;; CHECK-NEXT: )
6120+
(func $loop-tuple-br_on
6121+
;; The br_on here does not send any values when it branches. This is a test
6122+
;; for a bug where it did send the null along, which then caused an
6123+
;; assertion when we tried to combine the null with the tuple that flows
6124+
;; out.
6125+
(tuple.drop 3
6126+
(loop $loop (result i64 anyref i32)
6127+
(drop
6128+
;; As this br always happens, we can add an unreachable after it.
6129+
(br_on_null $loop
6130+
(ref.null any)
6131+
)
6132+
)
6133+
(tuple.make 3
6134+
(i64.const 1)
6135+
(ref.null any)
6136+
(i32.const 2)
6137+
)
6138+
)
6139+
)
60956140
)
60966141
)

0 commit comments

Comments
 (0)