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},