diff options
-rw-r--r-- | src/jit/optimizer.cpp | 32 | ||||
-rw-r--r-- | tests/src/JIT/Regression/JitBlue/GitHub_23739/GitHub_23739.cs | 212 | ||||
-rw-r--r-- | tests/src/JIT/Regression/JitBlue/GitHub_23739/GitHub_23739.csproj | 18 |
3 files changed, 251 insertions, 11 deletions
diff --git a/src/jit/optimizer.cpp b/src/jit/optimizer.cpp index 431f4d5ab1..7749e928ba 100644 --- a/src/jit/optimizer.cpp +++ b/src/jit/optimizer.cpp @@ -6885,26 +6885,36 @@ bool Compiler::optHoistLoopExprsForTree(GenTree* tree, // Tree must be a suitable CSE candidate for us to be able to hoist it. treeIsHoistable &= optIsCSEcandidate(tree); - // If it's a call, it must be a helper call, and be pure. - // Further, if it may run a cctor, it must be labeled as "Hoistable" - // (meaning it won't run a cctor because the class is not precise-init). - if (treeIsHoistable && tree->OperGet() == GT_CALL) + if (treeIsHoistable) { - GenTreeCall* call = tree->AsCall(); - if (call->gtCallType != CT_HELPER) + // We cannot hoist an r-value of TYP_STRUCT + // as they currently do not carry full descriptors of the struct type + if (tree->TypeGet() == TYP_STRUCT) { treeIsHoistable = false; } - else + + // If it's a call, it must be a helper call, and be pure. + // Further, if it may run a cctor, it must be labeled as "Hoistable" + // (meaning it won't run a cctor because the class is not precise-init). + if (tree->OperGet() == GT_CALL) { - CorInfoHelpFunc helpFunc = eeGetHelperNum(call->gtCallMethHnd); - if (!s_helperCallProperties.IsPure(helpFunc)) + GenTreeCall* call = tree->AsCall(); + if (call->gtCallType != CT_HELPER) { treeIsHoistable = false; } - else if (s_helperCallProperties.MayRunCctor(helpFunc) && (call->gtFlags & GTF_CALL_HOISTABLE) == 0) + else { - treeIsHoistable = false; + CorInfoHelpFunc helpFunc = eeGetHelperNum(call->gtCallMethHnd); + if (!s_helperCallProperties.IsPure(helpFunc)) + { + treeIsHoistable = false; + } + else if (s_helperCallProperties.MayRunCctor(helpFunc) && (call->gtFlags & GTF_CALL_HOISTABLE) == 0) + { + treeIsHoistable = false; + } } } } diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_23739/GitHub_23739.cs b/tests/src/JIT/Regression/JitBlue/GitHub_23739/GitHub_23739.cs new file mode 100644 index 0000000000..b75bc51568 --- /dev/null +++ b/tests/src/JIT/Regression/JitBlue/GitHub_23739/GitHub_23739.cs @@ -0,0 +1,212 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +// + +using System; +using System.Runtime.CompilerServices; + +class GitHub_23739 +{ + struct Struct1f + { + float a; + } + + class Cls1f + { + public Struct1f sf; + } + + struct Struct2f + { + float a, b; + } + + class Cls2f + { + public Struct2f sf; + } + + struct Struct3f + { + float a, b, c; + } + + class Cls3f + { + public Struct3f sf; + } + + struct Struct4f + { + float a, b, c, d; + } + + class Cls4f + { + public Struct4f sf; + } + + struct Struct5f + { + float a, b, c, d, e; + } + + class Cls5f + { + public Struct5f sf; + } + + struct Struct6f + { + float a, b, c, d, e, f; + } + + class Cls6f + { + public Struct6f sf; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static void Sink<T>(ref T t) + { + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static void Test1f(Cls1f c) + { + Struct1f l1 = default; + Struct1f l2 = default; + Struct1f l3 = default; + + for (int i = 0; i < 10; i++) + { + l1 = c.sf; + l2 = c.sf; + l3 = c.sf; + } + + Sink(ref l1); + Sink(ref l2); + Sink(ref l3); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static void Test2f(Cls2f c) + { + Struct2f l1 = default; + Struct2f l2 = default; + Struct2f l3 = default; + + for (int i = 0; i < 10; i++) + { + l1 = c.sf; + l2 = c.sf; + l3 = c.sf; + } + + Sink(ref l1); + Sink(ref l2); + Sink(ref l3); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static void Test3f(Cls3f c) + { + Struct3f l1 = default; + Struct3f l2 = default; + Struct3f l3 = default; + + for (int i = 0; i < 10; i++) + { + l1 = c.sf; + l2 = c.sf; + l3 = c.sf; + } + + Sink(ref l1); + Sink(ref l2); + Sink(ref l3); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static void Test4f(Cls4f c) + { + Struct4f l1 = default; + Struct4f l2 = default; + Struct4f l3 = default; + + for (int i = 0; i < 10; i++) + { + l1 = c.sf; + l2 = c.sf; + l3 = c.sf; + } + + Sink(ref l1); + Sink(ref l2); + Sink(ref l3); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static void Test5f(Cls5f c) + { + Struct5f l1 = default; + Struct5f l2 = default; + Struct5f l3 = default; + + for (int i = 0; i < 10; i++) + { + l1 = c.sf; + l2 = c.sf; + l3 = c.sf; + } + + Sink(ref l1); + Sink(ref l2); + Sink(ref l3); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static void Test6f(Cls6f c) + { + Struct6f l1 = default; + Struct6f l2 = default; + Struct6f l3 = default; + + for (int i = 0; i < 10; i++) + { + l1 = c.sf; + l2 = c.sf; + l3 = c.sf; + } + + Sink(ref l1); + Sink(ref l2); + Sink(ref l3); + } + + static int Main() + { + Cls1f cls1f = new Cls1f(); + Test1f(cls1f); + + Cls2f cls2f = new Cls2f(); + Test2f(cls2f); + + Cls3f cls3f = new Cls3f(); + Test3f(cls3f); + + Cls4f cls4f = new Cls4f(); + Test4f(cls4f); + + Cls5f cls5f = new Cls5f(); + Test5f(cls5f); + + Cls6f cls6f = new Cls6f(); + Test6f(cls6f); + + return 100; + } +} diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_23739/GitHub_23739.csproj b/tests/src/JIT/Regression/JitBlue/GitHub_23739/GitHub_23739.csproj new file mode 100644 index 0000000000..fb6ae363eb --- /dev/null +++ b/tests/src/JIT/Regression/JitBlue/GitHub_23739/GitHub_23739.csproj @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Release</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <AssemblyName>$(MSBuildProjectName)</AssemblyName> + <OutputType>Exe</OutputType> + <DebugType></DebugType> + <Optimize>True</Optimize> + <AllowUnsafeBlocks>True</AllowUnsafeBlocks> + </PropertyGroup> + <ItemGroup> + <Compile Include="$(MSBuildProjectName).cs" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> + <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup> +</Project> |