-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Are the wasm simd shl/shr intrinsics sound? #137941
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
Comments
Yes, this is a plain bug, it needs to mask |
Yes the documentation reflects the wasm intrinsic, and agreed it's a bug that should be fixed. If codegen regresses then that would ideally lead to an issue to improve it on LLVM's side, but the definition here should nevertheless change even if it regresses slightly. |
Also, to dispel any doubt since this is simd-related, this is indeed a problem where with today's nightly: use core::arch::wasm32::*;
#[no_mangle]
pub extern "C" fn foo(a: v128) -> v128 {
i8x16_shl(a, 100)
} compiles to define dso_local <4 x i32> @foo(<4 x i32> %a) unnamed_addr #0 !dbg !5 {
ret <4 x i32> undef, !dbg !26
} |
This commit fixes an issue where simd shift intrinsic in LLVM are undefined behavior if the shift amount is larger than the bit width of the lane. While in WebAssembly the corresponding instructions are defined as masking out the upper bits we need to represent that explicitly in LLVM IR to ensure that the semantics remain defined. cc rust-lang/rust#137941
(sorry for multiple comments) I've posted a fix to rust-lang/stdarch#1737 and additionally confirmed that adding this shift doesn't actually affect codegen, so once that's merged and ready I think this can be closed on the update of rust-lang/rust's stdarch submodule. |
This commit fixes an issue where simd shift intrinsic in LLVM are undefined behavior if the shift amount is larger than the bit width of the lane. While in WebAssembly the corresponding instructions are defined as masking out the upper bits we need to represent that explicitly in LLVM IR to ensure that the semantics remain defined. cc rust-lang/rust#137941
This commit fixes an issue where simd shift intrinsic in LLVM are undefined behavior if the shift amount is larger than the bit width of the lane. While in WebAssembly the corresponding instructions are defined as masking out the upper bits we need to represent that explicitly in LLVM IR to ensure that the semantics remain defined. cc rust-lang/rust#137941
This can be closed now, the stdarch PR was merged and the submodule in this repository has been updated to include it. (Can be verified by checking source of the intrinsics in nightly docs, e.g., https://doc.rust-lang.org/nightly/core/arch/wasm/fn.i8x16_shl.html). |
I found this in stdarch:
However,
simd_shl
is UB when the shift amount exceeds the bitwidth. So the implementation does not seem to match what the doc comment says?Cc @alexcrichton @Amanieu @workingjubilee
The text was updated successfully, but these errors were encountered: