Skip to content

Commit a5f99c6

Browse files
authored
JIT: fix local assertion prop error for partial local comparisons (#112506)
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.
1 parent 953bc61 commit a5f99c6

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
@@ -2223,6 +2223,22 @@ AssertionInfo Compiler::optAssertionGenJtrue(GenTree* tree)
22232223
// If op1 is lcl and op2 is const or lcl, create assertion.
22242224
if ((op1->gtOper == GT_LCL_VAR) && (op2->OperIsConst() || (op2->gtOper == GT_LCL_VAR))) // Fix for Dev10 851483
22252225
{
2226+
// Watch out for cases where long local(s) are implicitly truncated.
2227+
//
2228+
LclVarDsc* const lcl1Dsc = lvaGetDesc(op1->AsLclVarCommon());
2229+
if ((lcl1Dsc->TypeGet() == TYP_LONG) && (op1->TypeGet() != TYP_LONG))
2230+
{
2231+
return NO_ASSERTION_INDEX;
2232+
}
2233+
if (op2->OperIs(GT_LCL_VAR))
2234+
{
2235+
LclVarDsc* const lcl2Dsc = lvaGetDesc(op2->AsLclVarCommon());
2236+
if ((lcl2Dsc->TypeGet() == TYP_LONG) && (op2->TypeGet() != TYP_LONG))
2237+
{
2238+
return NO_ASSERTION_INDEX;
2239+
}
2240+
}
2241+
22262242
return optCreateJtrueAssertions(op1, op2, assertionKind);
22272243
}
22282244
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)