Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix RefNull issues #3123

Merged
merged 3 commits into from
Sep 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/ir/ExpressionAnalyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ template<typename T> void visitImmediates(Expression* curr, T& visitor) {
visitor.visitInt(curr->op);
visitor.visitNonScopeName(curr->nameOperand);
}
void visitRefNull(RefNull* curr) {}
void visitRefNull(RefNull* curr) { visitor.visitType(curr->type); }
void visitRefIsNull(RefIsNull* curr) {}
void visitRefFunc(RefFunc* curr) { visitor.visitNonScopeName(curr->func); }
void visitTry(Try* curr) {}
Expand Down
9 changes: 6 additions & 3 deletions src/passes/Precompute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,12 @@ struct Precompute
curr->finalize();
return;
}
} else if (singleValue.isNull() &&
curr->value->template is<RefNull>()) {
return;
} else if (singleValue.isNull()) {
if (auto* n = curr->value->template dynCast<RefNull>()) {
n->finalize(singleValue.type);
curr->finalize();
return;
}
} else if (singleValue.type == Type::funcref) {
if (auto* r = curr->value->template dynCast<RefFunc>()) {
r->func = singleValue.getFunc();
Expand Down
5 changes: 3 additions & 2 deletions src/tools/execution-results.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ struct ExecutionResults {
// change (after duplicate function elimination or roundtripping)
// while the function contents are still the same
for (Literal& val : ret) {
if (val.type == Type::funcref) {
if (val.type == Type::funcref && !val.isNull()) {
val = Literal::makeFunc(Name("funcref"));
}
}
Expand Down Expand Up @@ -112,7 +112,8 @@ struct ExecutionResults {
}
std::cout << "[fuzz-exec] comparing " << name << '\n';
if (results[name] != other.results[name]) {
std::cout << "not identical!\n";
std::cout << "not identical! " << results[name]
<< " != " << other.results[name] << "\n";
return false;
}
}
Expand Down
11 changes: 9 additions & 2 deletions test/passes/optimize-instructions_all-features.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
(type $i64_=>_i64 (func (param i64) (result i64)))
(type $i32_i64_f32_=>_none (func (param i32 i64 f32)))
(type $i32_i64_f32_f64_=>_none (func (param i32 i64 f32 f64)))
(type $none_=>_anyref (func (result anyref)))
(type $i32_i32_i32_=>_none (func (param i32 i32 i32)))
(type $i32_i32_f64_f64_=>_none (func (param i32 i32 f64 f64)))
(type $i32_i64_f64_i32_=>_none (func (param i32 i64 f64 i32)))
(type $none_=>_f64 (func (result f64)))
(type $none_=>_anyref (func (result anyref)))
(memory $0 0)
(export "load-off-2" (func $load-off-2))
(func $f (param $i1 i32) (param $i2 i64)
Expand Down Expand Up @@ -3712,9 +3712,16 @@
(unreachable)
)
)
(func $if-arms-subtype (result anyref)
(func $if-arms-subtype-fold (result anyref)
(ref.null extern)
)
(func $if-arms-subtype-nofold (result anyref)
(if (result anyref)
(i32.const 0)
(ref.null extern)
(ref.null func)
)
)
(func $optimize-boolean-context (param $x i32) (param $y i32)
(if
(local.get $x)
Expand Down
13 changes: 11 additions & 2 deletions test/passes/optimize-instructions_all-features.wast
Original file line number Diff line number Diff line change
Expand Up @@ -4207,8 +4207,17 @@
(unreachable)
)
)
;; Tests when if arms are subtype of if's type
(func $if-arms-subtype (result anyref)
;; These functions test if an `if` with subtyped arms is correctly folded
;; 1. if its `ifTrue` and `ifFalse` arms are identical (can fold)
(func $if-arms-subtype-fold (result anyref)
(if (result anyref)
(i32.const 0)
(ref.null extern)
(ref.null extern)
)
)
;; 2. if its `ifTrue` and `ifFalse` arms are not identical (cannot fold)
(func $if-arms-subtype-nofold (result anyref)
(if (result anyref)
(i32.const 0)
(ref.null extern)
Expand Down