Skip to content

Commit 7d2f80d

Browse files
authored
Update LocalSubtyping for exact references (#7355)
After calculating the best possible type for a local, LocalSubtyping then checks to see whether the local can be non-nullable based on whether all of its gets are dominated by sets. If it cannot be non-nullable, the new type is adjusted to be nullable. This adjustment did not previously preserve exactness, causing an assertion that the optimization improves the type to fail. Fix the adjustment and add a test.
1 parent 894c770 commit 7d2f80d

File tree

3 files changed

+42
-1
lines changed

3 files changed

+42
-1
lines changed

scripts/test/fuzzing.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@
104104
# TODO: fuzzer support for exact references
105105
'exact-references.wast',
106106
'optimize-instructions-exact.wast',
107+
'local-subtyping-exact.wast',
107108
]
108109

109110

src/passes/LocalSubtyping.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,8 @@ struct LocalSubtyping : public WalkerPass<PostWalker<LocalSubtyping>> {
152152
// Remove non-nullability if we disallow that in locals.
153153
if (newType.isNonNullable()) {
154154
if (cannotBeNonNullable.count(i)) {
155-
newType = Type(newType.getHeapType(), Nullable);
155+
newType =
156+
Type(newType.getHeapType(), Nullable, newType.getExactness());
156157
}
157158
} else if (!newType.isDefaultable()) {
158159
// Aside from the case we just handled of allowed non-nullability, we
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited.
2+
3+
;; Check that LocalSubtyping handles exact references properly when it
4+
;; determines that a local that would otherwise be non-nullable must be nullable
5+
;; because of control flow dominance constraints.
6+
7+
;; RUN: wasm-opt %s -all --local-subtyping -S -o - | filecheck %s
8+
9+
(module
10+
;; CHECK: (func $test (type $0) (param $0 (exact nullref)) (result anyref)
11+
;; CHECK-NEXT: (local $1 (exact nullref))
12+
;; CHECK-NEXT: (if
13+
;; CHECK-NEXT: (i32.const 0)
14+
;; CHECK-NEXT: (then
15+
;; CHECK-NEXT: (local.set $1
16+
;; CHECK-NEXT: (ref.as_non_null
17+
;; CHECK-NEXT: (local.get $0)
18+
;; CHECK-NEXT: )
19+
;; CHECK-NEXT: )
20+
;; CHECK-NEXT: )
21+
;; CHECK-NEXT: )
22+
;; CHECK-NEXT: (local.get $1)
23+
;; CHECK-NEXT: )
24+
(func $test (param (exact nullref)) (result anyref)
25+
(local (exact nullref))
26+
(if
27+
(i32.const 0)
28+
(then
29+
(local.set 1
30+
;; This would let the local be (ref exact none) if it dominated the get.
31+
(ref.as_non_null
32+
(local.get 0)
33+
)
34+
)
35+
)
36+
)
37+
(local.get 1)
38+
)
39+
)

0 commit comments

Comments
 (0)