From 25ef3e01b24c69ac78091dd735f564b8225cc55b Mon Sep 17 00:00:00 2001 From: Jordan Peck Date: Thu, 15 Oct 2026 00:26:00 +0100 Subject: [PATCH] WASM: Select with relaxed_laneselect when relaxed FastSIMD masks are all ones or all zeros per lane, so i32x4.relaxed_laneselect matches v128.bitselect and is a single blend on x64 hosts instead of and/andnot/or. Strict builds keep bitselect. --- include/FastSIMD/ToolSet/WASM/128/f32x4.h | 10 +++++++++- include/FastSIMD/ToolSet/WASM/128/i32x4.h | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/include/FastSIMD/ToolSet/WASM/128/f32x4.h b/include/FastSIMD/ToolSet/WASM/128/f32x4.h index 1b3fde1..a9b8e42 100644 --- a/include/FastSIMD/ToolSet/WASM/128/f32x4.h +++ b/include/FastSIMD/ToolSet/WASM/128/f32x4.h @@ -190,7 +190,15 @@ namespace FS template>> FS_FORCEINLINE f32<4, SIMD> Select( const typename f32<4, SIMD>::MaskTypeArg& mask, const f32<4, SIMD>& ifTrue, const f32<4, SIMD>& ifFalse ) { - return wasm_v128_bitselect( ifTrue.native, ifFalse.native, mask.native ); + if constexpr( FastSIMD::IsRelaxed() ) + { + // Mask lanes are all ones or all zeros, laneselect is a single blend on x64 hosts (bitselect is and/andnot/or) + return wasm_i32x4_relaxed_laneselect( ifTrue.native, ifFalse.native, mask.native ); + } + else + { + return wasm_v128_bitselect( ifTrue.native, ifFalse.native, mask.native ); + } } diff --git a/include/FastSIMD/ToolSet/WASM/128/i32x4.h b/include/FastSIMD/ToolSet/WASM/128/i32x4.h index f879354..d7f911d 100644 --- a/include/FastSIMD/ToolSet/WASM/128/i32x4.h +++ b/include/FastSIMD/ToolSet/WASM/128/i32x4.h @@ -156,7 +156,15 @@ namespace FS template>> FS_FORCEINLINE i32<4, SIMD> Select( const typename i32<4, SIMD>::MaskTypeArg& mask, const i32<4, SIMD>& ifTrue, const i32<4, SIMD>& ifFalse ) { - return wasm_v128_bitselect( ifTrue.native, ifFalse.native, mask.native ); + if constexpr( FastSIMD::IsRelaxed() ) + { + // Mask lanes are all ones or all zeros, laneselect is a single blend on x64 hosts (bitselect is and/andnot/or) + return wasm_i32x4_relaxed_laneselect( ifTrue.native, ifFalse.native, mask.native ); + } + else + { + return wasm_v128_bitselect( ifTrue.native, ifFalse.native, mask.native ); + } } template>>