Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/coreclr/jit/lowerarmarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3919,11 +3919,11 @@ void Lowering::ContainCheckHWIntrinsic(GenTreeHWIntrinsic* node)
}

// Handle op3
if (op3->IsVectorZero() && op1->IsMaskAllBitsSet())
if (op3->IsVectorZero() && op1->IsMaskAllBitsSet() && op2->IsEmbMaskOp())
{
// When we are merging with zero, we can specialize
// and avoid instantiating the vector constant.
// Do this only if op1 was AllTrueMask
// Do this only if op1 was AllTrueMask and op2 is embedded.
MakeSrcContained(node, op3);
}
Copy link
Member

@tannergooding tannergooding Aug 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is the right fix. The zero (and in fact any constant or other value here) is still containable.

op1 is AllBitsSet so therefore nothing from op3 can ever be selected, so it is "unused". This means it is valid to drop the sel entirely and just emit op2 directly.

The only time we should be hitting this path is when op2 is an operation that requires a mask to be specified (even if unused) or some manually written user code in minopts. For the latter, it's still fine to contain the zero constant and just use the op2 register for both inputs (containment is a basic operation that happens at all codegen levels).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

op1 is AllBitsSet so therefore nothing from op3 can ever be selected, so it is "unused". This means it is valid to drop the sel entirely and just emit op2 directly.

Updated to do this instead.

Required the embedded HWIntrinsic check, otherwise lowering goes into an infinite loop adding and removing conditional selects.


Expand Down
31 changes: 31 additions & 0 deletions src/tests/JIT/Regression/JitBlue/Runtime_105719/Runtime_105719.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// 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;
using System.Runtime.CompilerServices;
using System.Numerics;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.Arm;

public class Runtime_105723
{
[Fact]
public static void TestEntryPoint()
{
if (Sve.IsSupported)
{
var vr3 = Sve.CreateTrueMaskInt32();
var vr4 = Vector.Create<int>(1);
var vr5 = Vector128.CreateScalar(0).AsVector();
Vector<int> vr6 = Sve.ConditionalSelect(vr3, vr4, vr5);
Consume(vr6);
}
}

[MethodImpl(MethodImplOptions.NoInlining)]
private static void Consume(Vector<int> v)
{
;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!-- Needed for CLRTestEnvironmentVariable -->
<RequiresProcessIsolation>true</RequiresProcessIsolation>
<Optimize>True</Optimize>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildProjectName).cs" />

<CLRTestEnvironmentVariable Include="DOTNET_TieredCompilation" Value="0" />
</ItemGroup>
</Project>