Skip to content

Commit

Permalink
ARM64-SVE: Allow op inside conditionalselect to be non HWintrinsic (#…
Browse files Browse the repository at this point in the history
…107180)

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

* Add Sve.IsSupported check to test
  • Loading branch information
a74nh committed Sep 9, 2024
1 parent ac4b7c6 commit 2ed43b6
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 33 deletions.
68 changes: 35 additions & 33 deletions src/coreclr/jit/lowerarmarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4050,47 +4050,49 @@ GenTree* Lowering::LowerHWIntrinsicCndSel(GenTreeHWIntrinsic* cndSelNode)
GenTree* nestedOp1 = nestedCndSel->Op(1);
GenTree* nestedOp2 = nestedCndSel->Op(2);
assert(varTypeIsMask(nestedOp1));
assert(nestedOp2->OperIsHWIntrinsic());

NamedIntrinsic nestedOp2Id = nestedOp2->AsHWIntrinsic()->GetHWIntrinsicId();

// If the nested op uses Pg/Z, then inactive lanes will result in zeros, so can only transform if
// op3 is all zeros. Such a Csel operation is absorbed into the instruction when emitted. Skip this optimisation
// when the nestedOp is a reduce operation.

if (nestedOp1->IsMaskAllBitsSet() && !HWIntrinsicInfo::IsReduceOperation(nestedOp2Id) &&
(!HWIntrinsicInfo::IsZeroingMaskedOperation(nestedOp2Id) || op3->IsVectorZero()))
if (nestedOp2->OperIsHWIntrinsic())
{
GenTree* nestedOp2 = nestedCndSel->Op(2);
GenTree* nestedOp3 = nestedCndSel->Op(3);
NamedIntrinsic nestedOp2Id = nestedOp2->AsHWIntrinsic()->GetHWIntrinsicId();

JITDUMP("lowering nested ConditionalSelect HWIntrinisic (before):\n");
DISPTREERANGE(BlockRange(), cndSelNode);
JITDUMP("\n");
// If the nested op uses Pg/Z, then inactive lanes will result in zeros, so can only transform if
// op3 is all zeros. Such a Csel operation is absorbed into the instruction when emitted. Skip this
// optimisation when the nestedOp is a reduce operation.

// Transform:
//
// CndSel(mask, CndSel(AllTrue, embeddedMask(trueValOp2), trueValOp3), op3) to
// CndSel(mask, embedded(trueValOp2), op3)
//
cndSelNode->Op(2) = nestedCndSel->Op(2);
if (nestedOp3->IsMaskZero())
{
BlockRange().Remove(nestedOp3);
}
else
if (nestedOp1->IsMaskAllBitsSet() && !HWIntrinsicInfo::IsReduceOperation(nestedOp2Id) &&
(!HWIntrinsicInfo::IsZeroingMaskedOperation(nestedOp2Id) || op3->IsVectorZero()))
{
nestedOp3->SetUnusedValue();
}
GenTree* nestedOp2 = nestedCndSel->Op(2);
GenTree* nestedOp3 = nestedCndSel->Op(3);

JITDUMP("lowering nested ConditionalSelect HWIntrinisic (before):\n");
DISPTREERANGE(BlockRange(), cndSelNode);
JITDUMP("\n");

// Transform:
//
// CndSel(mask, CndSel(AllTrue, embeddedMask(trueValOp2), trueValOp3), op3) to
// CndSel(mask, embedded(trueValOp2), op3)
//
cndSelNode->Op(2) = nestedCndSel->Op(2);
if (nestedOp3->IsMaskZero())
{
BlockRange().Remove(nestedOp3);
}
else
{
nestedOp3->SetUnusedValue();
}

BlockRange().Remove(nestedOp1);
BlockRange().Remove(nestedCndSel);
BlockRange().Remove(nestedOp1);
BlockRange().Remove(nestedCndSel);

JITDUMP("lowering nested ConditionalSelect HWIntrinisic (after):\n");
DISPTREERANGE(BlockRange(), cndSelNode);
JITDUMP("\n");
JITDUMP("lowering nested ConditionalSelect HWIntrinisic (after):\n");
DISPTREERANGE(BlockRange(), cndSelNode);
JITDUMP("\n");

return cndSelNode;
return cndSelNode;
}
}
}
else if (op1->IsMaskAllBitsSet())
Expand Down
59 changes: 59 additions & 0 deletions src/tests/JIT/Regression/JitBlue/Runtime_106869/Runtime_106869.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// 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:25:51
// Run on Arm64 Windows
// Seed: 13938901376337307772-vectort,vector64,vector128,armsve
// Reduced from 210.5 KiB to 1.1 KiB in 00:02:19
// Hits JIT assert in Release:
// Assertion failed 'nestedOp2->OperIsHWIntrinsic()' in 'Program:Main(Fuzzlyn.ExecutionServer.IRuntime)' during 'Lowering nodeinfo' (IL size 119; hash 0xade6b36b; FullOpts)
//
// File: C:\dev\dotnet\runtime2\src\coreclr\jit\lowerarmarch.cpp Line: 4062
//
using System;
using System.Numerics;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.Arm;

public struct S0
{
public ulong F5;
}

public class C0
{
public int F1;
}

public class Runtime_1068867
{
public static S0 s_7;
public static byte s_14;

[Fact]
public static void TestEntryPoint()
{
if (Sve.IsSupported)
{
var vr12 = new C0();
var vr14 = vr12.F1;
var vr15 = Vector128.CreateScalar(vr14).AsVector();
var vr16 = Vector128.CreateScalar(0).AsVector();
var vr17 = Vector128.CreateScalar(0).AsVector();
var vr18 = Vector128.CreateScalar(0).AsVector();
var vr19 = Vector128.CreateScalar(1).AsVector();
var vr20 = Sve.ConditionalSelect(vr17, vr18, vr19);
var vr21 = Vector128.CreateScalar(0).AsVector();
var vr22 = Sve.ConditionalSelect(vr16, vr20, vr21);
Consume(vr22);
}
}

[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 2ed43b6

Please sign in to comment.