Skip to content

Commit fc3e8ea

Browse files
kotlarmilosCopilot
andauthored
[clr-ios] Fix Vector<T> width and R2R AVX baseline mismatch on x64 iOS/tvOS simulators (#129012)
## Description The interpreter only supports 128-bit Vector<T>, but on Mac Catalyst and iOS simulator x64 it was ending up with 256-bit Vector<T>, which is what caused the NullReferenceException in Vector.get_IsHardwareAccelerated. The runtime already limits Vector<T> to 128-bit for the full interpreter mode, but it wasn't doing so on no-JIT builds where everything is interpreted anyway, so AVX2 on x64 silently bumped it up to 256-bit. This change applies the same 128-bit limit whenever the interpreter is the only thing running code. arm64 was never affected since Vector<T> is always 128-bit there. Crossgen2 had the matching problem where it presumed an x86-64-v3 (AVX2) ReadyToRun baseline for the Apple x64 simulator targets, so the precompiled R2R code and the interpreter disagreed on the Vector<T> width. It now uses the x86-64-v2 baseline for the iOS/tvOS simulators as well, matching osx and maccatalyst, so both share the same 128-bit view. The x64 simulators also run under Rosetta, which does not support AVX, so presuming it was incorrect regardless. As defense in depth, when an eager fixup failure disables R2R on a no-JIT runtime where the image was compiled with stripped IL bodies (so there is no IL to fall back to), the runtime now fails fast with a clear message instead of running the throw stub left in place of the IL, which previously surfaced as an opaque stack overflow. Fixes #128901 Fixes #128898 --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent e099ef5 commit fc3e8ea

4 files changed

Lines changed: 24 additions & 10 deletions

File tree

src/coreclr/tools/Common/InstructionSetHelpers.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ public static InstructionSetSupport ConfigureInstructionSetSupport(string instru
3131

3232
if ((targetArchitecture == TargetArchitecture.X86) || (targetArchitecture == TargetArchitecture.X64))
3333
{
34-
if (isReadyToRun && targetOS != TargetOS.OSX && targetOS != TargetOS.MacCatalyst)
34+
bool isAppleOS = targetOS is TargetOS.OSX or TargetOS.MacCatalyst
35+
or TargetOS.iOSSimulator or TargetOS.tvOSSimulator;
36+
37+
if (isReadyToRun && !isAppleOS)
3538
{
3639
// ReadyToRun can presume AVX2, BMI1, BMI2, F16C, FMA, LZCNT, and MOVBE
3740
instructionSetSupportBuilder.AddSupportedInstructionSet("x86-64-v3");

src/coreclr/vm/ceeload.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3588,6 +3588,14 @@ void Module::RunEagerFixupsUnlocked()
35883588
{
35893589
_ASSERTE(IsReadyToRun());
35903590
GetReadyToRunInfo()->DisableAllR2RCode();
3591+
3592+
#ifndef FEATURE_DYNAMIC_CODE_COMPILED
3593+
if (GetReadyToRunInfo()->HasStrippedILBodies())
3594+
{
3595+
EEPOLICY_HANDLE_FATAL_ERROR_WITH_MESSAGE(COR_E_EXECUTIONENGINE,
3596+
W("ReadyToRun code was disabled by a failed eager fixup, but the image has stripped IL bodies and this runtime has no JIT fallback."));
3597+
}
3598+
#endif // !FEATURE_DYNAMIC_CODE_COMPILED
35913599
}
35923600
else
35933601
{

src/coreclr/vm/codeman.cpp

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1503,7 +1503,12 @@ void EEJitManager::SetCpuInfo()
15031503
uint32_t maxVectorTBitWidth = (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_MaxVectorTBitWidth) / 128) * 128;
15041504

15051505
#if defined(FEATURE_INTERPRETER)
1506-
if (maxVectorTBitWidth != 128 && CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_InterpMode) == 3)
1506+
#if defined(FEATURE_DYNAMIC_CODE_COMPILED)
1507+
bool interpreterOnly = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_InterpMode) == 3;
1508+
#else
1509+
bool interpreterOnly = true;
1510+
#endif
1511+
if (maxVectorTBitWidth != 128 && interpreterOnly)
15071512
{
15081513
// Disable larger Vector<T> sizes when interpreter is enabled
15091514
maxVectorTBitWidth = 128;
@@ -1873,14 +1878,6 @@ void EEJitManager::SetCpuInfo()
18731878

18741879
uint32_t preferredVectorBitWidth = (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_PreferredVectorBitWidth) / 128) * 128;
18751880

1876-
#ifdef FEATURE_INTERPRETER
1877-
if (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_InterpMode) == 3)
1878-
{
1879-
// Disable larger Vector<T> sizes when interpreter is enabled, and not compiling S.P.Corelib
1880-
preferredVectorBitWidth = 128;
1881-
}
1882-
#endif
1883-
18841881
if ((preferredVectorBitWidth == 0) && throttleVector512)
18851882
{
18861883
preferredVectorBitWidth = 256;

src/coreclr/vm/readytoruninfo.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,12 @@ class ReadyToRunInfo
249249
return m_pHeader->CoreHeader.Flags & READYTORUN_FLAG_PARTIAL;
250250
}
251251

252+
BOOL HasStrippedILBodies()
253+
{
254+
LIMITED_METHOD_CONTRACT;
255+
return m_pHeader->CoreHeader.Flags & READYTORUN_FLAG_STRIPPED_IL_BODIES;
256+
}
257+
252258
void DisableAllR2RCode()
253259
{
254260
LIMITED_METHOD_CONTRACT;

0 commit comments

Comments
 (0)