Skip to content

Commit

Permalink
Optimize Vector64.Create for constants (#101662)
Browse files Browse the repository at this point in the history
  • Loading branch information
EgorBo committed May 17, 2024
1 parent 4246ba1 commit 91518ca
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 56 deletions.
96 changes: 40 additions & 56 deletions src/coreclr/jit/codegenarm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2395,73 +2395,57 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre
{
#if defined(FEATURE_SIMD)
case TYP_SIMD8:
{
if (vecCon->IsAllBitsSet())
{
emit->emitIns_R_I(INS_mvni, attr, targetReg, 0, INS_OPTS_2S);
}
else if (vecCon->IsZero())
{
emit->emitIns_R_I(INS_movi, attr, targetReg, 0, INS_OPTS_2S);
}
else
{
// Get a temp integer register to compute long address.
regNumber addrReg = internalRegisters.GetSingle(tree);

simd8_t constValue;
memcpy(&constValue, &vecCon->gtSimdVal, sizeof(simd8_t));

CORINFO_FIELD_HANDLE hnd = emit->emitSimd8Const(constValue);
emit->emitIns_R_C(INS_ldr, attr, targetReg, addrReg, hnd, 0);
}
break;
}

case TYP_SIMD12:
{
if (vecCon->IsAllBitsSet())
{
emit->emitIns_R_I(INS_mvni, attr, targetReg, 0, INS_OPTS_4S);
}
else if (vecCon->IsZero())
{
emit->emitIns_R_I(INS_movi, attr, targetReg, 0, INS_OPTS_4S);
}
else
{
// Get a temp integer register to compute long address.
regNumber addrReg = internalRegisters.GetSingle(tree);

simd16_t constValue = {};
memcpy(&constValue, &vecCon->gtSimdVal, sizeof(simd12_t));

CORINFO_FIELD_HANDLE hnd = emit->emitSimd16Const(constValue);
emit->emitIns_R_C(INS_ldr, attr, targetReg, addrReg, hnd, 0);
}
break;
}

case TYP_SIMD16:
{
// We ignore any differences between SIMD12 and SIMD16 here if we can broadcast the value
// via mvni/movi.
const bool is8 = tree->TypeIs(TYP_SIMD8);
if (vecCon->IsAllBitsSet())
{
emit->emitIns_R_I(INS_mvni, attr, targetReg, 0, INS_OPTS_4S);
emit->emitIns_R_I(INS_mvni, attr, targetReg, 0, is8 ? INS_OPTS_2S : INS_OPTS_4S);
}
else if (vecCon->IsZero())
{
emit->emitIns_R_I(INS_movi, attr, targetReg, 0, INS_OPTS_4S);
emit->emitIns_R_I(INS_movi, attr, targetReg, 0, is8 ? INS_OPTS_2S : INS_OPTS_4S);
}
else
{
// Get a temp integer register to compute long address.
regNumber addrReg = internalRegisters.GetSingle(tree);

simd16_t constValue;
memcpy(&constValue, &vecCon->gtSimdVal, sizeof(simd16_t));

CORINFO_FIELD_HANDLE hnd = emit->emitSimd16Const(constValue);
emit->emitIns_R_C(INS_ldr, attr, targetReg, addrReg, hnd, 0);
simd16_t val = vecCon->gtSimd16Val;
if (ElementsAreSame(val.i32, is8 ? 2 : 4) &&
emitter::emitIns_valid_imm_for_movi(val.i32[0], EA_4BYTE))
{
emit->emitIns_R_I(INS_movi, attr, targetReg, val.i32[0], is8 ? INS_OPTS_2S : INS_OPTS_4S);
}
else if (ElementsAreSame(val.i16, is8 ? 4 : 8) &&
emitter::emitIns_valid_imm_for_movi(val.i16[0], EA_2BYTE))
{
emit->emitIns_R_I(INS_movi, attr, targetReg, val.i16[0], is8 ? INS_OPTS_4H : INS_OPTS_8H);
}
else if (ElementsAreSame(val.i8, is8 ? 8 : 16) &&
emitter::emitIns_valid_imm_for_movi(val.i8[0], EA_1BYTE))
{
emit->emitIns_R_I(INS_movi, attr, targetReg, val.i8[0], is8 ? INS_OPTS_8B : INS_OPTS_16B);
}
else
{
// Get a temp integer register to compute long address.
regNumber addrReg = internalRegisters.GetSingle(tree);
CORINFO_FIELD_HANDLE hnd;
if (is8)
{
simd8_t constValue;
memcpy(&constValue, &vecCon->gtSimdVal, sizeof(simd8_t));
hnd = emit->emitSimd8Const(constValue);
}
else
{
simd16_t constValue;
memcpy(&constValue, &vecCon->gtSimdVal, sizeof(simd16_t));
hnd = emit->emitSimd16Const(constValue);
}
emit->emitIns_R_C(INS_ldr, attr, targetReg, addrReg, hnd, 0);
}
}
break;
}
Expand Down
11 changes: 11 additions & 0 deletions src/coreclr/jit/simd.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@
#ifndef _SIMD_H_
#define _SIMD_H_

template <typename T>
static bool ElementsAreSame(T* array, size_t size)
{
for (size_t i = 1; i < size; i++)
{
if (array[0] != array[i])
return false;
}
return true;
}

struct simd8_t
{
union
Expand Down

0 comments on commit 91518ca

Please sign in to comment.