WASM+simd128 codegen of `a.simd_eq(Simd::splat(b)).any()` deteriorates as width increases
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
The compiler lowers the following code to a 200+ instruction long scalar sequence on WASM+simd128:
#![feature(portable_simd)]
use core::simd::prelude::*;
fn f(a: u16x32, b: u16) -> bool {
a.simd_eq(Simd::splat(b)).any()
}
The 256-bit wide version could also arguably use some work (for example could be compiled like this), but it's not catastrophically heavy and I don't really have any benchmarks to claim that it's slow.
Meta
rustc --version --verbose:
rustc 1.78.0-nightly (c67326b06 2024-03-15)
binary: rustc
commit-hash: c67326b063bd27ed04f306ba2e372cd92e0a8751
commit-date: 2024-03-15
host: x86_64-unknown-linux-gnu
release: 1.78.0-nightly
LLVM version: 18.1.0
Compiler returned: 0
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 provided Rust portable_simd reproducer and inspect its WASM+simd128 output using the linked Godbolt example. Trace the compiler codegen path for simd_eq, splat, and any; done means the u16x32 case no longer lowers to a 200+ instruction scalar sequence, with the 256-bit variant considered separately.
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
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100