Skip to content

Commit

Permalink
JIT: properly update loop memory dependence when loops are removed (#…
Browse files Browse the repository at this point in the history
…56436)

If a loop is removed (because of unrolling) then the loop dependence
tracking introduced in #55936 and #56184 may not properly update.

So when a loop is removed, walk up the chain of parent loops looking
for one that is not removed, and record the dependence on that parent.

Addresses last part of #54118.
  • Loading branch information
AndyAyersMS authored Jul 28, 2021
1 parent db1b302 commit b25bd29
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 2 deletions.
30 changes: 28 additions & 2 deletions src/coreclr/jit/optimizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6067,17 +6067,43 @@ void Compiler::optRecordLoopMemoryDependence(GenTree* tree, BasicBlock* block, V

// Find the loop associated with this memory VN.
//
unsigned const updateLoopNum = vnStore->LoopOfVN(memoryVN);
unsigned updateLoopNum = vnStore->LoopOfVN(memoryVN);

if (updateLoopNum == BasicBlock::NOT_IN_LOOP)
if (updateLoopNum >= BasicBlock::MAX_LOOP_NUM)
{
// There should be only two special non-loop loop nums.
//
assert((updateLoopNum == BasicBlock::MAX_LOOP_NUM) || (updateLoopNum == BasicBlock::NOT_IN_LOOP));

// memoryVN defined outside of any loop, we can ignore.
//
JITDUMP(" ==> Not updating loop memory dependence of [%06u], memory " FMT_VN " not defined in a loop\n",
dspTreeID(tree), memoryVN);
return;
}

// If the loop was removed, then record the dependence in the nearest enclosing loop, if any.
//
while ((optLoopTable[updateLoopNum].lpFlags & LPFLG_REMOVED) != 0)
{
unsigned const updateParentLoopNum = optLoopTable[updateLoopNum].lpParent;

if (updateParentLoopNum == BasicBlock::NOT_IN_LOOP)
{
// Memory VN was defined in a loop, but no longer.
//
JITDUMP(" ==> Not updating loop memory dependence of [%06u], memory " FMT_VN
" no longer defined in a loop\n",
dspTreeID(tree), memoryVN);
break;
}

JITDUMP(" ==> " FMT_LP " removed, updating dependence to parent " FMT_LP "\n", updateLoopNum,
updateParentLoopNum);

updateLoopNum = updateParentLoopNum;
}

// If the update block is not the the header of a loop containing
// block, we can also ignore the update.
//
Expand Down
37 changes: 37 additions & 0 deletions src/tests/JIT/Regression/JitBlue/Runtime_54118/Runtime_54118_2.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Runtime.CompilerServices;

// Generated by Fuzzlyn v1.2 on 2021-07-22 13:36:33
// Seed: 11656046881568048475
// Reduced from 224.5 KiB to 0.4 KiB in 00:02:42
// Debug: Outputs 1
// Release: Outputs 0

public class Program
{
[MethodImpl(MethodImplOptions.NoInlining)]
static bool Eval(byte b) => b == 100;

static ulong[] s_34 = new ulong[]{0};
public static int Main()
{
byte[] vr1 = new byte[]{0};
bool result = false;
for (int vr2 = 0; vr2 < 2; vr2++)
{
for (int vr3 = 0; vr3 < 1; vr3++)
{
ulong vr4 = s_34[0]++;
}

vr1[0] = 100;
var vr5 = vr1[0];
result = Eval(vr5);
}

return result ? 100 : -1;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
</PropertyGroup>
<PropertyGroup>
<DebugType>None</DebugType>
<Optimize>True</Optimize>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildProjectName).cs" />
</ItemGroup>
</Project>

0 comments on commit b25bd29

Please sign in to comment.