Skip to content

Commit

Permalink
Mark operands of non-RMW as delayFree (#57252)
Browse files Browse the repository at this point in the history
* For non-RMW intrinsics, always delayfree the operands

* Add test case

* Update test case to add Avx2.IsSupported
  • Loading branch information
kunalspathak authored Aug 13, 2021
1 parent 5817dc8 commit 6fca5a5
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/coreclr/jit/lsrabuild.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3141,7 +3141,7 @@ int LinearScan::BuildDelayFreeUses(GenTree* node, GenTree* rmwNode, regMaskTP ca
if (use != nullptr)
{
// If node != rmwNode, then definitely node should be marked as "delayFree".
// However, if node == rmwNode, then we can mark node as "delayFree" only
// However, if node == rmwNode, then we can mark node as "delayFree" only if
// none of the node/rmwNode are the last uses. If either of them are last use,
// we can safely reuse the rmwNode as destination.
if ((use->getInterval() != rmwInterval) || (!rmwIsLastUse && !use->lastUse))
Expand Down
8 changes: 4 additions & 4 deletions src/coreclr/jit/lsraxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2403,7 +2403,7 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree)

// Any pair of the index, mask, or destination registers should be different
srcCount += BuildOperandUses(op1);
srcCount += BuildDelayFreeUses(op2, op1);
srcCount += BuildDelayFreeUses(op2);

// op3 should always be contained
assert(op3->isContained());
Expand All @@ -2428,9 +2428,9 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree)

// Any pair of the index, mask, or destination registers should be different
srcCount += BuildOperandUses(op1);
srcCount += BuildDelayFreeUses(op2, op1);
srcCount += BuildDelayFreeUses(op3, op1);
srcCount += BuildDelayFreeUses(op4, op1);
srcCount += BuildDelayFreeUses(op2);
srcCount += BuildDelayFreeUses(op3);
srcCount += BuildDelayFreeUses(op4);

// op5 should always be contained
assert(argList->Rest()->Current()->isContained());
Expand Down
30 changes: 30 additions & 0 deletions src/tests/JIT/Regression/JitBlue/Runtime_56967/Runtime_56967.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;

public class Program
{
// 'vlu1' is source as well as destination and want to make sure that
// we do not allocate same register to the src/dest. We need to mark the
// src as 'delayFree'.
static unsafe int Main()
{
if (Avx2.IsSupported)
{
int* values = stackalloc int[256];
var vmsk = Vector256.Create(-1, -1, -1, 0, -1, -1, -1, 0);
var vlu1 = Vector256.Create(0, 1, 2, 3, 4, 5, 6, 7);
var vlu2 = Vector256.Create(7, 6, 5, 4, 3, 2, 1, 0);

vlu1 = Avx2.GatherMaskVector256(vlu1, values, vlu1, vmsk, sizeof(int));
vlu2 = Avx2.GatherMaskVector256(vlu2, values, vlu2, vmsk, sizeof(int));

if (vlu1.GetElement(3) != 3 || vlu2.GetElement(3) != 4)
{
return 1;
}
}

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

0 comments on commit 6fca5a5

Please sign in to comment.