Skip to content
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
18 changes: 18 additions & 0 deletions src/coreclr/jit/hwintrinsicarm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1613,6 +1613,9 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
assert(sig->numArgs == 2);
var_types simdType = getSIMDTypeForSize(simdSize);

impSpillSideEffect(true,
verCurrentState.esStackDepth - 2 DEBUGARG("Spilling op1 side effects for HWIntrinsic"));

op2 = impPopStack().val;
op1 = impSIMDPopStack(simdType);

Expand All @@ -1633,6 +1636,9 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
break;
}

impSpillSideEffect(true,
verCurrentState.esStackDepth - 2 DEBUGARG("Spilling op1 side effects for HWIntrinsic"));

op2 = impPopStack().val;
op1 = impSIMDPopStack(simdType);

Expand All @@ -1653,6 +1659,9 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
break;
}

impSpillSideEffect(true,
verCurrentState.esStackDepth - 2 DEBUGARG("Spilling op1 side effects for HWIntrinsic"));

op2 = impPopStack().val;
op1 = impSIMDPopStack(simdType);

Expand All @@ -1669,11 +1678,20 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,

if (sig->numArgs == 3)
{
impSpillSideEffect(true, verCurrentState.esStackDepth -
3 DEBUGARG("Spilling op1 side effects for HWIntrinsic"));

impSpillSideEffect(true, verCurrentState.esStackDepth -
2 DEBUGARG("Spilling op2 side effects for HWIntrinsic"));

op3 = impPopStack().val;
}
else
{
assert(sig->numArgs == 2);

impSpillSideEffect(true, verCurrentState.esStackDepth -
2 DEBUGARG("Spilling op1 side effects for HWIntrinsic"));
}

op2 = impPopStack().val;
Expand Down
49 changes: 47 additions & 2 deletions src/coreclr/jit/hwintrinsicxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -461,8 +461,12 @@ GenTree* Compiler::impNonConstFallback(NamedIntrinsic intrinsic, var_types simdT
case NI_AVX2_ShiftRightArithmetic:
case NI_AVX2_ShiftRightLogical:
{
impSpillSideEffect(true,
verCurrentState.esStackDepth - 2 DEBUGARG("Spilling op1 side effects for HWIntrinsic"));

GenTree* op2 = impPopStack().val;
GenTree* op1 = impSIMDPopStack(simdType);

GenTree* tmpOp =
gtNewSimdHWIntrinsicNode(TYP_SIMD16, op2, NI_SSE2_ConvertScalarToVector128Int32, CORINFO_TYPE_INT, 16);
return gtNewSimdHWIntrinsicNode(simdType, op1, tmpOp, intrinsic, simdBaseJitType, genTypeSize(simdType));
Expand Down Expand Up @@ -2159,6 +2163,9 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic,
assert(sig->numArgs == 2);
var_types simdType = getSIMDTypeForSize(simdSize);

impSpillSideEffect(true,
verCurrentState.esStackDepth - 2 DEBUGARG("Spilling op1 side effects for HWIntrinsic"));

op2 = impPopStack().val;
op1 = impSIMDPopStack(simdType);

Expand Down Expand Up @@ -2187,6 +2194,9 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic,
assert(sig->numArgs == 2);
var_types simdType = getSIMDTypeForSize(simdSize);

impSpillSideEffect(true,
verCurrentState.esStackDepth - 2 DEBUGARG("Spilling op1 side effects for HWIntrinsic"));

op2 = impPopStack().val;
op1 = impSIMDPopStack(simdType);

Expand Down Expand Up @@ -2215,6 +2225,9 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic,
assert(sig->numArgs == 2);
var_types simdType = getSIMDTypeForSize(simdSize);

impSpillSideEffect(true,
verCurrentState.esStackDepth - 2 DEBUGARG("Spilling op1 side effects for HWIntrinsic"));

op2 = impPopStack().val;
op1 = impSIMDPopStack(simdType);

Expand Down Expand Up @@ -2244,11 +2257,20 @@ GenTree* Compiler::impBaseIntrinsic(NamedIntrinsic intrinsic,

if (sig->numArgs == 3)
{
impSpillSideEffect(true, verCurrentState.esStackDepth -
3 DEBUGARG("Spilling op1 side effects for HWIntrinsic"));

impSpillSideEffect(true, verCurrentState.esStackDepth -
2 DEBUGARG("Spilling op2 side effects for HWIntrinsic"));

op3 = impPopStack().val;
}
else
{
assert(sig->numArgs == 2);

impSpillSideEffect(true, verCurrentState.esStackDepth -
2 DEBUGARG("Spilling op1 side effects for HWIntrinsic"));
}

op2 = impPopStack().val;
Expand Down Expand Up @@ -2496,12 +2518,21 @@ GenTree* Compiler::impSSEIntrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HAND
case NI_SSE_CompareScalarNotGreaterThanOrEqual:
{
assert(sig->numArgs == 2);

bool supportsAvx = compOpportunisticallyDependsOn(InstructionSet_AVX);

if (!supportsAvx)
{
impSpillSideEffect(true, verCurrentState.esStackDepth -
2 DEBUGARG("Spilling op1 side effects for HWIntrinsic"));
}

op2 = impSIMDPopStack(TYP_SIMD16);
op1 = impSIMDPopStack(TYP_SIMD16);
simdBaseJitType = getBaseJitTypeOfSIMDType(sig->retTypeSigClass);
assert(JitType2PreciseVarType(simdBaseJitType) == TYP_FLOAT);

if (compOpportunisticallyDependsOn(InstructionSet_AVX))
if (supportsAvx)
{
// These intrinsics are "special import" because the non-AVX path isn't directly
// hardware supported. Instead, they start with "swapped operands" and we fix that here.
Expand Down Expand Up @@ -2568,11 +2599,20 @@ GenTree* Compiler::impSSE2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HAN
case NI_SSE2_CompareScalarNotGreaterThanOrEqual:
{
assert(sig->numArgs == 2);

bool supportsAvx = compOpportunisticallyDependsOn(InstructionSet_AVX);

if (!supportsAvx)
{
impSpillSideEffect(true, verCurrentState.esStackDepth -
2 DEBUGARG("Spilling op1 side effects for HWIntrinsic"));
}

op2 = impSIMDPopStack(TYP_SIMD16);
op1 = impSIMDPopStack(TYP_SIMD16);
assert(JitType2PreciseVarType(simdBaseJitType) == TYP_DOUBLE);

if (compOpportunisticallyDependsOn(InstructionSet_AVX))
if (supportsAvx)
{
// These intrinsics are "special import" because the non-AVX path isn't directly
// hardware supported. Instead, they start with "swapped operands" and we fix that here.
Expand Down Expand Up @@ -2641,9 +2681,14 @@ GenTree* Compiler::impAvxOrAvx2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHO
case NI_AVX2_PermuteVar8x32:
{
simdBaseJitType = getBaseJitTypeOfSIMDType(sig->retTypeSigClass);

impSpillSideEffect(true,
verCurrentState.esStackDepth - 2 DEBUGARG("Spilling op1 side effects for HWIntrinsic"));

// swap the two operands
GenTree* indexVector = impSIMDPopStack(TYP_SIMD32);
GenTree* sourceVector = impSIMDPopStack(TYP_SIMD32);

retNode = gtNewSimdHWIntrinsicNode(TYP_SIMD32, indexVector, sourceVector, NI_AVX2_PermuteVar8x32,
simdBaseJitType, 32);
break;
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2563,7 +2563,7 @@ inline void Compiler::impEvalSideEffects()
* i is the stack entry which will be checked and spilled.
*/

inline void Compiler::impSpillSideEffect(bool spillGlobEffects, unsigned i DEBUGARG(const char* reason))
void Compiler::impSpillSideEffect(bool spillGlobEffects, unsigned i DEBUGARG(const char* reason))
{
assert(i <= verCurrentState.esStackDepth);

Expand Down
12 changes: 12 additions & 0 deletions src/coreclr/jit/simdashwintrinsic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,12 @@ GenTree* Compiler::impSimdAsHWIntrinsic(NamedIntrinsic intrinsic,

case 2:
{
if (SimdAsHWIntrinsicInfo::SpillSideEffectsOp1(intrinsic))
{
impSpillSideEffect(true, verCurrentState.esStackDepth -
2 DEBUGARG("Spilling op1 side effects for SimdAsHWIntrinsic"));
}

CORINFO_ARG_LIST_HANDLE arg2 = isInstanceMethod ? argList : info.compCompHnd->getArgNext(argList);
argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg2, &argClass)));
op2 = getArgForHWIntrinsic(argType, argClass);
Expand Down Expand Up @@ -909,6 +915,12 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic,

case 2:
{
if (SimdAsHWIntrinsicInfo::SpillSideEffectsOp1(intrinsic))
{
impSpillSideEffect(true, verCurrentState.esStackDepth -
2 DEBUGARG("Spilling op1 side effects for SimdAsHWIntrinsic"));
}

CORINFO_ARG_LIST_HANDLE arg2 = isInstanceMethod ? argList : info.compCompHnd->getArgNext(argList);
argType = JITtype2varType(strip(info.compCompHnd->getArgType(sig, arg2, &argClass)));
op2 = getArgForHWIntrinsic(argType, argClass);
Expand Down
9 changes: 9 additions & 0 deletions src/coreclr/jit/simdashwintrinsic.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ enum class SimdAsHWIntrinsicFlag : unsigned int

// For SIMDVectorHandle, keep the base type from the result type
KeepBaseTypeFromRet = 0x10,

// Indicates that side effects need to be spilled for op1
SpillSideEffectsOp1 = 0x20,
};

inline SimdAsHWIntrinsicFlag operator~(SimdAsHWIntrinsicFlag value)
Expand Down Expand Up @@ -142,6 +145,12 @@ struct SimdAsHWIntrinsicInfo
SimdAsHWIntrinsicFlag flags = lookupFlags(id);
return (flags & SimdAsHWIntrinsicFlag::KeepBaseTypeFromRet) == SimdAsHWIntrinsicFlag::KeepBaseTypeFromRet;
}

static bool SpillSideEffectsOp1(NamedIntrinsic id)
{
SimdAsHWIntrinsicFlag flags = lookupFlags(id);
return (flags & SimdAsHWIntrinsicFlag::SpillSideEffectsOp1) == SimdAsHWIntrinsicFlag::SpillSideEffectsOp1;
}
};

#endif // _SIMD_AS_HWINTRINSIC_H_
Loading