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

Lower branches with unsupported extra values in IRBuilder #7202

Merged
merged 9 commits into from
Jan 11, 2025

Conversation

tlively
Copy link
Member

@tlively tlively commented Jan 9, 2025

WebAssembly allows all branch instructions to carry an arbitrary number
of values, but Binaryen IR only supports this for br, br_if, and
br_table. Previously we failed to parse any other branches that sent
additional arguments. To be able to parse more standard modules, support
extra values sent by other branches by lowering them away using scratch
locals and trampolines in IRBuilder. For now, only lower BrOn
expressions with extra values. Lowering for other branches will be done
in follow-on commits.

Fixes #7182.

WebAssembly allows all branch instructions to carry an arbitrary number
of values, but Binaryen IR only supports this for br, br_on, and
br_table. Previously we failed to parse any other branches that sent
additional arguments. To be able to parse more standard modules, support
extra values sent by other branches by lowering them away using scratch
locals and trampolines in IRBuilder. For now, only lower BrOn
expressions with extra values. Lowering for other branches will be done
in follow-on commits.

WIP because there are still several tests to write. The existing tests
suffice to get a sense of how horrible these lowerings are, though.
@tlively tlively requested a review from kripken January 9, 2025 07:29
@tlively tlively marked this pull request as draft January 9, 2025 07:29
@tlively tlively marked this pull request as ready for review January 10, 2025 22:57
@tlively tlively changed the title [WIP] Lower branches with unsupported extra values in IRBuilder Lower branches with unsupported extra values in IRBuilder Jan 10, 2025
@tlively tlively requested a review from kripken January 10, 2025 23:06
@tlively
Copy link
Member Author

tlively commented Jan 10, 2025

@kripken This should be ready for real review now.

}
static ScopeCtx
makeTryTable(TryTable* trytable, Name originalLabel, Type inputType) {
return ScopeCtx(TryTableScope{trytable, originalLabel}, inputType);
}

void resetForDelimiter(bool keepInput) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps add a comment for this? Reading e.g. makeElse it's not obvious to me what this does, or what "input" refers to in "keepInput".

Comment on lines 1012 to 1013
if (auto* block = curr->dynCast<Block>();
block && (!block->name || block->name == label)) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I should undo this change.

@@ -1058,14 +1039,14 @@ Result<> IRBuilder::visitEnd() {
this->func = nullptr;
blockHint = 0;
labelHint = 0;
} else if (auto* block = scope.getBlock()) {
assert(*expr == block);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I should put the assertion back.

break;
}

// If the value under test is unreachable, then we can proceed without putting
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth doing this? We could leave it for dce.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have to bail out here because we don't know what types to use for the scratch locals. I'll clarify the comment.

(import "env" "i32" (global $i32 (mut i32)))
;; CHECK: (import "env" "i32" (global $i64 (mut i64)))
;; OPT_O: (import "env" "i32" (global $i64 (mut i64)))
(import "env" "i32" (global $i64 (mut i64)))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
(import "env" "i32" (global $i64 (mut i64)))
(import "env" "i64" (global $i64 (mut i64)))

purely for aesthetic reasons

@kripken
Copy link
Member

kripken commented Jan 11, 2025

About testing, we won't be getting any fuzzing support for this, unfortunately, since it isn't in the IR. Perhaps we could add a fuzz generator that emits stacky wat or something like that, but it sounds like a lot of work. Another option might be to bundle a few wasm files with such code, that would then at least be used as initial content (but they'd be lowered immediately, so not mutated on the form that matters most).

@tlively
Copy link
Member Author

tlively commented Jan 11, 2025

Another option would be to use wasm-tools smith to generate fuzz test cases, but even that would be nontrivial. We'll probably get the most bang for our buck by just making sure there are spec tests that exercise these patterns.

@kripken
Copy link
Member

kripken commented Jan 11, 2025

Makes sense, spec tests seem best.

lgtm with the comments above (spec tests can be later, either way).

@tlively
Copy link
Member Author

tlively commented Jan 11, 2025

I'll look into spec tests as a follow-up.

@tlively tlively enabled auto-merge (squash) January 11, 2025 01:41
@tlively tlively disabled auto-merge January 11, 2025 04:50
@tlively tlively enabled auto-merge (squash) January 11, 2025 04:50
@tlively tlively disabled auto-merge January 11, 2025 04:50
@tlively tlively merged commit 63be8c0 into main Jan 11, 2025
13 checks passed
@tlively tlively deleted the lower-br-on-values branch January 11, 2025 04:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Multivalue block types optimisation fails
2 participants