diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj
index bbb83077d16210..14945aa2237f61 100644
--- a/src/libraries/tests.proj
+++ b/src/libraries/tests.proj
@@ -578,6 +578,11 @@
+
+
+
+
+
diff --git a/src/mono/mono/mini/mini-llvm.c b/src/mono/mono/mini/mini-llvm.c
index 8aa11b4868dfc9..b619feb93c3737 100644
--- a/src/mono/mono/mini/mini-llvm.c
+++ b/src/mono/mono/mini/mini-llvm.c
@@ -10449,20 +10449,29 @@ MONO_RESTORE_WARNING
break;
}
case OP_WASM_SIMD_SWIZZLE: {
+ LLVMValueRef bidx = LLVMBuildBitCast (builder, rhs, LLVMVectorType (i1_t, 16), "");
int nelems = LLVMGetVectorSize (LLVMTypeOf (lhs));
- if (nelems == 16) {
- LLVMValueRef args [] = { lhs, rhs };
- values [ins->dreg] = call_intrins (ctx, INTRINS_WASM_SWIZZLE, args, "");
- break;
- }
-
- LLVMValueRef indexes [16];
- for (int i = 0; i < nelems; ++i)
- indexes [i] = LLVMBuildExtractElement (builder, rhs, const_int32 (i), "");
- LLVMValueRef shuffle_val = LLVMConstNull (LLVMVectorType (i4_t, nelems));
- for (int i = 0; i < nelems; ++i)
- shuffle_val = LLVMBuildInsertElement (builder, shuffle_val, convert (ctx, indexes [i], i4_t), const_int32 (i), "");
- values [ins->dreg] = LLVMBuildShuffleVector (builder, lhs, LLVMGetUndef (LLVMTypeOf (lhs)), shuffle_val, "");
+ if (nelems < 16) {
+ int shift = nelems == 8 ? 1 : (nelems == 4 ? 2 : 3);
+ LLVMValueRef fill = LLVMConstNull (LLVMVectorType (i1_t, 16));
+ LLVMValueRef offset = LLVMConstNull (LLVMVectorType (i1_t, 16));
+ int stride = 16 / nelems;
+ for (int i = 0; i < nelems; ++i) {
+ for (int j = 0; j < stride; ++j) {
+ offset = LLVMBuildInsertElement (builder, offset, const_int8 (j), const_int8 (i * stride + j), "");
+ fill = LLVMBuildInsertElement (builder, fill, const_int8 (i * stride), const_int8 (i * stride + j), "");
+ }
+ }
+ LLVMValueRef shiftv = create_shift_vector (ctx, bidx, const_int32 (shift));
+ bidx = LLVMBuildShl (builder, bidx, shiftv, "");
+ LLVMValueRef args [] = { bidx, fill };
+ bidx = call_intrins (ctx, INTRINS_WASM_SWIZZLE, args, "");
+ bidx = LLVMBuildAdd (builder, bidx, offset, "");
+ }
+ LLVMValueRef lhs_b = LLVMBuildBitCast (builder, lhs, LLVMVectorType (i1_t, 16), "");
+ LLVMValueRef args [] = { lhs_b, bidx };
+ LLVMValueRef result_b = call_intrins (ctx, INTRINS_WASM_SWIZZLE, args, "");
+ values [ins->dreg] = LLVMBuildBitCast (builder, result_b, LLVMTypeOf (lhs), "");
break;
}
case OP_WASM_EXTRACT_NARROW: {
diff --git a/src/mono/mono/mini/simd-intrinsics.c b/src/mono/mono/mini/simd-intrinsics.c
index 069333c0a610de..9176c76be61a6b 100644
--- a/src/mono/mono/mini/simd-intrinsics.c
+++ b/src/mono/mono/mini/simd-intrinsics.c
@@ -6154,8 +6154,8 @@ static SimdIntrinsic packedsimd_methods [] = {
{SN_LoadScalarVector128},
{SN_LoadVector128, OP_LOADX_MEMBASE},
{SN_LoadWideningVector128, OP_WASM_SIMD_LOAD_WIDENING},
- {SN_Max, OP_XBINOP, OP_IMIN, OP_XBINOP, OP_IMIN_UN, OP_XBINOP, OP_FMIN},
- {SN_Min, OP_XBINOP, OP_IMAX, OP_XBINOP, OP_IMAX_UN, OP_XBINOP, OP_FMAX},
+ {SN_Max, OP_XBINOP, OP_IMAX, OP_XBINOP, OP_IMAX_UN, OP_XBINOP, OP_FMAX},
+ {SN_Min, OP_XBINOP, OP_IMIN, OP_XBINOP, OP_IMIN_UN, OP_XBINOP, OP_FMIN},
{SN_Multiply},
{SN_MultiplyRoundedSaturateQ15, OP_XOP_X_X_X, INTRINS_WASM_Q15MULR_SAT_SIGNED},
{SN_MultiplyWideningLower, OP_WASM_EXTMUL_LOWER, 0, OP_WASM_EXTMUL_LOWER_U},