Skip to content

Commit

Permalink
ARM64-SVE: Delay free all ops within conditional select (#107036) (#1…
Browse files Browse the repository at this point in the history
…07436)

* ARM64-SVE: Delay free all ops within conditional select

* Fix comment

* Add test header

* don't delay prefUseOpNum

* Fix FMA

* Add assert checks for delay free

* Merge embedded op build code

* fix formatting

* simplify assert

* simplify FMA code

* Add tests for 106867

* ARM64-SVE: Allow op inside conditionselect to be non HWintrinsic

TEST_IMG: ubuntu/dotnet-build
TEST_CMD: safe ./projects/dotnet/build-runtime.sh

Jira: ENTLLT-7634
Change-Id: I337a291be6661f104fe90c7cdc27150eede43647

* Add Sve.IsSupported to tests

* Add Sve.IsSupported to test

* fix formatting

* Revert "ARM64-SVE: Allow op inside conditionselect to be non HWintrinsic"

* Revert "ARM64-SVE: Allow op inside conditionselect to be non HWintrinsic"

* Revert "ARM64-SVE: Allow op inside conditionselect to be non HWintrinsic"

Co-authored-by: Alan Hayward <a74nh@users.noreply.github.com>
  • Loading branch information
kunalspathak and a74nh authored Sep 6, 2024
1 parent 131408a commit 3c622af
Show file tree
Hide file tree
Showing 7 changed files with 191 additions and 46 deletions.
74 changes: 28 additions & 46 deletions src/coreclr/jit/lsraarm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1944,7 +1944,8 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou
GenTreeHWIntrinsic* embOp2Node = intrin.op2->AsHWIntrinsic();
size_t numArgs = embOp2Node->GetOperandCount();
const HWIntrinsic intrinEmb(embOp2Node);
numArgs = embOp2Node->GetOperandCount();
numArgs = embOp2Node->GetOperandCount();
GenTree* prefUseNode = nullptr;

if (HWIntrinsicInfo::IsFmaIntrinsic(intrinEmb.id))
{
Expand All @@ -1961,44 +1962,15 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou
unsigned resultOpNum =
embOp2Node->GetResultOpNumForRmwIntrinsic(user, intrinEmb.op1, intrinEmb.op2, intrinEmb.op3);

GenTree* emitOp1 = intrinEmb.op1;
GenTree* emitOp2 = intrinEmb.op2;
GenTree* emitOp3 = intrinEmb.op3;

if (resultOpNum == 2)
{
// op2 = op1 + (op2 * op3)
std::swap(emitOp1, emitOp3);
std::swap(emitOp1, emitOp2);
// op1 = (op1 * op2) + op3
}
else if (resultOpNum == 3)
if (resultOpNum == 0)
{
// op3 = op1 + (op2 * op3)
std::swap(emitOp1, emitOp3);
// op1 = (op1 * op2) + op3
prefUseNode = embOp2Node->Op(1);
}
else
{
// op1 = op1 + (op2 * op3)
// Nothing needs to be done
assert(resultOpNum >= 1 && resultOpNum <= 3);
prefUseNode = embOp2Node->Op(resultOpNum);
}

GenTree* ops[] = {intrinEmb.op1, intrinEmb.op2, intrinEmb.op3};
for (GenTree* op : ops)
{
if (op == emitOp1)
{
tgtPrefUse = BuildUse(op);
srcCount++;
}
else if (op == emitOp2 || op == emitOp3)
{
srcCount += BuildDelayFreeUses(op, emitOp1);
}
}

srcCount += BuildDelayFreeUses(intrin.op3, emitOp1);
}
else
{
Expand Down Expand Up @@ -2045,22 +2017,32 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou
{
prefUseOpNum = 2;
}
GenTree* prefUseNode = embOp2Node->Op(prefUseOpNum);
for (size_t argNum = 1; argNum <= numArgs; argNum++)
prefUseNode = embOp2Node->Op(prefUseOpNum);
}

for (size_t argNum = 1; argNum <= numArgs; argNum++)
{
GenTree* node = embOp2Node->Op(argNum);

if (node == prefUseNode)
{
if (argNum == prefUseOpNum)
{
tgtPrefUse = BuildUse(prefUseNode);
srcCount += 1;
}
else
{
srcCount += BuildDelayFreeUses(embOp2Node->Op(argNum), prefUseNode);
}
tgtPrefUse = BuildUse(node);
srcCount++;
}
else
{
RefPosition* useRefPosition = nullptr;

srcCount += BuildDelayFreeUses(intrin.op3, prefUseNode);
int uses = BuildDelayFreeUses(node, nullptr, RBM_NONE, &useRefPosition);
srcCount += uses;

// It is a hard requirement that these are not allocated to the same register as the destination,
// so verify no optimizations kicked in to skip setting the delay-free.
assert((useRefPosition != nullptr && useRefPosition->delayRegFree) || (uses == 0));
}
}

srcCount += BuildDelayFreeUses(intrin.op3, prefUseNode);
}
else if (intrin.op2 != nullptr)
{
Expand Down
40 changes: 40 additions & 0 deletions src/tests/JIT/Regression/JitBlue/Runtime_106864/Runtime_106864.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// 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 v2.3 on 2024-08-23 09:12:06
// Run on Arm64 Windows
// Seed: 9639718980642677114-vectort,vector64,vector128,armsve
// Reduced from 52.6 KiB to 0.4 KiB in 00:00:26
// Hits JIT assert in Release:
// Assertion failed 'targetReg != embMaskOp2Reg' in 'Program:Main(Fuzzlyn.ExecutionServer.IRuntime)' during 'Generate code' (IL size 32; hash 0xade6b36b; FullOpts)
//
// File: C:\dev\dotnet\runtime2\src\coreclr\jit\hwintrinsiccodegenarm64.cpp Line: 818
//
using System;
using System.Numerics;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.Arm;

public class C1
{
public Vector<short> F1;
}

public class Runtime_106864
{
public static C1 s_2 = new C1();

[Fact]
public static void TestEntryPoint()
{
if (Sve.IsSupported)
{
C1 vr2 = s_2;
var vr3 = vr2.F1;
var vr4 = vr2.F1;
vr2.F1 = Sve.Max(vr3, vr4);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Optimize>True</Optimize>
<NoWarn>$(NoWarn),SYSLIB5003</NoWarn>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildProjectName).cs" />
</ItemGroup>
</Project>
54 changes: 54 additions & 0 deletions src/tests/JIT/Regression/JitBlue/Runtime_106867/Runtime_106867.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// 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 v2.3 on 2024-08-23 10:10:06
// Run on Arm64 Windows
// Seed: 13584223539078280353-vectort,vector64,vector128,armsve
// Reduced from 87.4 KiB to 0.8 KiB in 00:00:52
// Hits JIT assert in Release:
// Assertion failed 'secondId->idReg1() != secondId->idReg4()' in 'S0:M6(ubyte,double):this' during 'Emit code' (IL size 81; hash 0x596acd7c; FullOpts)
//
// File: C:\dev\dotnet\runtime2\src\coreclr\jit\emitarm64sve.cpp Line: 18601
//
using System;
using System.Numerics;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.Arm;

public struct S0
{
public void M6(byte arg0, double arg1)
{
var vr0 = Vector128.CreateScalar(119.12962f).AsVector();
var vr3 = Runtime_106867.s_2;
var vr4 = Vector128.CreateScalar(1f).AsVector();
var vr5 = Runtime_106867.s_2;
var vr2 = Sve.FusedMultiplySubtractNegated(vr3, vr4, vr5);
if ((Sve.ConditionalExtractLastActiveElement(vr0, 0, vr2) < 0))
{
this = this;
}
}
}

public class Runtime_106867
{
public static Vector<float> s_2;
public static double[] s_5 = new double[]
{
0
};
public static byte s_16;

[Fact]
public static void TestEntryPoint()
{
if (Sve.IsSupported)
{
var vr6 = s_5[0];
new S0().M6(s_16, vr6);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Optimize>True</Optimize>
<NoWarn>$(NoWarn),SYSLIB5003</NoWarn>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildProjectName).cs" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Xunit;
using System.Runtime.CompilerServices;

// Generated by Fuzzlyn v2.3 on 2024-08-23 10:12:51
// Run on Arm64 Windows
// Seed: 4576767951799510057-vectort,vector64,vector128,armsve
// Reduced from 32.2 KiB to 0.5 KiB in 00:00:25
// Hits JIT assert in Release:
// Assertion failed 'secondId->idReg1() != secondId->idReg3()' in 'Program:Main(Fuzzlyn.ExecutionServer.IRuntime)' during 'Emit code' (IL size 55; hash 0xade6b36b; FullOpts)
//
// File: C:\dev\dotnet\runtime2\src\coreclr\jit\emitarm64sve.cpp Line: 18600
//
using System;
using System.Numerics;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.Arm;

public class Runtime_106866_2
{
[Fact]
public static void TestEntryPoint()
{
if (Sve.IsSupported)
{
Vector<short> vr4 = default(Vector<short>);
vr4 = Sve.MultiplyAdd(vr4, vr4, vr4);
var vr5 = (short)0;
var vr6 = Vector128.CreateScalar(vr5).AsVector();
var vr7 = (short)0;
var vr8 = Sve.ConditionalExtractLastActiveElement(vr6, vr7, vr4);
Consume(vr8);
}
}

[MethodImpl(MethodImplOptions.NoInlining)]
static void Consume<T>(T val)
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Optimize>True</Optimize>
<NoWarn>$(NoWarn),SYSLIB5003</NoWarn>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildProjectName).cs" />
</ItemGroup>
</Project>

0 comments on commit 3c622af

Please sign in to comment.