Skip to content

Commit fb5e6ef

Browse files
authored
[Multibyte] Fix GUFA on multibyte reads of different types (#8531)
Previously we'd filter i8 data with an i64 read into nothing.
1 parent cfe7c54 commit fb5e6ef

2 files changed

Lines changed: 72 additions & 0 deletions

File tree

src/ir/possible-contents.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2976,6 +2976,17 @@ void Flower::filterExpressionContents(PossibleContents& contents,
29762976
std::cout << "TNHOracle informs us that " << *exprLoc.expr << " contains "
29772977
<< maximalContents << "\n";
29782978
#endif
2979+
2980+
if (exprLoc.expr->is<ArrayLoad>()) {
2981+
// ArrayLoad cannot filter, as we can have writes of different sizes than
2982+
// the type of the location (e.g. write i32, do an i64.load). If there is
2983+
// any content, just report the maximal content, basically like a Memory.
2984+
if (!contents.isNone()) {
2985+
contents = maximalContents;
2986+
}
2987+
return;
2988+
}
2989+
29792990
contents.intersect(maximalContents);
29802991
if (contents.isNone()) {
29812992
// Nothing was left here at all.
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
2+
;; RUN: foreach %s %t wasm-opt -all --gufa --closed-world -S -o - | filecheck %s
3+
4+
(module
5+
;; CHECK: (type $0 (func))
6+
7+
;; CHECK: (type $array (array (mut i8)))
8+
(type $array (array (mut i8)))
9+
10+
;; CHECK: (export "test" (func $test))
11+
12+
;; CHECK: (func $test (type $0)
13+
;; CHECK-NEXT: (drop
14+
;; CHECK-NEXT: (i64.load32_u (type $array)
15+
;; CHECK-NEXT: (array.new_default $array
16+
;; CHECK-NEXT: (i32.const 69)
17+
;; CHECK-NEXT: )
18+
;; CHECK-NEXT: (i32.const 0)
19+
;; CHECK-NEXT: )
20+
;; CHECK-NEXT: )
21+
;; CHECK-NEXT: )
22+
(func $test (export "test")
23+
;; We initialize with i8s, and read an i64. That should not confuse us, and
24+
;; we do not optimize here (though we could, in theory, if we tracked the
25+
;; bytes and saw the i64 must be 0).
26+
(drop
27+
(i64.load32_u (type $array)
28+
(array.new_default $array
29+
(i32.const 69)
30+
)
31+
(i32.const 0)
32+
)
33+
)
34+
)
35+
)
36+
37+
(module
38+
;; CHECK: (type $array (array (mut i8)))
39+
(type $array (array (mut i8)))
40+
41+
;; CHECK: (type $1 (func (param (ref $array))))
42+
43+
;; CHECK: (export "test" (func $test))
44+
45+
;; CHECK: (func $test (type $1) (param $array (ref $array))
46+
;; CHECK-NEXT: (drop
47+
;; CHECK-NEXT: (unreachable)
48+
;; CHECK-NEXT: )
49+
;; CHECK-NEXT: )
50+
(func $test (export "test") (param $array (ref $array))
51+
;; As above, but now no $array is ever created (and we are in closed world).
52+
;; We can optimize this to trap.
53+
(drop
54+
(i64.load32_u (type $array)
55+
(local.get $array)
56+
(i32.const 0)
57+
)
58+
)
59+
)
60+
)
61+

0 commit comments

Comments
 (0)