Skip to content

Commit f99fdb7

Browse files
authored
Fix assertion failure in unsubtyping (#8148)
When noting a subtype relationship, Unsubtyping asserts that if the subtype is a tuple, then the supertype must be a tuple as well. This assertion was violated when SubtypingDiscoverer noted a subtyping between an unreachable br_if's tuple value and the br_if's type. Fix the problem by not noting this subtyping for unreachable br_ifs.
1 parent c6202f0 commit f99fdb7

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

src/ir/subtype-exprs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ struct SubtypingDiscoverer : public OverriddenVisitor<SubType> {
133133
void visitBreak(Break* curr) {
134134
if (curr->value) {
135135
self()->noteSubtype(curr->value, self()->findBreakTarget(curr->name));
136-
if (curr->condition) {
136+
if (curr->condition && curr->type != Type::unreachable) {
137137
self()->noteSubtype(curr->value, curr);
138138
}
139139
}

test/lit/passes/unsubtyping.wast

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2002,3 +2002,48 @@
20022002
)
20032003
)
20042004
)
2005+
2006+
;; Regression test for an assertion failure when br_if has a tuple value and
2007+
;; unreachable condition.
2008+
(module
2009+
;; CHECK: (rec
2010+
;; CHECK-NEXT: (type $A (sub (struct)))
2011+
(type $A (sub (struct)))
2012+
;; CHECK: (type $B (sub (struct)))
2013+
(type $B (sub $A (struct)))
2014+
;; CHECK: (type $C (sub $A (struct)))
2015+
(type $C (sub $B (struct)))
2016+
;; CHECK: (type $3 (func (param (ref $C)) (result (ref $A) (ref $A))))
2017+
2018+
;; CHECK: (func $test (type $3) (param $C (ref $C)) (result (ref $A) (ref $A))
2019+
;; CHECK-NEXT: (local $Bs (tuple (ref $B) (ref $B)))
2020+
;; CHECK-NEXT: (block $l
2021+
;; CHECK-NEXT: (local.tee $Bs
2022+
;; CHECK-NEXT: (block
2023+
;; CHECK-NEXT: (tuple.drop 2
2024+
;; CHECK-NEXT: (tuple.make 2
2025+
;; CHECK-NEXT: (local.get $C)
2026+
;; CHECK-NEXT: (local.get $C)
2027+
;; CHECK-NEXT: )
2028+
;; CHECK-NEXT: )
2029+
;; CHECK-NEXT: (unreachable)
2030+
;; CHECK-NEXT: )
2031+
;; CHECK-NEXT: )
2032+
;; CHECK-NEXT: )
2033+
;; CHECK-NEXT: )
2034+
(func $test (param $C (ref $C)) (result (ref $A) (ref $A))
2035+
(local $Bs (tuple (ref $B) (ref $B)))
2036+
(block $l (result (ref $A) (ref $A))
2037+
(local.set $Bs
2038+
;; Because the br_if is unreachable, we do not record $C <: $B.
2039+
(br_if $l
2040+
(tuple.make 2
2041+
(local.get $C)
2042+
(local.get $C)
2043+
)
2044+
(unreachable)
2045+
)
2046+
)
2047+
)
2048+
)
2049+
)

0 commit comments

Comments
 (0)