Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Arm64: Support additional condition checks in select nodes #78223

Merged
merged 1 commit into from
Nov 14, 2022
Merged
Show file tree
Hide file tree
Changes from all 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
11 changes: 11 additions & 0 deletions src/coreclr/jit/codegenarm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4752,6 +4752,17 @@ void CodeGen::genCodeForSelect(GenTreeConditional* tree)
const GenConditionDesc& prevDesc = GenConditionDesc::Get(prevCond);

emit->emitIns_R_R_R_COND(INS_csel, attr, targetReg, srcReg1, srcReg2, JumpKindToInsCond(prevDesc.jumpKind1));

// Some conditions require an additional condition check.
if (prevDesc.oper == GT_OR)
{
emit->emitIns_R_R_R_COND(INS_csel, attr, targetReg, srcReg1, targetReg, JumpKindToInsCond(prevDesc.jumpKind2));
}
else if (prevDesc.oper == GT_AND)
{
emit->emitIns_R_R_R_COND(INS_csel, attr, targetReg, targetReg, srcReg2, JumpKindToInsCond(prevDesc.jumpKind2));
}

regSet.verifyRegUsed(targetReg);
genProduceReg(tree);
}
Expand Down
3 changes: 2 additions & 1 deletion src/coreclr/jit/optimizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4853,7 +4853,8 @@ bool Compiler::optIfConvert(BasicBlock* block)
}

// Invert the condition.
cond->gtOper = GenTree::ReverseRelop(cond->gtOper);
GenTree* revCond = gtReverseCond(cond);
assert(cond == revCond); // Ensure `gtReverseCond` did not create a new node.

// Create a select node.
GenTreeConditional* select =
Expand Down
119 changes: 118 additions & 1 deletion src/tests/JIT/opt/Compares/compares.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,111 @@ public class SideEffects

[MethodImpl(MethodImplOptions.NoInlining)]
public static bool EqualsOrGreaterThan_MaxValue_LHSConst_SideEffects(SideEffects c) => c.B <= 255;


[MethodImpl(MethodImplOptions.NoInlining)]
public static void consume<T>(T a1, T a2) {}

/* If conditions that are consumed. */

[MethodImpl(MethodImplOptions.NoInlining)]
public static void Eq_byte_consume(byte a1, byte a2) {
//ARM64-FULL-LINE: cmp {{w[0-9]+}}, {{w[0-9]+}}
//ARM64-FULL-LINE-NEXT: csel {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, eq
if (a1 == a2) { a1 = 10; }
consume<byte>(a1, a2);
}

[MethodImpl(MethodImplOptions.NoInlining)]
public static void Ne_short_consume(short a1, short a2)
{
//ARM64-FULL-LINE: cmp {{w[0-9]+}}, {{w[0-9]+}}
//ARM64-NEXT-FULL-LINE: csel {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, ne
if (a1 != a2) { a1 = 11; }
consume<short>(a1, a2);
}

[MethodImpl(MethodImplOptions.NoInlining)]
public static void Lt_int_consume(int a1, int a2)
{
//ARM64-FULL-LINE: cmp {{w[0-9]+}}, {{w[0-9]+}}
//ARM64-NEXT-FULL-LINE: csel {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, lt
if (a1 < a2) { a1 = 12; }
consume<int>(a1, a2);
}

[MethodImpl(MethodImplOptions.NoInlining)]
public static void Le_long_consume(long a1, long a2)
{
//ARM64-FULL-LINE: cmp {{x[0-9]+}}, {{x[0-9]+}}
//ARM64-NEXT-FULL-LINE: csel {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, le
if (a1 <= a2) { a1 = 13; }
consume<long>(a1, a2);
}

[MethodImpl(MethodImplOptions.NoInlining)]
public static void Gt_ushort_consume(ushort a1, ushort a2)
{
//ARM64-FULL-LINE: cmp {{w[0-9]+}}, {{w[0-9]+}}
//ARM64-NEXT-FULL-LINE: csel {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, gt
if (a1 > a2) { a1 = 14; }
consume<ushort>(a1, a2);
}

[MethodImpl(MethodImplOptions.NoInlining)]
public static void Ge_uint_consume(uint a1, uint a2)
{
//ARM64-FULL-LINE: cmp {{w[0-9]+}}, {{w[0-9]+}}
//ARM64-NEXT-FULL-LINE: csel {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, ge
if (a1 >= a2) { a1 = 15; }
consume<uint>(a1, a2);
}

[MethodImpl(MethodImplOptions.NoInlining)]
public static void Eq_ulong_consume(ulong a1, ulong a2)
{
//ARM64-FULL-LINE: cmp {{x[0-9]+}}, {{x[0-9]+}}
//ARM64-NEXT-FULL-LINE: csel {{x[0-9]+}}, {{x[0-9]+}}, {{x[0-9]+}}, eq
if (a1 == a2) { a1 = 16; }
consume<ulong>(a1, a2);
}

[MethodImpl(MethodImplOptions.NoInlining)]
public static void Ne_float_int_consume(float f1, float f2, int a1, int a2)
{
//ARM64-FULL-LINE: fcmp {{s[0-9]+}}, {{s[0-9]+}}
//ARM64-NEXT-FULL-LINE: csel {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, ne
if (f1 != f2) { a1 = 17; }
consume<float>(a1, a2);
}

[MethodImpl(MethodImplOptions.NoInlining)]
public static void Lt_double_long_consume(double f1, double f2, long a1, long a2)
{
//ARM64-FULL-LINE: fcmp {{d[0-9]+}}, {{d[0-9]+}}
//ARM64-NEXT-FULL-LINE: csel {{x[0-31]}}, {{x[0-31]}}, {{x[0-31]}}, lt
if (f1 < f2) { a1 = 18; }
consume<double>(a1, a2);
}

[MethodImpl(MethodImplOptions.NoInlining)]
public static void Eq_double_long_consume(double f1, double f2, long a1, long a2)
{
//ARM64-FULL-LINE: fcmp {{d[0-9]+}}, {{d[0-9]+}}
//ARM64-NEXT-FULL-LINE: csel {{x[0-31]}}, {{x[0-31]}}, {{x[0-31]}}, eq
if (f1 == f2) { a1 = 18; }
consume<double>(a1, a2);
}

[MethodImpl(MethodImplOptions.NoInlining)]
public static void Ne_double_int_consume(double f1, double f2, int a1, int a2)
{
//ARM64-FULL-LINE: fcmp {{d[0-9]+}}, {{d[0-9]+}}
//ARM64-NEXT-FULL-LINE: csel {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, ne
if (f1 != f2) { a1 = 18; }
consume<double>(a1, a2);
}

public static int Main()
{
// Optimize comparison with full range values
Expand Down Expand Up @@ -197,7 +302,19 @@ public static int Main()
Console.WriteLine("FullRangeComparisonTest:EqualsOrGreaterThan_MaxValue_LHSConst_SideEffects(null) failed");
return 101;
}


Eq_byte_consume(10, 11);
Ne_short_consume(10, 11);
Lt_int_consume(10, 11);
Le_long_consume(10, 11);
Gt_ushort_consume(10, 11);
Ge_uint_consume(10, 11);
Eq_ulong_consume(10, 11);
Ne_float_int_consume(10.1F, 11.1F, 12, 13);
Lt_double_long_consume(10.1, 11.1, 12, 13);
Eq_double_long_consume(10.1, 11.1, 12, 13);
Ne_double_int_consume(10.1, 11.1, 12, 13);

Console.WriteLine("PASSED");
return 100;
}
Expand Down
9 changes: 7 additions & 2 deletions src/tests/JIT/opt/Compares/compares.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@
<OutputType>Exe</OutputType>
</PropertyGroup>
<PropertyGroup>
<DebugType>PdbOnly</DebugType>
<DebugType>None</DebugType>
<Optimize>True</Optimize>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildProjectName).cs" />
<Compile Include="$(MSBuildProjectName).cs">
<HasDisasmCheck>true</HasDisasmCheck>
</Compile>

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