Skip to content

Commit

Permalink
JIT: don't clone loops where init or limit is a cast local (#57602)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
AndyAyersMS authored Aug 18, 2021
1 parent b4d75a0 commit a108d25
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 3 deletions.
18 changes: 15 additions & 3 deletions src/coreclr/jit/loopcloning.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand All @@ -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);
Expand Down
28 changes: 28 additions & 0 deletions src/tests/JIT/Regression/JitBlue/Runtime_57535/Runtime_57535.cs
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -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>
31 changes: 31 additions & 0 deletions src/tests/JIT/Regression/JitBlue/Runtime_57535/Runtime_57535_1.cs
Original file line number Diff line number Diff line change
@@ -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) {}
}
Original file line number Diff line number Diff line change
@@ -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>

0 comments on commit a108d25

Please sign in to comment.