Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[mono][interp] Add Vector128.EqualsAny simd intrinsic #95901

Merged
merged 2 commits into from
Dec 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/mono/mono/mini/interp/interp-simd-intrins.def
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ INTERP_SIMD_INTRINSIC_P_PP (INTERP_SIMD_INTRINSIC_V128_I4_EQUALS, interp_v128_i4
INTERP_SIMD_INTRINSIC_P_PP (INTERP_SIMD_INTRINSIC_V128_R4_EQUALS, interp_v128_r4_equals, 65)
INTERP_SIMD_INTRINSIC_P_PP (INTERP_SIMD_INTRINSIC_V128_I8_EQUALS, interp_v128_i8_equals, 214)

INTERP_SIMD_INTRINSIC_P_PP (INTERP_SIMD_INTRINSIC_V128_I1_EQUALS_ANY, interp_v128_i1_equals_any, -1)
INTERP_SIMD_INTRINSIC_P_PP (INTERP_SIMD_INTRINSIC_V128_I2_EQUALS_ANY, interp_v128_i2_equals_any, -1)
INTERP_SIMD_INTRINSIC_P_PP (INTERP_SIMD_INTRINSIC_V128_I4_EQUALS_ANY, interp_v128_i4_equals_any, -1)
INTERP_SIMD_INTRINSIC_P_PP (INTERP_SIMD_INTRINSIC_V128_I8_EQUALS_ANY, interp_v128_i8_equals_any, -1)

INTERP_SIMD_INTRINSIC_P_P (INTERP_SIMD_INTRINSIC_V128_I1_CREATE_SCALAR, interp_v128_i1_create_scalar, -1)
INTERP_SIMD_INTRINSIC_P_P (INTERP_SIMD_INTRINSIC_V128_I2_CREATE_SCALAR, interp_v128_i2_create_scalar, -1)
INTERP_SIMD_INTRINSIC_P_P (INTERP_SIMD_INTRINSIC_V128_I4_CREATE_SCALAR, interp_v128_i4_create_scalar, -1)
Expand Down
37 changes: 37 additions & 0 deletions src/mono/mono/mini/interp/interp-simd.c
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,43 @@ interp_v128_i8_equals (gpointer res, gpointer v1, gpointer v2)
*(v128_i8*)res = *(v128_i8*)v1 == *(v128_i8*)v2;
}

// EqualsAny
static void
interp_v128_i1_equals_any (gpointer res, gpointer v1, gpointer v2)
{
v128_i1 resv = *(v128_i1*)v1 == *(v128_i1*)v2;

gint64 *resv_cast = (gint64*)&resv;
*(gint32*)res = *resv_cast || *(resv_cast + 1);
}

static void
interp_v128_i2_equals_any (gpointer res, gpointer v1, gpointer v2)
{
v128_i2 resv = *(v128_i2*)v1 == *(v128_i2*)v2;

gint64 *resv_cast = (gint64*)&resv;
*(gint32*)res = *resv_cast || *(resv_cast + 1);
}

static void
interp_v128_i4_equals_any (gpointer res, gpointer v1, gpointer v2)
{
v128_i4 resv = *(v128_i4*)v1 == *(v128_i4*)v2;

gint64 *resv_cast = (gint64*)&resv;
*(gint32*)res = *resv_cast || *(resv_cast + 1);
}

static void
interp_v128_i8_equals_any (gpointer res, gpointer v1, gpointer v2)
{
v128_i8 resv = *(v128_i8*)v1 == *(v128_i8*)v2;

gint64 *resv_cast = (gint64*)&resv;
*(gint32*)res = *resv_cast || *(resv_cast + 1);
}

// CreateScalar
static void
interp_v128_i1_create_scalar (gpointer res, gpointer v1)
Expand Down
1 change: 1 addition & 0 deletions src/mono/mono/mini/interp/mintops.h
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ typedef enum {
#define MINT_IS_STIND(op) ((op) >= MINT_STIND_I1 && (op) <= MINT_STIND_REF)
#define MINT_IS_LDIND_OFFSET(op) ((op) >= MINT_LDIND_OFFSET_I1 && (op) <= MINT_LDIND_OFFSET_I8)
#define MINT_IS_SIMD_CREATE(op) ((op) >= MINT_SIMD_V128_I1_CREATE && (op) <= MINT_SIMD_V128_I8_CREATE)
#define MINT_IS_RETURN(op) (((op) >= MINT_RET && (op) <= MINT_RET_U2) || (op) == MINT_RET_I4_IMM || (op) == MINT_RET_I8_IMM)

// TODO Add more
#define MINT_NO_SIDE_EFFECTS(op) (MINT_IS_MOV (op) || MINT_IS_LDC_I4 (op) || MINT_IS_LDC_I8 (op) || op == MINT_LDC_R4 || op == MINT_LDC_R8 || op == MINT_LDPTR || op == MINT_BOX)
Expand Down
1 change: 1 addition & 0 deletions src/mono/mono/mini/interp/simd-methods.def
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ SIMD_METHOD(CreateScalar)
SIMD_METHOD(CreateScalarUnsafe)

SIMD_METHOD(Equals)
SIMD_METHOD(EqualsAny)
SIMD_METHOD(EqualsFloatingPoint)
SIMD_METHOD(ExtractMostSignificantBits)
SIMD_METHOD(GreaterThan)
Expand Down
8 changes: 8 additions & 0 deletions src/mono/mono/mini/interp/transform-simd.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ static guint16 sri_vector128_methods [] = {
SN_CreateScalar,
SN_CreateScalarUnsafe,
SN_Equals,
SN_EqualsAny,
SN_ExtractMostSignificantBits,
SN_GreaterThan,
SN_LessThan,
Expand Down Expand Up @@ -419,6 +420,13 @@ emit_sri_vector128 (TransformData *td, MonoMethod *cmethod, MonoMethodSignature
else if (atype == MONO_TYPE_I8 || atype == MONO_TYPE_U8) simd_intrins = INTERP_SIMD_INTRINSIC_V128_I8_EQUALS;
else if (atype == MONO_TYPE_R4) simd_intrins = INTERP_SIMD_INTRINSIC_V128_R4_EQUALS;
break;
case SN_EqualsAny:
simd_opcode = MINT_SIMD_INTRINS_P_PP;
if (atype == MONO_TYPE_I1 || atype == MONO_TYPE_U1) simd_intrins = INTERP_SIMD_INTRINSIC_V128_I1_EQUALS_ANY;
else if (atype == MONO_TYPE_I2 || atype == MONO_TYPE_U2) simd_intrins = INTERP_SIMD_INTRINSIC_V128_I2_EQUALS_ANY;
else if (atype == MONO_TYPE_I4 || atype == MONO_TYPE_U4) simd_intrins = INTERP_SIMD_INTRINSIC_V128_I4_EQUALS_ANY;
else if (atype == MONO_TYPE_I8 || atype == MONO_TYPE_U8) simd_intrins = INTERP_SIMD_INTRINSIC_V128_I8_EQUALS_ANY;
break;
case SN_ExtractMostSignificantBits:
simd_opcode = MINT_SIMD_INTRINS_P_P;
if (arg_size == 1) simd_intrins = INTERP_SIMD_INTRINSIC_V128_I1_EXTRACT_MSB;
Expand Down
11 changes: 11 additions & 0 deletions src/mono/mono/mini/interp/transform.c
Original file line number Diff line number Diff line change
Expand Up @@ -8511,6 +8511,16 @@ emit_compacted_instruction (TransformData *td, guint16* start_ip, InterpInst *in
*ip++ = 0xbeef;
}
} else if (MINT_IS_UNCONDITIONAL_BRANCH (opcode) || MINT_IS_CONDITIONAL_BRANCH (opcode) || MINT_IS_SUPER_BRANCH (opcode)) {
if (opcode == MINT_BR) {
InterpInst *target_first_ins = interp_first_ins (ins->info.target_bb);
if (target_first_ins && MINT_IS_RETURN (target_first_ins->opcode)) {
// Emit the return directly instead of branching
ins = target_first_ins;
opcode = ins->opcode;
ip [-1] = opcode;
goto opcode_emit;
}
}
const int br_offset = GPTRDIFF_TO_INT (start_ip - td->new_code);
gboolean has_imm = opcode >= MINT_BEQ_I4_IMM_SP && opcode <= MINT_BLT_UN_I8_IMM_SP;
for (int i = 0; i < mono_interp_op_sregs [opcode]; i++)
Expand Down Expand Up @@ -8650,6 +8660,7 @@ emit_compacted_instruction (TransformData *td, guint16* start_ip, InterpInst *in
*ip++ = GINT_TO_UINT16 (ins->data [1]);
*ip++ = GINT_TO_UINT16 (ins->data [2]);
} else {
opcode_emit:
if (mono_interp_op_dregs [opcode])
*ip++ = GINT_TO_UINT16 (get_local_offset (td, ins->dreg));

Expand Down