Skip to content

Commit 4c6e4e2

Browse files
Fix assertions related to combining cmn (extended-register) (#113337) (#113376)
Fixes issues highlighted by Fuzzlyn, related to erroneously combining cast=>negate=>compare into `cmn (extended-register)` when the second operand is an integral constant.
1 parent 379af99 commit 4c6e4e2

3 files changed

Lines changed: 105 additions & 2 deletions

File tree

src/coreclr/jit/lowerarmarch.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -406,8 +406,21 @@ bool Lowering::IsContainableUnaryOrBinaryOp(GenTree* parentNode, GenTree* childN
406406

407407
if (childNode->gtGetOp1()->OperIs(GT_CAST))
408408
{
409-
// Grab the cast as well, we can contain this with cmn.
410-
GenTreeCast* cast = childNode->gtGetOp1()->AsCast();
409+
// Grab the cast as well, we can contain this with cmn (extended-register).
410+
GenTreeCast* cast = childNode->gtGetOp1()->AsCast();
411+
GenTree* castOp = cast->CastOp();
412+
413+
// Cannot contain the cast from floating point.
414+
if (!varTypeIsIntegral(castOp))
415+
{
416+
return false;
417+
}
418+
419+
// Cannot contain the cast if it already contains it's CastOp.
420+
if (castOp->isContained())
421+
{
422+
return false;
423+
}
411424

412425
assert(!cast->gtOverflow());
413426
assert(varTypeIsIntegral(cast) && varTypeIsIntegral(cast->CastToType()));
@@ -3187,11 +3200,15 @@ bool Lowering::TryLowerAndOrToCCMP(GenTreeOp* tree, GenTree** next)
31873200
//
31883201
GenCondition cond1;
31893202
if (op2->OperIsCmpCompare() && varTypeIsIntegralOrI(op2->gtGetOp1()) && IsInvariantInRange(op2, tree) &&
3203+
(op2->gtGetOp1()->IsIntegralConst() || !op2->gtGetOp1()->isContained()) &&
3204+
(op2->gtGetOp2() == nullptr || op2->gtGetOp2()->IsIntegralConst() || !op2->gtGetOp2()->isContained()) &&
31903205
TryLowerConditionToFlagsNode(tree, op1, &cond1))
31913206
{
31923207
// Fall through, converting op2 to the CCMP
31933208
}
31943209
else if (op1->OperIsCmpCompare() && varTypeIsIntegralOrI(op1->gtGetOp1()) && IsInvariantInRange(op1, tree) &&
3210+
(op1->gtGetOp1()->IsIntegralConst() || !op1->gtGetOp1()->isContained()) &&
3211+
(op1->gtGetOp2() == nullptr || op1->gtGetOp2()->IsIntegralConst() || !op1->gtGetOp2()->isContained()) &&
31953212
TryLowerConditionToFlagsNode(tree, op2, &cond1))
31963213
{
31973214
std::swap(op1, op2);
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
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.Numerics;
6+
using System.Runtime.Intrinsics;
7+
using System.Runtime.Intrinsics.Arm;
8+
using System.Runtime.CompilerServices;
9+
using Xunit;
10+
11+
#pragma warning disable SYSLIB5003 // Allow experimental SVE
12+
13+
public class Runtime_113337
14+
{
15+
static sbyte[] s_7;
16+
17+
[MethodImpl(MethodImplOptions.NoInlining)]
18+
static void issue1()
19+
{
20+
try
21+
{
22+
var vr9 = Vector64.Create<float>(0);
23+
if ((2147483647 == (-(int)AdvSimd.Extract(vr9, 1))))
24+
{
25+
s_7 = s_7;
26+
}
27+
}
28+
catch (PlatformNotSupportedException e)
29+
{
30+
}
31+
}
32+
33+
static int[][] s_2;
34+
static bool s_3;
35+
36+
[MethodImpl(MethodImplOptions.NoInlining)]
37+
static void issue2()
38+
{
39+
try
40+
{
41+
s_3 ^= (2021486855 != (-(long)s_2[0][0]));
42+
}
43+
catch (NullReferenceException e)
44+
{
45+
}
46+
}
47+
48+
static Vector<ulong>[] s_4;
49+
[MethodImpl(MethodImplOptions.NoInlining)]
50+
static void issue3()
51+
{
52+
try
53+
{
54+
var vr3 = Vector.Create<short>(1);
55+
var vr4 = (short)0;
56+
var vr5 = Vector128.CreateScalar(vr4).AsVector();
57+
if ((Sve.TestFirstTrue(vr3, vr5) | (3268100580U != (-(uint)Sve.SaturatingDecrementBy16BitElementCount(0, 1)))))
58+
{
59+
s_4[0] = s_4[0];
60+
}
61+
}
62+
catch (PlatformNotSupportedException e)
63+
{
64+
}
65+
catch (NullReferenceException e)
66+
{
67+
}
68+
}
69+
70+
[Fact]
71+
public static void TestEntryPoint()
72+
{
73+
// Checking for successful compilation
74+
issue1();
75+
issue2();
76+
issue3();
77+
}
78+
}
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)