-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
wasm->CLIF translation: consistently bitcast V128 values that are blo… #2303
wasm->CLIF translation: consistently bitcast V128 values that are blo… #2303
Conversation
I wonder if we can wrap SmallVec fn canonicalise<'a>(
builder: &mut FunctionBuilder,
values: &'a [ir::Value],
) -> impl AsRef<[ir::Value]> + 'a {
enum Result<'a> {
Ref(&'a [ir::Value]),
Vec(SmallVec<[ir::Value; 16]>),
}
impl<'a> AsRef<[u8]> for Result<'a> {
fn as_ref(&self) -> &[u8] {
match self {
Result::Ref(r) => r,
Result::Vec(v) => v.as_slice(),
}
}
}
// do_checks_and_stuff
if ... {
Result::Vec(canonicalised)
} else {
Result::Ref(values)
}
}
// do e.g.
let params = canonicalise(builder, destination_args);
builder
.ins()
.jump(real_dest_block, params.as_ref()); It is nice to see fast path for canonicalise when SIMD is not in use too. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you create tests for this in tests/wasm or cranelift/wasmtests? I think the reason that jumps/branches weren't covered when I had to add the original bitcasts is that I believed the spec testsuite covered these cases... but apparently not.
3cdf3c7
to
6dbc573
Compare
…ck formal parameters. In the current translation of wasm (128-bit) SIMD into CLIF, we work around differences in the type system models of wasm vs CLIF by inserting `bitcast` (a no-op cast) CLIF instructions before more or less every use of a SIMD value. Unfortunately this was not being done consistently and even small examples with a single if-then-else diamond that produces a SIMD value, could cause a verification failure downstream. In this case, the jump out of the "else" block needed a bitcast, but didn't have one. This patch wraps creation of CLIF jumps and conditional branches up into three functions, `canonicalise_then_jump` and `canonicalise_then_br{z,nz}`, and uses them consistently. They first cast the relevant block formal parameters, then generate the relevant kind of branch/jump. Hence, provided they are also used consistently in future to generate branches/jumps in this file, we are protected against such failures. The patch also adds a large(ish) comment at the top explaining this in more detail.
6dbc573
to
db93e13
Compare
Thanks all for the various comments/suggestions. I pushed a revised patch that addresses all of them. |
…ck formal parameters.
In the current translation of wasm (128-bit) SIMD into CLIF, we work around differences in the
type system models of wasm vs CLIF by inserting
bitcast
(no-op casts) CLIF instructions beforemore or less every use of a SIMD value. Unfortunately this was not being done consistently and
even small examples with a single if-then-else diamond that produces a SIMD value, could cause a
verification failure downstream. In this case, the jump out of the "else" block needed a
bitcast, but didn't have one.
This patch wraps creation of CLIF jumps and conditional branches up into a pair of functions,
canonicalise_then_jump
andcanonicalise_then_br_z_or_nz
, and uses them consistently. Theyfirst cast the relevant block formal parameters, then generate the relevant kind of branch/jump.
Hence, provided they are also used consistently in future to generate branches/jumps in this
file, we are protected against such failures.
The patch also adds a large(ish) comment at the top explaining this in more detail.