Skip to content

Commit

Permalink
[mono] Optimize Vector128.Create if there are some zero elements (#91924
Browse files Browse the repository at this point in the history
)

* Optimizing initializing SIMD vectors with some zero elements.

* Fix x64 case.

* Fixed zero checking for floats.
  • Loading branch information
jandupej authored Sep 13, 2023
1 parent 9695621 commit 35fc3c0
Showing 1 changed file with 26 additions and 6 deletions.
32 changes: 26 additions & 6 deletions src/mono/mono/mini/simd-intrinsics.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,22 @@ mono_emit_simd_field_load (MonoCompile *cfg, MonoClassField *field, MonoInst *ad
return NULL;
}

static gboolean
is_zero_const (const MonoInst* ins)
{
switch (ins->opcode) {
case OP_ICONST:
return (0 == GTMREG_TO_INT (ins->inst_c0));
case OP_I8CONST:
return (0 == ins->inst_l);
case OP_R4CONST:
return (0 == *(const uint32_t*)(ins->inst_p0)); // Must be binary zero. -0.0f has a sign of 1.
case OP_R8CONST:
return (0 == *(const uint64_t*)(ins->inst_p0));
}
return FALSE;
}

static int
simd_intrinsic_compare_by_name (const void *key, const void *value)
{
Expand Down Expand Up @@ -1061,9 +1077,11 @@ emit_vector_create_elementwise (
MonoClass *vklass = mono_class_from_mono_type_internal (vtype);
MonoInst *ins = emit_xzero (cfg, vklass);
for (int i = 0; i < fsig->param_count; ++i) {
ins = emit_simd_ins (cfg, vklass, op, ins->dreg, args [i]->dreg);
ins->inst_c0 = i;
ins->inst_c1 = type;
if (!is_zero_const (args [i])) {
ins = emit_simd_ins (cfg, vklass, op, ins->dreg, args [i]->dreg);
ins->inst_c0 = i;
ins->inst_c1 = type;
}
}
return ins;
}
Expand Down Expand Up @@ -1694,9 +1712,11 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
MonoInst *ins;

ins = emit_xzero (cfg, klass);
ins = emit_simd_ins (cfg, klass, type_to_insert_op (arg0_type), ins->dreg, args [0]->dreg);
ins->inst_c0 = 0;
ins->inst_c1 = arg0_type;
if (!is_zero_const (args [0])) {
ins = emit_simd_ins (cfg, klass, type_to_insert_op (arg0_type), ins->dreg, args [0]->dreg);
ins->inst_c0 = 0;
ins->inst_c1 = arg0_type;
}
return ins;
#else
if (type_enum_is_float (arg0_type)) {
Expand Down

0 comments on commit 35fc3c0

Please sign in to comment.