@@ -2634,6 +2634,28 @@ bool Compiler::StructPromotionHelper::IsArmHfaParameter(unsigned lclNum)
2634
2634
return hfaType != CORINFO_HFA_ELEM_NONE;
2635
2635
}
2636
2636
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
+
2637
2659
// --------------------------------------------------------------------------------------------
2638
2660
// ShouldPromoteStructVar - Should a struct var be promoted if it can be promoted?
2639
2661
// This routine mainly performs profitability checks. Right now it also has
@@ -2693,10 +2715,10 @@ bool Compiler::StructPromotionHelper::ShouldPromoteStructVar(unsigned lclNum)
2693
2715
#if FEATURE_MULTIREG_STRUCT_PROMOTE
2694
2716
// Is this a variable holding a value with exactly two fields passed in
2695
2717
// multiple registers?
2696
- if (compiler-> lvaIsMultiregStruct (varDsc, compiler-> info . compIsVarArgs ))
2718
+ if (varDsc-> lvIsMultiRegArg || IsSysVMultiRegType (varDsc-> GetLayout () ))
2697
2719
{
2698
2720
if ((structPromotionInfo.fieldCnt != 2 ) &&
2699
- ! ((structPromotionInfo.fieldCnt == 1 ) && varTypeIsSIMD (structPromotionInfo.fields [0 ].fldType )))
2721
+ ((structPromotionInfo.fieldCnt != 1 ) || ! varTypeIsSIMD (structPromotionInfo.fields [0 ].fldType )))
2700
2722
{
2701
2723
JITDUMP (" Not promoting multireg struct local V%02u, because lvIsParam is true, #fields != 2 and it's "
2702
2724
" not a single SIMD.\n " ,
@@ -2713,6 +2735,7 @@ bool Compiler::StructPromotionHelper::ShouldPromoteStructVar(unsigned lclNum)
2713
2735
}
2714
2736
else
2715
2737
#endif // !FEATURE_MULTIREG_STRUCT_PROMOTE
2738
+ {
2716
2739
2717
2740
// TODO-PERF - Implement struct promotion for incoming single-register structs.
2718
2741
// Also the implementation of jmp uses the 4 byte move to store
@@ -2726,6 +2749,7 @@ bool Compiler::StructPromotionHelper::ShouldPromoteStructVar(unsigned lclNum)
2726
2749
lclNum, structPromotionInfo.fieldCnt );
2727
2750
shouldPromote = false ;
2728
2751
}
2752
+ }
2729
2753
}
2730
2754
else if ((lclNum == compiler->genReturnLocal ) && (structPromotionInfo.fieldCnt > 1 ))
2731
2755
{
0 commit comments