Skip to content

Commit 9703a2e

Browse files
authored
JIT: Copy loop memory dependence recursively on hoisting (#116068)
When hoisting we were cloning the full tree but only copying memory dependence of the root node. Ensure we copy it for the full tree.
1 parent 0c88424 commit 9703a2e

File tree

3 files changed

+75
-31
lines changed

3 files changed

+75
-31
lines changed

src/coreclr/jit/optimizer.cpp

Lines changed: 21 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3674,30 +3674,7 @@ void Compiler::optPerformHoistExpr(GenTree* origExpr, BasicBlock* exprBb, FlowGr
36743674

36753675
preheader->CopyFlags(exprBb, BBF_COPY_PROPAGATE);
36763676

3677-
Statement* hoistStmt = gtNewStmt(hoist);
3678-
3679-
// Simply append the statement at the end of the preHead's list.
3680-
Statement* firstStmt = preheader->firstStmt();
3681-
if (firstStmt != nullptr)
3682-
{
3683-
/* append after last statement */
3684-
3685-
Statement* lastStmt = preheader->lastStmt();
3686-
assert(lastStmt->GetNextStmt() == nullptr);
3687-
3688-
lastStmt->SetNextStmt(hoistStmt);
3689-
hoistStmt->SetPrevStmt(lastStmt);
3690-
firstStmt->SetPrevStmt(hoistStmt);
3691-
}
3692-
else
3693-
{
3694-
/* Empty pre-header - store the single statement in the block */
3695-
3696-
preheader->bbStmtList = hoistStmt;
3697-
hoistStmt->SetPrevStmt(hoistStmt);
3698-
}
3699-
3700-
hoistStmt->SetNextStmt(nullptr);
3677+
fgInsertStmtAtEnd(preheader, fgNewStmtFromTree(hoist));
37013678

37023679
#ifdef DEBUG
37033680
if (verbose)
@@ -3708,12 +3685,6 @@ void Compiler::optPerformHoistExpr(GenTree* origExpr, BasicBlock* exprBb, FlowGr
37083685
}
37093686
#endif
37103687

3711-
if (fgNodeThreading == NodeThreading::AllTrees)
3712-
{
3713-
gtSetStmtInfo(hoistStmt);
3714-
fgSetStmtSeq(hoistStmt);
3715-
}
3716-
37173688
#ifdef DEBUG
37183689
if (m_nodeTestData != nullptr)
37193690
{
@@ -4304,22 +4275,41 @@ void Compiler::optRecordLoopMemoryDependence(GenTree* tree, BasicBlock* block, V
43044275
}
43054276

43064277
//------------------------------------------------------------------------
4307-
// optCopyLoopMemoryDependence: record that tree's loop memory dependence
4278+
// optCopyLoopMemoryDependence: Recursively record that tree's loop memory dependence
43084279
// is the same as some other tree.
43094280
//
43104281
// Arguments:
43114282
// fromTree -- tree to copy dependence from
43124283
// toTree -- tree in question
43134284
//
4285+
// Remarks:
4286+
// This requires 'toTree' to be in its own statement
4287+
//
43144288
void Compiler::optCopyLoopMemoryDependence(GenTree* fromTree, GenTree* toTree)
43154289
{
4290+
assert(fromTree->OperGet() == toTree->OperGet());
4291+
43164292
NodeToLoopMemoryBlockMap* const map = GetNodeToLoopMemoryBlockMap();
43174293
BasicBlock* mapBlock = nullptr;
43184294

43194295
if (map->Lookup(fromTree, &mapBlock))
43204296
{
43214297
map->Set(toTree, mapBlock);
43224298
}
4299+
4300+
GenTreeOperandIterator fromIterCur = fromTree->OperandsBegin();
4301+
GenTreeOperandIterator fromIterEnd = fromTree->OperandsEnd();
4302+
GenTreeOperandIterator toIterCur = toTree->OperandsBegin();
4303+
GenTreeOperandIterator toIterEnd = toTree->OperandsEnd();
4304+
4305+
while (fromIterCur != fromIterEnd)
4306+
{
4307+
optCopyLoopMemoryDependence(*fromIterCur, *toIterCur);
4308+
++fromIterCur;
4309+
++toIterCur;
4310+
}
4311+
4312+
assert(toIterCur == toIterEnd);
43234313
}
43244314

43254315
//------------------------------------------------------------------------
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
// Generated by Fuzzlyn v2.8 on 2025-04-27 22:46:08
5+
// Run on X86 Windows
6+
// Seed: 2255917678885586044-vectort,vector128,vector256,x86aes,x86avx,x86avx2,x86avx512bw,x86avx512bwvl,x86avx512cd,x86avx512cdvl,x86avx512dq,x86avx512dqvl,x86avx512f,x86avx512fvl,x86bmi1,x86bmi2,x86fma,x86lzcnt,x86pclmulqdq,x86popcnt,x86sse,x86sse2,x86sse3,x86sse41,x86sse42,x86ssse3,x86x86base
7+
// Reduced from 118.3 KiB to 1.0 KiB in 00:17:25
8+
// Debug: Outputs <0, 0, 0, 0, 0, 0, 0, 0>
9+
// Release: Outputs <1, 0, 0, 0, 0, 0, 0, 0>
10+
using System.Numerics;
11+
using System.Runtime.CompilerServices;
12+
using System.Runtime.Intrinsics;
13+
using Xunit;
14+
15+
public class Runtime_115109
16+
{
17+
static int s_5 = 101;
18+
static Vector<int>[] s_10;
19+
static byte s_21;
20+
21+
[Fact]
22+
public static int TestEntryPoint()
23+
{
24+
s_10 = [Vector128.CreateScalar(0).AsVector()];
25+
bool vr5 = 0 <= M10();
26+
return s_10[0][0];
27+
}
28+
29+
[MethodImpl(MethodImplOptions.NoInlining)]
30+
private static byte M10()
31+
{
32+
byte lvar2 = 3;
33+
do
34+
{
35+
s_5 = 100;
36+
int lvar4 = 0;
37+
do
38+
{
39+
s_10[0] = Vector128.CreateScalar(s_5).AsVector();
40+
}
41+
while (++lvar4 < 2);
42+
}
43+
while (--lvar2 > 1);
44+
return s_21;
45+
}
46+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<Optimize>True</Optimize>
4+
</PropertyGroup>
5+
<ItemGroup>
6+
<Compile Include="$(MSBuildProjectName).cs" />
7+
</ItemGroup>
8+
</Project>

0 commit comments

Comments
 (0)