Skip to content

Commit dc08e2b

Browse files
authored
JIT: Stop setting class handles for promoted parameter SIMD fields (#87967)
Having these class handles floating around in the JIT is problematic during prejit where the JIT-EE calls allowed on "random" type handles (in this case the type of a field of a struct) is limited. Precursor to #87917
1 parent 369301f commit dc08e2b

File tree

3 files changed

+41
-11
lines changed

3 files changed

+41
-11
lines changed

src/coreclr/jit/codegencommon.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3017,7 +3017,20 @@ void CodeGen::genFnPrologCalleeRegArgs(regNumber xtraReg, bool* pXtraRegClobbere
30173017
#if defined(UNIX_AMD64_ABI)
30183018
if (varTypeIsStruct(varDsc))
30193019
{
3020-
CORINFO_CLASS_HANDLE typeHnd = varDsc->GetLayout()->GetClassHandle();
3020+
CORINFO_CLASS_HANDLE typeHnd;
3021+
if (varDsc->lvIsStructField)
3022+
{
3023+
// The only case we currently permit is a wrapped SIMD field,
3024+
// where we won't have the class handle available, so get it
3025+
// from the parent struct -- they will agree on ABI details.
3026+
LclVarDsc* parentDsc = compiler->lvaGetDesc(varDsc->lvParentLcl);
3027+
assert(varTypeIsSIMD(varDsc) && (parentDsc->lvFieldCnt == 1));
3028+
typeHnd = parentDsc->GetLayout()->GetClassHandle();
3029+
}
3030+
else
3031+
{
3032+
typeHnd = varDsc->GetLayout()->GetClassHandle();
3033+
}
30213034
assert(typeHnd != nullptr);
30223035
SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR structDesc;
30233036
compiler->eeGetSystemVAmd64PassStructInRegisterDescriptor(typeHnd, &structDesc);
@@ -3114,7 +3127,7 @@ void CodeGen::genFnPrologCalleeRegArgs(regNumber xtraReg, bool* pXtraRegClobbere
31143127
}
31153128
}
31163129
#if FEATURE_MULTIREG_ARGS
3117-
else if (compiler->lvaIsMultiregStruct(varDsc, compiler->info.compIsVarArgs))
3130+
else if (varDsc->lvIsMultiRegArg)
31183131
{
31193132
if (varDsc->lvIsHfaRegArg())
31203133
{
@@ -3323,7 +3336,7 @@ void CodeGen::genFnPrologCalleeRegArgs(regNumber xtraReg, bool* pXtraRegClobbere
33233336
{
33243337
// This must be a SIMD type that's fully enregistered, but is passed as an HFA.
33253338
// Each field will be inserted into the same destination register.
3326-
assert(varTypeIsSIMD(varDsc) && !compiler->isOpaqueSIMDType(varDsc->GetLayout()));
3339+
assert(varTypeIsSIMD(varDsc));
33273340
assert(regArgTab[argNum].slot <= (int)varDsc->lvHfaSlots());
33283341
assert(argNum > 0);
33293342
assert(regArgTab[argNum - 1].varNum == varNum);

src/coreclr/jit/lclvars.cpp

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2523,10 +2523,23 @@ void Compiler::StructPromotionHelper::PromoteStructVar(unsigned lclNum)
25232523
#ifdef FEATURE_SIMD
25242524
if (varTypeIsSIMD(pFieldInfo->fldType))
25252525
{
2526-
compiler->lvaSetStruct(varNum, pFieldInfo->fldTypeHnd, false);
25272526
// We will not recursively promote this, so mark it as 'lvRegStruct' (note that we wouldn't
25282527
// be promoting this if we didn't think it could be enregistered.
25292528
fieldVarDsc->lvRegStruct = true;
2529+
2530+
// SIMD types may be HFAs so we need to set the correct state on
2531+
// the promoted fields to get the right ABI treatment in the
2532+
// backend.
2533+
if (GlobalJitOptions::compFeatureHfa && (pFieldInfo->fldSize <= MAX_PASS_MULTIREG_BYTES))
2534+
{
2535+
// hfaType is set to float, double or SIMD type if it is an HFA, otherwise TYP_UNDEF
2536+
var_types hfaType = compiler->GetHfaType(pFieldInfo->fldTypeHnd);
2537+
if (varTypeIsValidHfaType(hfaType))
2538+
{
2539+
fieldVarDsc->SetHfaType(hfaType);
2540+
fieldVarDsc->lvIsMultiRegArg = (varDsc->lvIsMultiRegArg != 0) && (fieldVarDsc->lvHfaSlots() > 1);
2541+
}
2542+
}
25302543
}
25312544
#endif // FEATURE_SIMD
25322545

@@ -2986,16 +2999,20 @@ void Compiler::lvaSetStruct(unsigned varNum, ClassLayout* layout, bool unsafeVal
29862999
}
29873000
#endif // not TARGET_64BIT
29883001

2989-
unsigned classAttribs = info.compCompHnd->getClassAttribs(layout->GetClassHandle());
2990-
29913002
// Check whether this local is an unsafe value type and requires GS cookie protection.
29923003
// GS checks require the stack to be re-ordered, which can't be done with EnC.
2993-
if (unsafeValueClsCheck && (classAttribs & CORINFO_FLG_UNSAFE_VALUECLASS) && !opts.compDbgEnC)
3004+
if (unsafeValueClsCheck)
29943005
{
2995-
setNeedsGSSecurityCookie();
2996-
compGSReorderStackLayout = true;
2997-
varDsc->lvIsUnsafeBuffer = true;
3006+
unsigned classAttribs = info.compCompHnd->getClassAttribs(layout->GetClassHandle());
3007+
3008+
if ((classAttribs & CORINFO_FLG_UNSAFE_VALUECLASS) && !opts.compDbgEnC)
3009+
{
3010+
setNeedsGSSecurityCookie();
3011+
compGSReorderStackLayout = true;
3012+
varDsc->lvIsUnsafeBuffer = true;
3013+
}
29983014
}
3015+
29993016
#ifdef DEBUG
30003017
if (JitConfig.EnableExtraSuperPmiQueries())
30013018
{

src/coreclr/jit/regalloc.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ regNumber Compiler::raUpdateRegStateForArg(RegState* regState, LclVarDsc* argDsc
154154
if (argDsc->lvIsHfaRegArg())
155155
{
156156
assert(regState->rsIsFloat);
157-
unsigned cSlots = GetHfaCount(argDsc->GetLayout()->GetClassHandle());
157+
unsigned cSlots = argDsc->lvHfaSlots();
158158
for (unsigned i = 1; i < cSlots; i++)
159159
{
160160
assert(inArgReg + i <= LAST_FP_ARGREG);

0 commit comments

Comments
 (0)