From: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 19 Aug 2021 14:20:23 +0000 (-0700) Subject: [release/6.0] JIT: don't clone loops where init or limit is a cast local (#57685) X-Git-Tag: accepted/tizen/unified/20220110.054933~297 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5d0820af5eac70f95d1395d60cb000e4fb08a49b;p=platform%2Fupstream%2Fdotnet%2Fruntime.git [release/6.0] JIT: don't clone loops where init or limit is a cast local (#57685) * 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 Co-authored-by: SingleAccretion <62474226+SingleAccretion@users.noreply.github.com> --- diff --git a/src/coreclr/jit/loopcloning.cpp b/src/coreclr/jit/loopcloning.cpp index 69e916c3..9b2898a 100644 --- a/src/coreclr/jit/loopcloning.cpp +++ b/src/coreclr/jit/loopcloning.cpp @@ -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 index 0000000..1af6664 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_57535/Runtime_57535.cs @@ -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 index 0000000..f3e1cbd --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_57535/Runtime_57535.csproj @@ -0,0 +1,12 @@ + + + Exe + + + None + True + + + + + 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 index 0000000..83040ad --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_57535/Runtime_57535_1.cs @@ -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 index 0000000..f3e1cbd --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_57535/Runtime_57535_1.csproj @@ -0,0 +1,12 @@ + + + Exe + + + None + True + + + + +