rust-lang / rust-lang/portable-simd
`wasm32-unknown-unknown` doesn't use simd instructions (at least, for one particular example, but plausibly more)
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 1.1k
- Forks
- 108
- Avg merge
- 22h 53m
- Merged PRs (30d)
- 3
Description
Godbolt link: https://godbolt.org/z/KEsaM8sbh.
This function is fully scalarized to bytes under --target=wasm32-unknown-unknown -Ctarget-features=+simd128:
pub fn all_ascii_simd_std(s: &[u8; 32]) -> bool {
use core::simd::*;
const ALL_HI: u8x32 = u8x32::from_array([0x80; 32]);
const ZERO: u8x32 = u8x32::from_array([0; 32]);
(u8x32::from_array(*s) & ALL_HI).simd_eq(ZERO).all()
}
I tried:
- Adding
#[target_feature(enable = "simd128")]to it, which does not help. - Rewriting it to 2 vectors of native width (e.g.
[u8x16; 2]), which also does not help (this is also included in the example). - Changing it in a couple other ways.
And none of it helped.
This is unfortunate because WebAssembly's SIMD should be pretty efficient here -- u8x16_bitmask already only looks at the high bit, so it can avoid masking with u8x16_splat(0x80). Ideally, I'd get the same thing as:
#[target_feature(enable = "simd128")]
pub fn all_ascii_simd_wasm(s: &[u8; 32]) -> bool {
use core::arch::wasm32::*;
let a = unsafe { v128_load(s.as_ptr().cast()) };
let b = unsafe { v128_load(s.as_ptr().add(16).cast()) };
u8x16_bitmask(v128_or(a, b)) == 0
}
Or you know, something vectorized? Or even a fallback to usize SWAR? Sadly, we get nothing like that.
It is concerning that the function it does load the vectors, but then goes out of its way to convert them to bytes that the rest of the operations are performed on. This implies to me that none of the operations here are supported, meaning that core::simd doesn't use simd128 on wasm targets at all... Which might mean it's an easy fix (flip a bool somewhere?) or something to report upstream.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the Godbolt example linked in the issue and compare the generated code for core::simd on wasm32-unknown-unknown with the explicit core::arch::wasm32 version. Check the listed target features and alternative vector-width examples, then determine whether core::simd operations are unsupported or incorrectly lowered; done means the example produces vectorized output or the limitation is clearly identified.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust, wasm
- Domain
- compilers, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100