Skip to content

Commit d03b2d0

Browse files
authored
Arm64/Sve: Fix overzealous assert for embedded mask intrinsics with RMW semantics (#105541)
1 parent 0fbd814 commit d03b2d0

File tree

5 files changed

+112
-24
lines changed

5 files changed

+112
-24
lines changed

src/coreclr/jit/hwintrinsiccodegenarm64.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
551551
// If `falseReg` is zero, then move the first operand of `intrinEmbMask` in the
552552
// destination using /Z.
553553

554-
assert(targetReg != embMaskOp2Reg);
554+
assert((targetReg != embMaskOp2Reg) || (embMaskOp1Reg == embMaskOp2Reg));
555555
assert(intrin.op3->isContained() || !intrin.op1->IsMaskAllBitsSet());
556556
GetEmitter()->emitInsSve_R_R_R(INS_sve_movprfx, emitSize, targetReg, maskReg, embMaskOp1Reg, opt);
557557
}
@@ -870,7 +870,6 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
870870

871871
if (HWIntrinsicInfo::IsFmaIntrinsic(intrinEmbMask.id))
872872
{
873-
assert(falseReg != embMaskOp3Reg);
874873
// For FMA, the operation we are trying to perform is:
875874
// result = op1 + (op2 * op3)
876875
//

src/tests/JIT/Regression/JitBlue/Runtime_105474/Runtime_105474.cs

Lines changed: 53 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,42 +3,73 @@
33

44
using System;
55
using System.Runtime.CompilerServices;
6+
using System.Numerics;
67
using System.Runtime.Intrinsics;
78
using System.Runtime.Intrinsics.Arm;
8-
using System.Runtime.Intrinsics.X86;
99
using Xunit;
1010

11-
#nullable disable
12-
13-
public class Runtime_105474_A
11+
public class Runtime_105474
1412
{
15-
private void Method0()
13+
private static Vector<double> s_3;
14+
15+
[Fact]
16+
public static void TestEntryPoint()
1617
{
17-
Vector128<ulong> vr0 = Vector128.CreateScalar(1698800584428641629UL);
18-
AdvSimd.ShiftLeftLogicalSaturate(vr0, 229);
18+
if (Sve.IsSupported)
19+
{
20+
TestMethod1();
21+
TestMethod2(Vector<double>.Zero);
22+
TestMethod3(Vector<double>.Zero);
23+
TestMethod4(Vector<double>.Zero);
24+
TestMethod5(Vector<double>.Zero);
25+
TestMethod6(Vector<double>.Zero);
26+
}
1927
}
2028

21-
private void Method1()
29+
[method: MethodImpl(MethodImplOptions.NoInlining)]
30+
private static void TestMethod1()
2231
{
23-
Vector128<float> vr1 = default;
24-
Avx.Compare(vr1, vr1, (FloatComparisonMode)255);
32+
// Expected codegen: fmad z17.d, p0/m, z17.d, z16.d
33+
var vr1 = Vector128.CreateScalar((double)10).AsVector();
34+
s_3 = Sve.FusedMultiplyAdd(vr1, s_3, s_3);
2535
}
2636

27-
[Fact]
28-
public static void TestEntryPointArm()
37+
[method: MethodImpl(MethodImplOptions.NoInlining)]
38+
private static void TestMethod2(Vector<double> mask)
2939
{
30-
if (AdvSimd.IsSupported)
31-
{
32-
Assert.Throws<ArgumentOutOfRangeException>(() => new Runtime_105474_A().Method0());
33-
}
40+
// Expected codegen: fmla z16.d, p0/m, z17.d, z17.d
41+
var vr1 = Vector128.CreateScalar((double)10).AsVector();
42+
s_3 = Sve.ConditionalSelect(mask, Sve.FusedMultiplyAdd(vr1, s_3, s_3), s_3);
3443
}
3544

36-
[Fact]
37-
public static void TestEntryPoint()
45+
[method: MethodImpl(MethodImplOptions.NoInlining)]
46+
private static void TestMethod3(Vector<double> mask)
3847
{
39-
if (Avx.IsSupported)
40-
{
41-
Assert.Throws<ArgumentOutOfRangeException>(() => new Runtime_105474_A().Method1());
42-
}
48+
// Expected codegen: fmad z16.d, p0/m, z16.d, z16.d
49+
s_3 = Sve.ConditionalSelect(mask, Sve.FusedMultiplyAdd(s_3, s_3, s_3), s_3);
50+
}
51+
52+
[method: MethodImpl(MethodImplOptions.NoInlining)]
53+
private static void TestMethod4(Vector<double> mask)
54+
{
55+
// Expected codegen: fmad z16.d, p0/m, z17.d, z16.d
56+
var vr1 = Vector128.CreateScalar((double)10).AsVector();
57+
s_3 = Sve.ConditionalSelect(mask, Sve.FusedMultiplyAdd(s_3, vr1, s_3), s_3);
58+
}
59+
60+
[method: MethodImpl(MethodImplOptions.NoInlining)]
61+
private static void TestMethod5(Vector<double> mask)
62+
{
63+
// Expected codegen: fmad z16.d, p0/m, z16.d, z17.d
64+
var vr1 = Vector128.CreateScalar((double)10).AsVector();
65+
s_3 = Sve.ConditionalSelect(mask, Sve.FusedMultiplyAdd(s_3, vr1, vr1), s_3);
66+
}
67+
68+
[method: MethodImpl(MethodImplOptions.NoInlining)]
69+
private static void TestMethod6(Vector<double> mask)
70+
{
71+
// Expected codegen: fmad z16.d, p0/m, z16.d, z16.d
72+
var vr1 = Vector128.CreateScalar((double)10).AsVector();
73+
s_3 = Sve.ConditionalSelect(mask, Sve.FusedMultiplyAdd(vr1, vr1, vr1), s_3);
4374
}
4475
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
3+
<!-- Needed for CLRTestEnvironmentVariable -->
4+
<RequiresProcessIsolation>true</RequiresProcessIsolation>
5+
<DebugType>None</DebugType>
36
<Optimize>True</Optimize>
7+
<NoWarn>$(NoWarn);SYSLIB5003</NoWarn>
48
</PropertyGroup>
59
<ItemGroup>
610
<Compile Include="$(MSBuildProjectName).cs" />
11+
<CLRTestEnvironmentVariable Include="DOTNET_TieredCompilation" Value="0" />
12+
<CLRTestEnvironmentVariable Include="DOTNET_JITMinOpts" Value="0" />
713
</ItemGroup>
814
</Project>
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
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+
using System;
5+
using System.Runtime.CompilerServices;
6+
using System.Runtime.Intrinsics;
7+
using System.Runtime.Intrinsics.Arm;
8+
using System.Runtime.Intrinsics.X86;
9+
using Xunit;
10+
11+
#nullable disable
12+
13+
public class Runtime_105479_A
14+
{
15+
private void Method0()
16+
{
17+
Vector128<ulong> vr0 = Vector128.CreateScalar(1698800584428641629UL);
18+
AdvSimd.ShiftLeftLogicalSaturate(vr0, 229);
19+
}
20+
21+
private void Method1()
22+
{
23+
Vector128<float> vr1 = default;
24+
Avx.Compare(vr1, vr1, (FloatComparisonMode)255);
25+
}
26+
27+
[Fact]
28+
public static void TestEntryPointArm()
29+
{
30+
if (AdvSimd.IsSupported)
31+
{
32+
Assert.Throws<ArgumentOutOfRangeException>(() => new Runtime_105479_A().Method0());
33+
}
34+
}
35+
36+
[Fact]
37+
public static void TestEntryPoint()
38+
{
39+
if (Avx.IsSupported)
40+
{
41+
Assert.Throws<ArgumentOutOfRangeException>(() => new Runtime_105479_A().Method1());
42+
}
43+
}
44+
}
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)