From 32b7be762b314205556069f67a58efcc7897366f Mon Sep 17 00:00:00 2001 From: Bruce Forstall Date: Thu, 18 May 2023 09:16:07 -0700 Subject: [PATCH] Fix issue with hoisting and copy prop interaction (#85493) * Fix issue with hoisting and copy prop interaction After hoisting creates a tree copy, it morphs it. That morph might lose the value numbers on LCL_VAR uses, but leave the SSA numbers. Copy prop was assuming that such a use had a VN. Instead, check this dynamically instead of asserting. Fixes #84619 * Further optimize cast in fgOptimizeCastOnStore() If we optimize the cast, call `fgOptimizeCast` to see if it can be optimized further. * Add regression test * Feedback --- src/coreclr/jit/copyprop.cpp | 3 ++- src/coreclr/jit/morph.cpp | 3 +++ .../JitBlue/Runtime_84619/Runtime_84619.cs | 28 ++++++++++++++++++++++ .../JitBlue/Runtime_84619/Runtime_84619.csproj | 9 +++++++ 4 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_84619/Runtime_84619.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_84619/Runtime_84619.csproj diff --git a/src/coreclr/jit/copyprop.cpp b/src/coreclr/jit/copyprop.cpp index 2798d2e..d212c35 100644 --- a/src/coreclr/jit/copyprop.cpp +++ b/src/coreclr/jit/copyprop.cpp @@ -158,7 +158,8 @@ int Compiler::optCopyProp_LclVarScore(const LclVarDsc* lclVarDsc, const LclVarDs bool Compiler::optCopyProp( BasicBlock* block, Statement* stmt, GenTreeLclVarCommon* tree, unsigned lclNum, LclNumToLiveDefsMap* curSsaName) { - assert(((tree->gtFlags & GTF_VAR_DEF) == 0) && (tree->GetLclNum() == lclNum) && tree->gtVNPair.BothDefined()); + assert((tree->gtFlags & GTF_VAR_DEF) == 0); + assert(tree->GetLclNum() == lclNum); bool madeChanges = false; LclVarDsc* varDsc = lvaGetDesc(lclNum); diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 6bd6c87..b1db6f5 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -10196,6 +10196,9 @@ GenTree* Compiler::fgOptimizeCastOnStore(GenTree* store) { // This is a type-changing cast so we cannot remove it entirely. cast->gtCastType = genActualType(castToType); + + // See if we can optimize the new cast. + store->Data() = fgOptimizeCast(cast); } return store; diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_84619/Runtime_84619.cs b/src/tests/JIT/Regression/JitBlue/Runtime_84619/Runtime_84619.cs new file mode 100644 index 0000000..2a118cd --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_84619/Runtime_84619.cs @@ -0,0 +1,28 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Xunit; + +// Generated by Fuzzlyn v1.5 on 2023-04-09 16:37:03 +// Run on X64 Windows +// Seed: 6230188300048624105 +// Reduced from 155.1 KiB to 0.2 KiB in 00:01:48 +// Hits JIT assert in Release: +// Assertion failed '((tree->gtFlags & GTF_VAR_DEF) == 0) && (tree->GetLclNum() == lclNum) && tree->gtVNPair.BothDefined()' in 'Program:Main(Fuzzlyn.ExecutionServer.IRuntime)' during 'VN based copy prop' (IL size 25; hash 0xade6b36b; FullOpts) +// +// File: D:\a\_work\1\s\src\coreclr\jit\copyprop.cpp Line: 161 +// +public class Runtime_84619 +{ + public static sbyte s_27; + [Fact] + public static int TestEntryPoint() + { + long vr1 = 0; + for (int vr3 = 0; vr3 < -1; vr3++) + { + s_27 = (sbyte)(vr1 | vr1); + } + return 100; + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_84619/Runtime_84619.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_84619/Runtime_84619.csproj new file mode 100644 index 0000000..1bb887e --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_84619/Runtime_84619.csproj @@ -0,0 +1,9 @@ + + + True + None + + + + + \ No newline at end of file -- 2.7.4