Skip to content

Commit

Permalink
Fix the vector concatenation overloads of Vector128/256
Browse files Browse the repository at this point in the history
  • Loading branch information
imhameed committed Mar 11, 2021
1 parent ca728df commit 24a89e1
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 1 deletion.
4 changes: 4 additions & 0 deletions src/mono/mono/mini/mini-llvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -7550,6 +7550,10 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
values [ins->dreg] = LLVMBuildBitCast (builder, lhs, t, "");
break;
}
case OP_XCONCAT: {
values [ins->dreg] = concatenate_vectors (ctx, lhs, rhs);
break;
}
#endif // defined(TARGET_X86) || defined(TARGET_AMD64) || defined(TARGET_ARM64) || defined(TARGET_WASM)

#if defined(TARGET_X86) || defined(TARGET_AMD64) || defined(TARGET_WASM)
Expand Down
2 changes: 2 additions & 0 deletions src/mono/mono/mini/mini-ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -1565,6 +1565,8 @@ MINI_OP(OP_XOP_OVR_SCALAR_X_X_X, "xop_ovr_scalar_x_x_x", XREG, XREG, XREG)
MINI_OP3(OP_XOP_OVR_SCALAR_X_X_X_X, "xop_ovr_scalar_x_x_x_x", XREG, XREG, XREG, XREG)
MINI_OP(OP_XOP_OVR_BYSCALAR_X_X_X, "xop_ovr_byscalar_x_x_x", XREG, XREG, XREG)

MINI_OP(OP_XCONCAT, "xconcat", XREG, XREG, XREG)

MINI_OP(OP_XCAST, "xcast", XREG, XREG, NONE)
/* Extract element of vector */
/* The index is assumed to be in range */
Expand Down
36 changes: 35 additions & 1 deletion src/mono/mono/mini/simd-intrinsics.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,15 @@ emit_xcompare (MonoCompile *cfg, MonoClass *klass, MonoTypeEnum etype, MonoInst
return ins;
}

static gboolean
is_intrinsics_vector_type (MonoType *vector_type)
{
if (vector_type->type != MONO_TYPE_GENERICINST) return FALSE;
MonoClass *klass = mono_class_from_mono_type_internal (vector_type);
const char *name = m_class_get_name (klass);
return !strcmp (name, "Vector64`1") || !strcmp (name, "Vector128`1") || !strcmp (name, "Vector256`1");
}

static MonoType*
get_vector_t_elem_type (MonoType *vector_type)
{
Expand Down Expand Up @@ -487,6 +496,28 @@ static guint16 sri_vector_methods [] = {
SN_CreateScalarUnsafe,
};

static gboolean
is_elementwise_create_overload (MonoMethodSignature *fsig, MonoType *ret_type)
{
uint16_t param_count = fsig->param_count;
if (param_count < 1) return FALSE;
MonoType *type = fsig->params [0];
gboolean is_vector_primitive = MONO_TYPE_IS_PRIMITIVE (type) && (type->type >= MONO_TYPE_I1 && type->type <= MONO_TYPE_R8);
if (!is_vector_primitive) return FALSE;
if (!mono_metadata_type_equal (ret_type, type)) return FALSE;
for (uint16_t i = 1; i < param_count; ++i)
if (!mono_metadata_type_equal (type, fsig->params [i])) return FALSE;
return TRUE;
}

static gboolean
is_create_from_half_vectors_overload (MonoMethodSignature *fsig)
{
if (fsig->param_count != 2) return FALSE;
if (!is_intrinsics_vector_type (fsig->params [0])) return FALSE;
return mono_metadata_type_equal (fsig->params [0], fsig->params [1]);
}

static MonoInst*
emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args)
{
Expand Down Expand Up @@ -519,8 +550,11 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
MonoType *etype = get_vector_t_elem_type (fsig->ret);
if (fsig->param_count == 1 && mono_metadata_type_equal (fsig->params [0], etype))
return emit_simd_ins (cfg, klass, type_to_expand_op (etype), args [0]->dreg, -1);
else
else if (is_create_from_half_vectors_overload (fsig))
return emit_simd_ins (cfg, klass, OP_XCONCAT, args [0]->dreg, args [1]->dreg);
else if (is_elementwise_create_overload (fsig, etype))
return emit_vector_create_elementwise (cfg, fsig, fsig->ret, etype, args);
break;
}
case SN_CreateScalarUnsafe:
return emit_simd_ins_for_sig (cfg, klass, OP_CREATE_SCALAR_UNSAFE, -1, arg0_type, fsig, args);
Expand Down

0 comments on commit 24a89e1

Please sign in to comment.