Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit f06134e

Browse files
committed
Don't struct-promote opaque vectors
The hardware vector types: `Vector64<T>`, `Vector128<T>` and `Vector256<T>` are declared as having one or more fields of `ulong`. However, the JIT shouldn't be promoting these fields to local variables. It is almost never the right type, and the intrinsics in any case are not designed to cooperate with promoted fields (i.e. an index of a `Vector<ulong>` won't map to the promoted lclVar). Most importantly, it causes all copies of the vector to be done as 64-bit integer loads and stores. Finally, it will be important, as we support vector ABIs, to distinguish the handling of the fixed-size vectors (`Vector2`, `Vector3` and `Vector4`) which *are* considered to be normal structs of N floats, from the opaque types which will be passed in vector registers.
1 parent 71f259c commit f06134e

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

src/jit/compiler.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7640,6 +7640,17 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
76407640
return NO_CLASS_HANDLE;
76417641
}
76427642

7643+
// Returns true if this is a SIMD type that should be considered an opaque
7644+
// vector type (i.e. do not analyze or promote its fields).
7645+
// Note that all but the fixed vector types are opaque, even though they may
7646+
// actually be declared as having fields.
7647+
bool isOpaqueSIMDType(CORINFO_CLASS_HANDLE structHandle)
7648+
{
7649+
return ((m_simdHandleCache != nullptr) && (structHandle != m_simdHandleCache->SIMDVector2Handle) &&
7650+
(structHandle != m_simdHandleCache->SIMDVector3Handle) &&
7651+
(structHandle != m_simdHandleCache->SIMDVector4Handle));
7652+
}
7653+
76437654
// Returns true if the tree corresponds to a TYP_SIMD lcl var.
76447655
// Note that both SIMD vector args and locals are mared as lvSIMDType = true, but
76457656
// type of an arg node is TYP_BYREF and a local node is TYP_SIMD or TYP_STRUCT.
@@ -7648,6 +7659,16 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
76487659
return tree->OperIsLocal() && lvaTable[tree->AsLclVarCommon()->gtLclNum].lvSIMDType;
76497660
}
76507661

7662+
// Returns true if the lclVar is an opaque SIMD type.
7663+
bool isOpaqueSIMDLclVar(LclVarDsc* varDsc)
7664+
{
7665+
if (!varDsc->lvSIMDType)
7666+
{
7667+
return false;
7668+
}
7669+
return isOpaqueSIMDType(varDsc->lvVerTypeInfo.GetClassHandle());
7670+
}
7671+
76517672
// Returns true if the type of the tree is a byref of TYP_SIMD
76527673
bool isAddrOfSIMDType(GenTree* tree)
76537674
{
@@ -7987,6 +8008,11 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
79878008
return lvaSIMDInitTempVarNum;
79888009
}
79898010

8011+
#else // !FEATURE_SIMD
8012+
bool isOpaqueSIMDLclVar(LclVarDsc* varDsc)
8013+
{
8014+
return false;
8015+
}
79908016
#endif // FEATURE_SIMD
79918017

79928018
public:

src/jit/morph.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16973,7 +16973,7 @@ void Compiler::fgPromoteStructs()
1697316973

1697416974
// If we have marked this as lvUsedInSIMDIntrinsic, then we do not want to promote
1697516975
// its fields. Instead, we will attempt to enregister the entire struct.
16976-
if (varDsc->lvIsSIMDType() && varDsc->lvIsUsedInSIMDIntrinsic())
16976+
if (varDsc->lvIsSIMDType() && (varDsc->lvIsUsedInSIMDIntrinsic() || isOpaqueSIMDLclVar(varDsc)))
1697716977
{
1697816978
varDsc->lvRegStruct = true;
1697916979
}

0 commit comments

Comments
 (0)