summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/jit/assertionprop.cpp19
-rw-r--r--src/jit/compiler.h9
-rw-r--r--src/jit/gentree.cpp35
-rw-r--r--src/jit/optcse.cpp3
-rw-r--r--tests/src/JIT/Regression/JitBlue/GitHub_24185/GitHub_24185.cs36
-rw-r--r--tests/src/JIT/Regression/JitBlue/GitHub_24185/GitHub_24185.csproj33
6 files changed, 114 insertions, 21 deletions
diff --git a/src/jit/assertionprop.cpp b/src/jit/assertionprop.cpp
index cd1b90ffa2..5b62e88303 100644
--- a/src/jit/assertionprop.cpp
+++ b/src/jit/assertionprop.cpp
@@ -3901,11 +3901,22 @@ GenTree* Compiler::optAssertionProp_Update(GenTree* newTree, GenTree* tree, GenT
// locate our parent node and update it so that it points to newTree.
if (newTree != tree)
{
- GenTree** link = gtFindLink(stmt, tree);
- noway_assert(link != nullptr);
+ FindLinkData linkData = gtFindLink(stmt, tree);
+ GenTree** useEdge = linkData.result;
+ GenTree* parent = linkData.parent;
+ noway_assert(useEdge != nullptr);
- // Replace the old operand with the newTree
- *link = newTree;
+ if (parent != nullptr)
+ {
+ parent->ReplaceOperand(useEdge, newTree);
+ }
+ else
+ {
+ // If there's no parent, the tree being replaced is the root of the
+ // statement.
+ assert((stmt->gtStmtExpr == tree) && (&stmt->gtStmtExpr == useEdge));
+ stmt->gtStmtExpr = newTree;
+ }
// We only need to ensure that the gtNext field is set as it is used to traverse
// to the next node in the tree. We will re-morph this entire statement in
diff --git a/src/jit/compiler.h b/src/jit/compiler.h
index b091c929c9..fed7003faa 100644
--- a/src/jit/compiler.h
+++ b/src/jit/compiler.h
@@ -2994,7 +2994,14 @@ public:
static fgWalkPreFn gtMarkColonCond;
static fgWalkPreFn gtClearColonCond;
- GenTree** gtFindLink(GenTreeStmt* stmt, GenTree* node);
+ struct FindLinkData
+ {
+ GenTree* nodeToFind;
+ GenTree** result;
+ GenTree* parent;
+ };
+
+ FindLinkData gtFindLink(GenTreeStmt* stmt, GenTree* node);
bool gtHasCatchArg(GenTree* tree);
typedef ArrayStack<GenTree*> GenTreeStack;
diff --git a/src/jit/gentree.cpp b/src/jit/gentree.cpp
index f0dfbc7ee5..df6b324a06 100644
--- a/src/jit/gentree.cpp
+++ b/src/jit/gentree.cpp
@@ -7931,23 +7931,32 @@ bool Compiler::gtCompareTree(GenTree* op1, GenTree* op2)
GenTree* Compiler::gtGetThisArg(GenTreeCall* call)
{
- if (call->gtCallObjp != nullptr)
+ GenTree* thisArg = call->gtCallObjp;
+ if (thisArg != nullptr)
{
- if (call->gtCallObjp->gtOper != GT_NOP && call->gtCallObjp->gtOper != GT_ASG)
+ if (thisArg->OperIs(GT_NOP, GT_ASG) == false)
{
- if (!(call->gtCallObjp->gtFlags & GTF_LATE_ARG))
+ if ((thisArg->gtFlags & GTF_LATE_ARG) == 0)
{
return call->gtCallObjp;
}
}
- if (call->gtCallLateArgs)
+ if (call->gtCallLateArgs != nullptr)
{
unsigned argNum = 0;
fgArgTabEntry* thisArgTabEntry = gtArgEntryByArgNum(call, argNum);
GenTree* result = thisArgTabEntry->node;
+ // Assert if we used DEBUG_DESTROY_NODE.
+ assert(result->gtOper != GT_COUNT);
+
#if !FEATURE_FIXED_OUT_ARGS && defined(DEBUG)
+ // Check that call->fgArgInfo used in gtArgEntryByArgNum was not
+ // left outdated by assertion propogation updates.
+ // There is no information about registers of late args for platforms
+ // with FEATURE_FIXED_OUT_ARGS that is why this debug check is under
+ // !FEATURE_FIXED_OUT_ARGS.
regNumber thisReg = REG_ARG_0;
GenTree* lateArgs = call->gtCallLateArgs;
regList list = call->regArgList;
@@ -7966,6 +7975,7 @@ GenTree* Compiler::gtGetThisArg(GenTreeCall* call)
index++;
}
#endif // !FEATURE_FIXED_OUT_ARGS && defined(DEBUG)
+
return result;
}
}
@@ -15156,42 +15166,37 @@ Compiler::fgWalkResult Compiler::gtClearColonCond(GenTree** pTree, fgWalkData* d
return WALK_CONTINUE;
}
-struct FindLinkData
-{
- GenTree* nodeToFind;
- GenTree** result;
-};
-
/*****************************************************************************
*
* Callback used by the tree walker to implement fgFindLink()
*/
static Compiler::fgWalkResult gtFindLinkCB(GenTree** pTree, Compiler::fgWalkData* cbData)
{
- FindLinkData* data = (FindLinkData*)cbData->pCallbackData;
+ Compiler::FindLinkData* data = (Compiler::FindLinkData*)cbData->pCallbackData;
if (*pTree == data->nodeToFind)
{
data->result = pTree;
+ data->parent = cbData->parent;
return Compiler::WALK_ABORT;
}
return Compiler::WALK_CONTINUE;
}
-GenTree** Compiler::gtFindLink(GenTreeStmt* stmt, GenTree* node)
+Compiler::FindLinkData Compiler::gtFindLink(GenTreeStmt* stmt, GenTree* node)
{
- FindLinkData data = {node, nullptr};
+ FindLinkData data = {node, nullptr, nullptr};
fgWalkResult result = fgWalkTreePre(&stmt->gtStmtExpr, gtFindLinkCB, &data);
if (result == WALK_ABORT)
{
assert(data.nodeToFind == *data.result);
- return data.result;
+ return data;
}
else
{
- return nullptr;
+ return {node, nullptr, nullptr};
}
}
diff --git a/src/jit/optcse.cpp b/src/jit/optcse.cpp
index 9dc421b3fd..a25e17c4fa 100644
--- a/src/jit/optcse.cpp
+++ b/src/jit/optcse.cpp
@@ -2364,7 +2364,8 @@ public:
// Walk the statement 'stmt' and find the pointer
// in the tree is pointing to 'exp'
//
- GenTree** link = m_pCompiler->gtFindLink(stmt, exp);
+ Compiler::FindLinkData linkData = m_pCompiler->gtFindLink(stmt, exp);
+ GenTree** link = linkData.result;
#ifdef DEBUG
if (link == nullptr)
diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_24185/GitHub_24185.cs b/tests/src/JIT/Regression/JitBlue/GitHub_24185/GitHub_24185.cs
new file mode 100644
index 0000000000..3695ab2a8f
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/GitHub_24185/GitHub_24185.cs
@@ -0,0 +1,36 @@
+// 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.Threading;
+using System.Threading.Tasks;
+
+// The test shows recursive assertion propogation in one statement.
+
+namespace GitHub_24185
+{
+ public class Program
+ {
+ static int Main(string[] args)
+ {
+ try
+ {
+ throw new AggregateException(new Exception("A random exception1"), new Exception("A random exception2"));
+ }
+ catch (Exception e)
+ {
+ // Each expression in this condition checks that `e` is not null and checks its type.
+ // This information should be calculated once and propogated by assertion propogation.
+ if (!(e is AggregateException) ||
+ !((((AggregateException)e).InnerExceptions[0] is ArgumentException)
+ || ((AggregateException)e).InnerExceptions[0] is AggregateException))
+ {
+ return 100;
+ }
+
+ }
+ return 0;
+ }
+ }
+}
diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_24185/GitHub_24185.csproj b/tests/src/JIT/Regression/JitBlue/GitHub_24185/GitHub_24185.csproj
new file mode 100644
index 0000000000..cc72c511df
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/GitHub_24185/GitHub_24185.csproj
@@ -0,0 +1,33 @@
+<?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)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "></PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>None</DebugType>
+ <Optimize>True</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="$(MSBuildProjectName).cs" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
+</Project> \ No newline at end of file