From 662718345459a71ac4212f6241d98d25d7caf78c Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Fri, 25 Mar 2022 08:22:30 -0700 Subject: [PATCH] JIT: block some struct promotion for OSR (#67131) This undoes part of #65903. OSR methods can't rely solely on their own analysis for struct promotion as they only see parts of methods. --- src/coreclr/jit/lclvars.cpp | 8 ++ src/tests/JIT/opt/OSR/invalidpromotion.cs | 73 +++++++++++++++++++ src/tests/JIT/opt/OSR/invalidpromotion.csproj | 30 ++++++++ 3 files changed, 111 insertions(+) create mode 100644 src/tests/JIT/opt/OSR/invalidpromotion.cs create mode 100644 src/tests/JIT/opt/OSR/invalidpromotion.csproj diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index f888b756a69..64f4dd690b8 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -1851,6 +1851,14 @@ bool Compiler::StructPromotionHelper::CanPromoteStructVar(unsigned lclNum) return false; } + // If the local was exposed at Tier0, we currently have to assume it's aliased for OSR. + // + if (compiler->lvaIsOSRLocal(lclNum) && compiler->info.compPatchpointInfo->IsExposed(lclNum)) + { + JITDUMP(" struct promotion of V%02u is disabled because it is an exposed OSR local\n", lclNum); + return false; + } + CORINFO_CLASS_HANDLE typeHnd = varDsc->GetStructHnd(); assert(typeHnd != NO_CLASS_HANDLE); diff --git a/src/tests/JIT/opt/OSR/invalidpromotion.cs b/src/tests/JIT/opt/OSR/invalidpromotion.cs new file mode 100644 index 00000000000..5aeb7242814 --- /dev/null +++ b/src/tests/JIT/opt/OSR/invalidpromotion.cs @@ -0,0 +1,73 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +interface IFoo +{ + public Span AsSpan(); +} + +public struct ObjectSequence1 : IFoo +{ + public object Value1; + + public Span AsSpan() + { + return MemoryMarshal.CreateSpan(ref Value1, 1); + } +} + +public struct ObjectSequenceMany : IFoo +{ + public object[] _values; + + public Span AsSpan() + { + return _values.AsSpan(); + } + + public ObjectSequenceMany(object[] x) + { + _values = x; + } +} + +public class InvalidPromotion +{ + [MethodImpl(MethodImplOptions.NoInlining)] + static bool G(int n) where T : IFoo + { + // OSR cannot safely promote values + T values = default; + + if (values is ObjectSequenceMany) + { + values = (T)(object)new ObjectSequenceMany(new object[5]); + } + + Span indexedValues = values.AsSpan(); + + // For a patchpoint here. + for (int i = 0; i < n; i++) + { + indexedValues[i] = "foo"; + } + + if (values is ObjectSequence1) + { + return (indexedValues[0] == ((ObjectSequence1)(object)values).Value1); + } + + return false; + } + + public static int Main() + { + return G(1) ? 100 : -1; + } +} + + diff --git a/src/tests/JIT/opt/OSR/invalidpromotion.csproj b/src/tests/JIT/opt/OSR/invalidpromotion.csproj new file mode 100644 index 00000000000..8c42cae6844 --- /dev/null +++ b/src/tests/JIT/opt/OSR/invalidpromotion.csproj @@ -0,0 +1,30 @@ + + + Exe + + True + + + + + + + + + -- GitLab