Skip to content

Commit 643facd

Browse files
authored
Fix RefNull issues (#3123)
* ExpressionAnalyzer: Fix `ref.null ht` equality check to include `ht`. * Precompute: Fix `ref.null ht` expression reuse to also update `ht`. * Fuzzing: Fix `ref.null func` becoming canonicalized to `ref.func $funcref` when evaluating execution results, by adding a check for `isNull`. * Fuzzing: Print actual and expected execution results when aborting. * Tests: Update `if-arms-subtype` test in `optimize-instructions` to check that identical `if` arms become folded while not identical arms are kept.
1 parent 0c53fb5 commit 643facd

File tree

5 files changed

+30
-10
lines changed

5 files changed

+30
-10
lines changed

src/ir/ExpressionAnalyzer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ template<typename T> void visitImmediates(Expression* curr, T& visitor) {
219219
visitor.visitInt(curr->op);
220220
visitor.visitNonScopeName(curr->nameOperand);
221221
}
222-
void visitRefNull(RefNull* curr) {}
222+
void visitRefNull(RefNull* curr) { visitor.visitType(curr->type); }
223223
void visitRefIsNull(RefIsNull* curr) {}
224224
void visitRefFunc(RefFunc* curr) { visitor.visitNonScopeName(curr->func); }
225225
void visitTry(Try* curr) {}

src/passes/Precompute.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,12 @@ struct Precompute
134134
curr->finalize();
135135
return;
136136
}
137-
} else if (singleValue.isNull() &&
138-
curr->value->template is<RefNull>()) {
139-
return;
137+
} else if (singleValue.isNull()) {
138+
if (auto* n = curr->value->template dynCast<RefNull>()) {
139+
n->finalize(singleValue.type);
140+
curr->finalize();
141+
return;
142+
}
140143
} else if (singleValue.type == Type::funcref) {
141144
if (auto* r = curr->value->template dynCast<RefFunc>()) {
142145
r->func = singleValue.getFunc();

src/tools/execution-results.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ struct ExecutionResults {
7373
// change (after duplicate function elimination or roundtripping)
7474
// while the function contents are still the same
7575
for (Literal& val : ret) {
76-
if (val.type == Type::funcref) {
76+
if (val.type == Type::funcref && !val.isNull()) {
7777
val = Literal::makeFunc(Name("funcref"));
7878
}
7979
}
@@ -112,7 +112,8 @@ struct ExecutionResults {
112112
}
113113
std::cout << "[fuzz-exec] comparing " << name << '\n';
114114
if (results[name] != other.results[name]) {
115-
std::cout << "not identical!\n";
115+
std::cout << "not identical! " << results[name]
116+
<< " != " << other.results[name] << "\n";
116117
return false;
117118
}
118119
}

test/passes/optimize-instructions_all-features.txt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010
(type $i64_=>_i64 (func (param i64) (result i64)))
1111
(type $i32_i64_f32_=>_none (func (param i32 i64 f32)))
1212
(type $i32_i64_f32_f64_=>_none (func (param i32 i64 f32 f64)))
13+
(type $none_=>_anyref (func (result anyref)))
1314
(type $i32_i32_i32_=>_none (func (param i32 i32 i32)))
1415
(type $i32_i32_f64_f64_=>_none (func (param i32 i32 f64 f64)))
1516
(type $i32_i64_f64_i32_=>_none (func (param i32 i64 f64 i32)))
1617
(type $none_=>_f64 (func (result f64)))
17-
(type $none_=>_anyref (func (result anyref)))
1818
(memory $0 0)
1919
(export "load-off-2" (func $load-off-2))
2020
(func $f (param $i1 i32) (param $i2 i64)
@@ -3712,9 +3712,16 @@
37123712
(unreachable)
37133713
)
37143714
)
3715-
(func $if-arms-subtype (result anyref)
3715+
(func $if-arms-subtype-fold (result anyref)
37163716
(ref.null extern)
37173717
)
3718+
(func $if-arms-subtype-nofold (result anyref)
3719+
(if (result anyref)
3720+
(i32.const 0)
3721+
(ref.null extern)
3722+
(ref.null func)
3723+
)
3724+
)
37183725
(func $optimize-boolean-context (param $x i32) (param $y i32)
37193726
(if
37203727
(local.get $x)

test/passes/optimize-instructions_all-features.wast

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4207,8 +4207,17 @@
42074207
(unreachable)
42084208
)
42094209
)
4210-
;; Tests when if arms are subtype of if's type
4211-
(func $if-arms-subtype (result anyref)
4210+
;; These functions test if an `if` with subtyped arms is correctly folded
4211+
;; 1. if its `ifTrue` and `ifFalse` arms are identical (can fold)
4212+
(func $if-arms-subtype-fold (result anyref)
4213+
(if (result anyref)
4214+
(i32.const 0)
4215+
(ref.null extern)
4216+
(ref.null extern)
4217+
)
4218+
)
4219+
;; 2. if its `ifTrue` and `ifFalse` arms are not identical (cannot fold)
4220+
(func $if-arms-subtype-nofold (result anyref)
42124221
(if (result anyref)
42134222
(i32.const 0)
42144223
(ref.null extern)

0 commit comments

Comments
 (0)