@@ -2634,6 +2634,28 @@ bool Compiler::StructPromotionHelper::IsArmHfaParameter(unsigned lclNum)
26342634 return hfaType != CORINFO_HFA_ELEM_NONE;
26352635}
26362636
2637+ // --------------------------------------------------------------------------------------------
2638+ // IsSysVMultiRegType - Check if a type is one that could be passed in 2
2639+ // registers in some cases.
2640+ // This is a quirk to match old promotion behavior.
2641+ //
2642+ // Arguments:
2643+ // lclNum - The local
2644+ //
2645+ // Return value:
2646+ // True if it sometimes may be passed in two registers.
2647+ //
2648+ bool Compiler::StructPromotionHelper::IsSysVMultiRegType (ClassLayout* layout)
2649+ {
2650+ #ifdef UNIX_AMD64_ABI
2651+ SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR structDesc;
2652+ compiler->eeGetSystemVAmd64PassStructInRegisterDescriptor (layout->GetClassHandle (), &structDesc);
2653+ return structDesc.passedInRegisters && (structDesc.eightByteCount == 2 );
2654+ #else
2655+ return false ;
2656+ #endif
2657+ }
2658+
26372659// --------------------------------------------------------------------------------------------
26382660// ShouldPromoteStructVar - Should a struct var be promoted if it can be promoted?
26392661// This routine mainly performs profitability checks. Right now it also has
@@ -2693,10 +2715,10 @@ bool Compiler::StructPromotionHelper::ShouldPromoteStructVar(unsigned lclNum)
26932715#if FEATURE_MULTIREG_STRUCT_PROMOTE
26942716 // Is this a variable holding a value with exactly two fields passed in
26952717 // multiple registers?
2696- if (compiler-> lvaIsMultiregStruct (varDsc, compiler-> info . compIsVarArgs ))
2718+ if (varDsc-> lvIsMultiRegArg || IsSysVMultiRegType (varDsc-> GetLayout () ))
26972719 {
26982720 if ((structPromotionInfo.fieldCnt != 2 ) &&
2699- ! ((structPromotionInfo.fieldCnt == 1 ) && varTypeIsSIMD (structPromotionInfo.fields [0 ].fldType )))
2721+ ((structPromotionInfo.fieldCnt != 1 ) || ! varTypeIsSIMD (structPromotionInfo.fields [0 ].fldType )))
27002722 {
27012723 JITDUMP (" Not promoting multireg struct local V%02u, because lvIsParam is true, #fields != 2 and it's "
27022724 " not a single SIMD.\n " ,
@@ -2713,6 +2735,7 @@ bool Compiler::StructPromotionHelper::ShouldPromoteStructVar(unsigned lclNum)
27132735 }
27142736 else
27152737#endif // !FEATURE_MULTIREG_STRUCT_PROMOTE
2738+ {
27162739
27172740 // TODO-PERF - Implement struct promotion for incoming single-register structs.
27182741 // Also the implementation of jmp uses the 4 byte move to store
@@ -2726,6 +2749,7 @@ bool Compiler::StructPromotionHelper::ShouldPromoteStructVar(unsigned lclNum)
27262749 lclNum, structPromotionInfo.fieldCnt );
27272750 shouldPromote = false ;
27282751 }
2752+ }
27292753 }
27302754 else if ((lclNum == compiler->genReturnLocal ) && (structPromotionInfo.fieldCnt > 1 ))
27312755 {
0 commit comments