[release/6.0-rc1] JIT: don't clone loops where init or limit is a cast local (#57690)
authorgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Thu, 19 Aug 2021 14:20:47 +0000 (07:20 -0700)
committerGitHub <noreply@github.com>
Thu, 19 Aug 2021 14:20:47 +0000 (07:20 -0700)
* JIT: don't clone loops where init or limit is a cast local

The loop cloner assumes all computations it introduces are compatible
with TYP_INT, so don't allow cloning when the initial or final value
are variables with incompatible types.

Fixes #57535.

* Apply suggestions from code review

Co-authored-by: SingleAccretion <62474226+SingleAccretion@users.noreply.github.com>
Co-authored-by: Andy Ayers <andya@microsoft.com>
Co-authored-by: SingleAccretion <62474226+SingleAccretion@users.noreply.github.com>
src/coreclr/jit/loopcloning.cpp
src/tests/JIT/Regression/JitBlue/Runtime_57535/Runtime_57535.cs [new file with mode: 0644]
src/tests/JIT/Regression/JitBlue/Runtime_57535/Runtime_57535.csproj [new file with mode: 0644]
src/tests/JIT/Regression/JitBlue/Runtime_57535/Runtime_57535_1.cs [new file with mode: 0644]
src/tests/JIT/Regression/JitBlue/Runtime_57535/Runtime_57535_1.csproj [new file with mode: 0644]

index 69e916c..9b2898a 100644 (file)
@@ -968,7 +968,14 @@ bool Compiler::optDeriveLoopCloningConditions(unsigned loopNum, LoopCloneContext
         else if (loop->lpFlags & LPFLG_VAR_INIT)
         {
             // initVar >= 0
-            LC_Condition geZero(GT_GE, LC_Expr(LC_Ident(loop->lpVarInit, LC_Ident::Var)),
+            const unsigned initLcl = loop->lpVarInit;
+            if (!genActualTypeIsInt(lvaGetDesc(initLcl)))
+            {
+                JITDUMP("> Init var V%02u not compatible with TYP_INT\n", initLcl);
+                return false;
+            }
+
+            LC_Condition geZero(GT_GE, LC_Expr(LC_Ident(initLcl, LC_Ident::Var)),
                                 LC_Expr(LC_Ident(0, LC_Ident::Const)));
             context->EnsureConditions(loopNum)->Push(geZero);
         }
@@ -992,9 +999,14 @@ bool Compiler::optDeriveLoopCloningConditions(unsigned loopNum, LoopCloneContext
         }
         else if (loop->lpFlags & LPFLG_VAR_LIMIT)
         {
-            unsigned limitLcl = loop->lpVarLimit();
-            ident             = LC_Ident(limitLcl, LC_Ident::Var);
+            const unsigned limitLcl = loop->lpVarLimit();
+            if (!genActualTypeIsInt(lvaGetDesc(limitLcl)))
+            {
+                JITDUMP("> Limit var V%02u not compatible with TYP_INT\n", limitLcl);
+                return false;
+            }
 
+            ident = LC_Ident(limitLcl, LC_Ident::Var);
             LC_Condition geZero(GT_GE, LC_Expr(ident), LC_Expr(LC_Ident(0, LC_Ident::Const)));
 
             context->EnsureConditions(loopNum)->Push(geZero);
diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_57535/Runtime_57535.cs b/src/tests/JIT/Regression/JitBlue/Runtime_57535/Runtime_57535.cs
new file mode 100644 (file)
index 0000000..1af6664
--- /dev/null
@@ -0,0 +1,28 @@
+using System;
+using System.Runtime.CompilerServices;
+
+class Runtime_57535
+{
+    static long z;
+
+    public static int Main()
+    {
+        z = 10;
+        int[] a = F();
+        long zz = z;
+        int result = 0;
+        for (int i = 0; i < (int) zz; i++)        
+        {
+            result += a[i];
+        }
+        return result;
+    }
+
+    [MethodImpl(MethodImplOptions.NoInlining)]
+    static int[] F()
+    {
+       int[] result = new int[100];
+       result[3] = 100;
+       return result;
+    }
+}
diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_57535/Runtime_57535.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_57535/Runtime_57535.csproj
new file mode 100644 (file)
index 0000000..f3e1cbd
--- /dev/null
@@ -0,0 +1,12 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+  </PropertyGroup>
+  <PropertyGroup>
+    <DebugType>None</DebugType>
+    <Optimize>True</Optimize>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="$(MSBuildProjectName).cs" />
+  </ItemGroup>
+</Project>
diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_57535/Runtime_57535_1.cs b/src/tests/JIT/Regression/JitBlue/Runtime_57535/Runtime_57535_1.cs
new file mode 100644 (file)
index 0000000..83040ad
--- /dev/null
@@ -0,0 +1,31 @@
+using System;
+using System.Runtime.CompilerServices;
+
+class Runtime_57535_1
+{
+    static long z;
+
+    public static int Main()
+    {
+        z = 2;
+        int[] a = F();
+        long zz = z;
+        int result = 0;
+        for (int i = (int) zz; i < a.Length; i++)
+        {
+            result += a[i];
+        }
+        Bar(zz);
+        return result;
+    }
+
+    [MethodImpl(MethodImplOptions.NoInlining)]
+    static int[] F()
+    {
+       int[] result = new int[100];
+       result[3] = 100;
+       return result;
+    }
+
+    static void Bar(long z) {}
+}
diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_57535/Runtime_57535_1.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_57535/Runtime_57535_1.csproj
new file mode 100644 (file)
index 0000000..f3e1cbd
--- /dev/null
@@ -0,0 +1,12 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+  </PropertyGroup>
+  <PropertyGroup>
+    <DebugType>None</DebugType>
+    <Optimize>True</Optimize>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="$(MSBuildProjectName).cs" />
+  </ItemGroup>
+</Project>