Skip to content

Commit 8a346d2

Browse files
[release/9.0-staging] JIT: fix local assertion prop error for partial local comparisons (#112539)
* JIT: fix local assertion prop error for partial local comparisons If a JTRUE comparison only involves part of a local value we cannot make assertions about the local as a whole. Fixes #111352. * restrict to TYP_LONG locals --------- Co-authored-by: Andy Ayers <[email protected]>
1 parent 6a30014 commit 8a346d2

File tree

3 files changed

+66
-0
lines changed

3 files changed

+66
-0
lines changed

src/coreclr/jit/assertionprop.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2211,6 +2211,22 @@ AssertionInfo Compiler::optAssertionGenJtrue(GenTree* tree)
22112211
// If op1 is lcl and op2 is const or lcl, create assertion.
22122212
if ((op1->gtOper == GT_LCL_VAR) && (op2->OperIsConst() || (op2->gtOper == GT_LCL_VAR))) // Fix for Dev10 851483
22132213
{
2214+
// Watch out for cases where long local(s) are implicitly truncated.
2215+
//
2216+
LclVarDsc* const lcl1Dsc = lvaGetDesc(op1->AsLclVarCommon());
2217+
if ((lcl1Dsc->TypeGet() == TYP_LONG) && (op1->TypeGet() != TYP_LONG))
2218+
{
2219+
return NO_ASSERTION_INDEX;
2220+
}
2221+
if (op2->OperIs(GT_LCL_VAR))
2222+
{
2223+
LclVarDsc* const lcl2Dsc = lvaGetDesc(op2->AsLclVarCommon());
2224+
if ((lcl2Dsc->TypeGet() == TYP_LONG) && (op2->TypeGet() != TYP_LONG))
2225+
{
2226+
return NO_ASSERTION_INDEX;
2227+
}
2228+
}
2229+
22142230
return optCreateJtrueAssertions(op1, op2, assertionKind);
22152231
}
22162232
else if (!optLocalAssertionProp)
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
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.Runtime.CompilerServices;
5+
using Xunit;
6+
7+
public class Runtime_111352
8+
{
9+
[Fact]
10+
public static int Test1() => Problem1(0x1_0000_0001L, 0x2_0000_0001L);
11+
12+
[MethodImpl(MethodImplOptions.NoInlining)]
13+
public static int Problem1(long x, long y)
14+
{
15+
if ((uint)x == (uint)y)
16+
{
17+
if (x == y)
18+
{
19+
return -1;
20+
}
21+
}
22+
23+
return 100;
24+
}
25+
26+
[Fact]
27+
public static int Test2() => Problem2(0x1_0000_0000L);
28+
29+
[MethodImpl(MethodImplOptions.NoInlining)]
30+
public static int Problem2(long x)
31+
{
32+
if ((uint)x == 0)
33+
{
34+
if (x == 0)
35+
{
36+
return -1;
37+
}
38+
}
39+
40+
return 100;
41+
}
42+
}
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)