diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index 7a8fb916abfc1..1f8f3d3fc8853 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -3594,6 +3594,31 @@ bool Compiler::compStressCompileHelper(compStressArea stressArea, unsigned weigh return (hash < weight); } +//------------------------------------------------------------------------ +// compPromoteFewerStructs: helper to determine if the local +// should not be promoted under a stress mode. +// +// Arguments: +// lclNum - local number to test +// +// Returns: +// true if this local should not be promoted. +// +// Notes: +// Reject ~50% of the potential promotions if STRESS_PROMOTE_FEWER_STRUCTS is active. +// +bool Compiler::compPromoteFewerStructs(unsigned lclNum) +{ + bool rejectThisPromo = false; + const bool promoteLess = compStressCompile(STRESS_PROMOTE_FEWER_STRUCTS, 50); + if (promoteLess) + { + + rejectThisPromo = (((info.compMethodHash() ^ lclNum) & 1) == 0); + } + return rejectThisPromo; +} + #endif // DEBUG void Compiler::compInitDebuggingInfo() diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 6353797cb3c23..eba87e205b6c9 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -9268,6 +9268,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX STRESS_MODE(GENERIC_VARN) \ STRESS_MODE(PROFILER_CALLBACKS) /* Will generate profiler hooks for ELT callbacks */ \ STRESS_MODE(BYREF_PROMOTION) /* Change undoPromotion decisions for byrefs */ \ + STRESS_MODE(PROMOTE_FEWER_STRUCTS)/* Don't promote some structs that can be promoted */ \ \ /* After COUNT_VARN, stress level 2 does all of these all the time */ \ \ @@ -9314,6 +9315,8 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX return compStressCompile(STRESS_RANDOM_INLINE, 50); } + bool compPromoteFewerStructs(unsigned lclNum); + #endif // DEBUG bool compTailCallStress() diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index ca6e34a083e1c..7ab2f7bdc403e 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -2104,6 +2104,14 @@ bool Compiler::StructPromotionHelper::ShouldPromoteStructVar(unsigned lclNum) // TODO-1stClassStructs: a temporary solution to keep diffs small, it will be fixed later. shouldPromote = false; } +#if defined(DEBUG) + else if (compiler->compPromoteFewerStructs(lclNum)) + { + // Do not promote some structs, that can be promoted, to stress promoted/unpromoted moves. + JITDUMP("Not promoting promotable struct local V%02u, because of STRESS_PROMOTE_FEWER_STRUCTS\n", lclNum); + shouldPromote = false; + } +#endif // // If the lvRefCnt is zero and we have a struct promoted parameter we can end up with an extra store of diff --git a/src/tests/Interop/PInvoke/Vector2_3_4/Vector2_3_4.csproj b/src/tests/Interop/PInvoke/Vector2_3_4/Vector2_3_4.csproj index 78c3de24d972d..1e836849fd95b 100644 --- a/src/tests/Interop/PInvoke/Vector2_3_4/Vector2_3_4.csproj +++ b/src/tests/Interop/PInvoke/Vector2_3_4/Vector2_3_4.csproj @@ -1,6 +1,8 @@ Exe + + true diff --git a/src/tests/JIT/Methodical/xxobj/ldobj/_il_relldobj_V.ilproj b/src/tests/JIT/Methodical/xxobj/ldobj/_il_relldobj_V.ilproj index 00f4af88c13c3..3655ae36a32e1 100644 --- a/src/tests/JIT/Methodical/xxobj/ldobj/_il_relldobj_V.ilproj +++ b/src/tests/JIT/Methodical/xxobj/ldobj/_il_relldobj_V.ilproj @@ -2,6 +2,8 @@ Exe 1 + + true PdbOnly