Skip to content

Commit 55805ee

Browse files
Don't do an invalid mask conversion optimization for conditional select nodes (#118154)
1 parent 9c714ff commit 55805ee

File tree

5 files changed

+52
-78
lines changed

5 files changed

+52
-78
lines changed

src/coreclr/jit/gentree.cpp

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28461,22 +28461,6 @@ bool GenTree::OperIsConvertVectorToMask() const
2846128461
return false;
2846228462
}
2846328463

28464-
//------------------------------------------------------------------------
28465-
// OperIsVectorConditionalSelect: Is this a vector ConditionalSelect hwintrinsic
28466-
//
28467-
// Return Value:
28468-
// true if the node is a vector ConditionalSelect hwintrinsic
28469-
// otherwise; false
28470-
//
28471-
bool GenTree::OperIsVectorConditionalSelect() const
28472-
{
28473-
if (OperIsHWIntrinsic())
28474-
{
28475-
return AsHWIntrinsic()->OperIsVectorConditionalSelect();
28476-
}
28477-
return false;
28478-
}
28479-
2848028464
//------------------------------------------------------------------------
2848128465
// OperIsVectorFusedMultiplyOp: Is this a vector FusedMultiplyOp hwintrinsic
2848228466
//

src/coreclr/jit/gentree.h

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1715,7 +1715,6 @@ struct GenTree
17151715
bool OperIsHWIntrinsic(NamedIntrinsic intrinsicId) const;
17161716
bool OperIsConvertMaskToVector() const;
17171717
bool OperIsConvertVectorToMask() const;
1718-
bool OperIsVectorConditionalSelect() const;
17191718
bool OperIsVectorFusedMultiplyOp() const;
17201719

17211720
// This is here for cleaner GT_LONG #ifdefs.
@@ -6576,34 +6575,6 @@ struct GenTreeHWIntrinsic : public GenTreeJitIntrinsic
65766575
#endif
65776576
}
65786577

6579-
bool OperIsVectorConditionalSelect() const
6580-
{
6581-
switch (GetHWIntrinsicId())
6582-
{
6583-
#if defined(TARGET_XARCH)
6584-
case NI_Vector128_ConditionalSelect:
6585-
case NI_Vector256_ConditionalSelect:
6586-
case NI_Vector512_ConditionalSelect:
6587-
{
6588-
return true;
6589-
}
6590-
#endif // TARGET_XARCH
6591-
6592-
#if defined(TARGET_ARM64)
6593-
case NI_AdvSimd_BitwiseSelect:
6594-
case NI_Sve_ConditionalSelect:
6595-
{
6596-
return true;
6597-
}
6598-
#endif // TARGET_ARM64
6599-
6600-
default:
6601-
{
6602-
return false;
6603-
}
6604-
}
6605-
}
6606-
66076578
bool OperIsVectorFusedMultiplyOp() const
66086579
{
66096580
switch (GetHWIntrinsicId())

src/coreclr/jit/optimizemaskconversions.cpp

Lines changed: 3 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -175,37 +175,11 @@ class MaskConversionsCheckVisitor final : public GenTreeVisitor<MaskConversionsC
175175

176176
// Look for:
177177
// user: ConvertVectorToMask(use:LCL_VAR(x)))
178-
// -or-
179-
// user: ConditionalSelect(use:LCL_VAR(x), y, z)
180178

181-
if ((user != nullptr) && user->OperIsHWIntrinsic())
179+
if ((user != nullptr) && user->OperIsConvertVectorToMask())
182180
{
183-
GenTreeHWIntrinsic* hwintrin = user->AsHWIntrinsic();
184-
NamedIntrinsic ni = hwintrin->GetHWIntrinsicId();
185-
186-
if (hwintrin->OperIsConvertVectorToMask())
187-
{
188-
convertOp = user->AsHWIntrinsic();
189-
hasConversion = true;
190-
}
191-
else if (hwintrin->OperIsVectorConditionalSelect())
192-
{
193-
// We don't actually have a convert here, but we do have a case where
194-
// the mask is being used in a ConditionalSelect and therefore can be
195-
// consumed directly as a mask. While the IR shows TYP_SIMD, it gets
196-
// handled in lowering as part of the general embedded-mask support.
197-
198-
// We notably don't check that op2 supported embedded masking directly
199-
// because we can still consume the mask directly in such cases. We'll just
200-
// emit `vblendmps zmm1 {k1}, zmm2, zmm3` instead of containing the CndSel
201-
// as part of something like `vaddps zmm1 {k1}, zmm2, zmm3`
202-
203-
if (hwintrin->Op(1) == lclOp)
204-
{
205-
convertOp = user->AsHWIntrinsic();
206-
hasConversion = true;
207-
}
208-
}
181+
convertOp = user->AsHWIntrinsic();
182+
hasConversion = true;
209183
}
210184
break;
211185
}
@@ -402,7 +376,6 @@ class MaskConversionsUpdateVisitor final : public GenTreeVisitor<MaskConversions
402376

403377
lclOp->Data() = lclOp->Data()->AsHWIntrinsic()->Op(1);
404378
}
405-
406379
else if (isLocalStore && addConversion)
407380
{
408381
// Convert
@@ -416,7 +389,6 @@ class MaskConversionsUpdateVisitor final : public GenTreeVisitor<MaskConversions
416389
lclOp->Data() = m_compiler->gtNewSimdCvtVectorToMaskNode(TYP_MASK, lclOp->Data(), weight->simdBaseJitType,
417390
weight->simdSize);
418391
}
419-
420392
else if (isLocalUse && removeConversion)
421393
{
422394
// Convert
@@ -426,7 +398,6 @@ class MaskConversionsUpdateVisitor final : public GenTreeVisitor<MaskConversions
426398

427399
*use = lclOp;
428400
}
429-
430401
else if (isLocalUse && addConversion)
431402
{
432403
// Convert
@@ -510,7 +481,6 @@ class MaskConversionsUpdateVisitor final : public GenTreeVisitor<MaskConversions
510481
PhaseStatus Compiler::fgOptimizeMaskConversions()
511482
{
512483
#if defined(FEATURE_MASKED_HW_INTRINSICS)
513-
514484
if (opts.OptimizationDisabled())
515485
{
516486
JITDUMP("Skipping. Optimizations Disabled\n");
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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.Buffers.Text;
6+
using System.Linq;
7+
using System.Runtime.CompilerServices;
8+
using System.Threading;
9+
using Xunit;
10+
11+
public class Runtime_118143
12+
{
13+
[Fact]
14+
public static void TestEntryPoint()
15+
{
16+
for (int i = 0; i < 300; i++)
17+
{
18+
RunBase64Test();
19+
Thread.Sleep(1);
20+
}
21+
}
22+
23+
[MethodImpl(MethodImplOptions.NoInlining)]
24+
private static void RunBase64Test()
25+
{
26+
byte[] input = new byte[64];
27+
byte[] output = new byte[Base64.GetMaxEncodedToUtf8Length(input.Length)];
28+
byte[] expected = Convert.FromHexString(
29+
"5957466859574668595746685957466859574668595746685957466859574668595746685957466859574668" +
30+
"5957466859574668595746685957466859574668595746685957466859574668595746685957466859513D3D");
31+
input.AsSpan().Fill((byte)'a');
32+
Base64.EncodeToUtf8(input, output, out _, out _);
33+
if (!output.SequenceEqual(expected))
34+
throw new InvalidOperationException("Invalid Base64 output");
35+
}
36+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<Optimize>True</Optimize>
4+
<!-- Needed for CLRTestEnvironmentVariable -->
5+
<RequiresProcessIsolation>true</RequiresProcessIsolation>
6+
</PropertyGroup>
7+
<ItemGroup>
8+
<Compile Include="$(MSBuildProjectName).cs" />
9+
<!-- The issue reproduces only with tiered compilation and PGO enabled -->
10+
<CLRTestEnvironmentVariable Include="DOTNET_TieredCompilation" Value="1" />
11+
<CLRTestEnvironmentVariable Include="DOTNET_TieredPGO" Value="1" />
12+
</ItemGroup>
13+
</Project>

0 commit comments

Comments
 (0)