Skip to content

[WebAssembly] manual splat not recognized #178940

@folkertdev

Description

@folkertdev

The wasm backend does not recognize a manual splat, while other backends do. For e.g. s390x vectors are not part of the baseline, and the pattern is only recognized when the vector target feature is enabled. For wasm, enabling +simd128 still does not recognize the splat.

https://llvm.godbolt.org/z/z3Ma9fTja

For instance this IR

define dso_local void @foo(i16 noundef %v, ptr noalias noundef writeonly align 1 captures(none) dereferenceable(16) initializes((0, 16)) %p) unnamed_addr #0 {
start:
  store i16 %v, ptr %p, align 1
  %_5.sroa.4.0.p.sroa_idx = getelementptr inbounds nuw i8, ptr %p, i32 2
  store i16 %v, ptr %_5.sroa.4.0.p.sroa_idx, align 1
  %_5.sroa.5.0.p.sroa_idx = getelementptr inbounds nuw i8, ptr %p, i32 4
  store i16 %v, ptr %_5.sroa.5.0.p.sroa_idx, align 1
  %_5.sroa.6.0.p.sroa_idx = getelementptr inbounds nuw i8, ptr %p, i32 6
  store i16 %v, ptr %_5.sroa.6.0.p.sroa_idx, align 1
  %_5.sroa.7.0.p.sroa_idx = getelementptr inbounds nuw i8, ptr %p, i32 8
  store i16 %v, ptr %_5.sroa.7.0.p.sroa_idx, align 1
  %_5.sroa.8.0.p.sroa_idx = getelementptr inbounds nuw i8, ptr %p, i32 10
  store i16 %v, ptr %_5.sroa.8.0.p.sroa_idx, align 1
  %_5.sroa.9.0.p.sroa_idx = getelementptr inbounds nuw i8, ptr %p, i32 12
  store i16 %v, ptr %_5.sroa.9.0.p.sroa_idx, align 1
  %_5.sroa.10.0.p.sroa_idx = getelementptr inbounds nuw i8, ptr %p, i32 14
  store i16 %v, ptr %_5.sroa.10.0.p.sroa_idx, align 1
  ret void
}

should optimize to

define dso_local void @foo(i16 noundef %v, ptr noalias noundef writeonly align 1 captures(none) dereferenceable(16) initializes((0, 16)) %p) unnamed_addr #0 {
start:
  %0 = insertelement <8 x i16> poison, i16 %v, i64 0
  %1 = shufflevector <8 x i16> %0, <8 x i16> poison, <8 x i32> zeroinitializer
  store <8 x i16> %1, ptr %p, align 1
  ret void
}

LLVM does just that for most targets, but not on webassembly.

This manual splat pattern is not uncommon in rust when array expressions are used, see rust-lang/rust#97804. Previously other backends also did not optimize this pattern, that was tracked in #55994 but the issue was silently resolved.

Metadata

Metadata

Assignees

No one assigned

    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