From 17c851488d986163b1071a77a32170ccb265f436 Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Fri, 17 Mar 2017 00:21:50 -0700 Subject: [PATCH] JIT: Fix noway_assert when inlining The jit keeps track of which inline arguments can be modified via starg during the inlinee IL prescan to ensure that a temp is used to represent such arguments in the inlined body. There is a noway_assert the a starg is procecssed during importation that double-checks that a temp is really being used, and this assert was firing. The prescan guraded the starg tracking with a check to avoid an out-of-bounds write into the argument table when scanning bad IL with bogus argument numbers. The predicate was checking the argument number against lvaTableCount. Unfortunately for inlinees this value is not related to the number of arguments. In particular it some rare cases it may be an underestimate so the prescan might end up failing to note a starg. If the the jit then tries to inline and the caller passes a constant, the assert will then fire. Fix is to update the guard to use the number of callee arguments. This is known to be less than the table size by earlier checks. Added a test case. Closes dotnet/coreclr#9891. Commit migrated from https://github.com/dotnet/coreclr/commit/0380bad51faf5ef608208f1ead8294dcf8519ce0 --- src/coreclr/src/jit/flowgraph.cpp | 17 +++++---- .../Regression/JitBlue/GitHub_9891/GitHub_9891.cs | 31 ++++++++++++++++ .../JitBlue/GitHub_9891/GitHub_9891.csproj | 42 ++++++++++++++++++++++ 3 files changed, 84 insertions(+), 6 deletions(-) create mode 100644 src/coreclr/tests/src/JIT/Regression/JitBlue/GitHub_9891/GitHub_9891.cs create mode 100644 src/coreclr/tests/src/JIT/Regression/JitBlue/GitHub_9891/GitHub_9891.csproj diff --git a/src/coreclr/src/jit/flowgraph.cpp b/src/coreclr/src/jit/flowgraph.cpp index 8bd267c..0cc0d56 100644 --- a/src/coreclr/src/jit/flowgraph.cpp +++ b/src/coreclr/src/jit/flowgraph.cpp @@ -4535,17 +4535,22 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, BYTE* } varNum = (sz == sizeof(BYTE)) ? getU1LittleEndian(codeAddr) : getU2LittleEndian(codeAddr); - varNum = compMapILargNum(varNum); // account for possible hidden param - // This check is only intended to prevent an AV. Bad varNum values will later - // be handled properly by the verifier. - if (varNum < lvaTableCnt) + if (isInlining) { - if (isInlining) + if (varNum < impInlineInfo->argCnt) { impInlineInfo->inlArgInfo[varNum].argHasStargOp = true; } - else + } + else + { + // account for possible hidden param + varNum = compMapILargNum(varNum); + + // This check is only intended to prevent an AV. Bad varNum values will later + // be handled properly by the verifier. + if (varNum < lvaTableCnt) { // In non-inline cases, note written-to locals. lvaTable[varNum].lvArgWrite = 1; diff --git a/src/coreclr/tests/src/JIT/Regression/JitBlue/GitHub_9891/GitHub_9891.cs b/src/coreclr/tests/src/JIT/Regression/JitBlue/GitHub_9891/GitHub_9891.cs new file mode 100644 index 0000000..72a6bbc --- /dev/null +++ b/src/coreclr/tests/src/JIT/Regression/JitBlue/GitHub_9891/GitHub_9891.cs @@ -0,0 +1,31 @@ +// 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; + +// Noway assert where an inlinee modified a parameter with index > 16, +// and caller that had few args or locals passed in a constant for +// that parameter. + +class B +{ + int X( + int a01, int a02, int a03, int a04, + int a05, int a06, int a07, int a08, + int a09, int a10, int a11, int a12, + int a13, int a14, int a15, int a16, + int a17, int a18, int a19, int a20) + { + a20 = a19; + return a20; + } + + public static int Main(string[] args) + { + B b = new B(); + int v = b.X(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20); + return v + 81; + } +} diff --git a/src/coreclr/tests/src/JIT/Regression/JitBlue/GitHub_9891/GitHub_9891.csproj b/src/coreclr/tests/src/JIT/Regression/JitBlue/GitHub_9891/GitHub_9891.csproj new file mode 100644 index 0000000..6b8b07a --- /dev/null +++ b/src/coreclr/tests/src/JIT/Regression/JitBlue/GitHub_9891/GitHub_9891.csproj @@ -0,0 +1,42 @@ + + + + + Debug + AnyCPU + $(MSBuildProjectName) + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + Exe + Properties + 512 + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + $(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages + ..\..\ + + 7a9bfb7d + + + + + + + + + False + + + + + True + + + + + + + + + + + -- 2.7.4