Skip to content

wasm32-unknown-unknown doesn't use simd instructions (at least, for one particular example, but plausibly more) #320

@thomcc

Description

@thomcc

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions