Skip to content

Commit a78f02b

Browse files
authored
JIT: fix x86 EH issue when removing an empty try (#115731)
Morph may have already cleared out the continuation block, so we won't find a GT_END_LFIN there. Fixes #115700
1 parent 307d19e commit a78f02b

File tree

5 files changed

+82
-3
lines changed

5 files changed

+82
-3
lines changed

src/coreclr/jit/codegenxarch.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4879,7 +4879,8 @@ void CodeGen::genCodeForShift(GenTree* tree)
48794879
{
48804880
int shiftByValue = (int)shiftBy->AsIntConCommon()->IconValue();
48814881

4882-
if (tree->OperIsRotate() && compiler->compOpportunisticallyDependsOn(InstructionSet_BMI2) && !tree->gtSetFlags())
4882+
if (tree->OperIsRotate() && compiler->compOpportunisticallyDependsOn(InstructionSet_BMI2) &&
4883+
!tree->gtSetFlags())
48834884
{
48844885
// If we have a contained source operand, we must emit rorx.
48854886
// We may also use rorx for 64bit values when a mov would otherwise be required,
@@ -4906,7 +4907,8 @@ void CodeGen::genCodeForShift(GenTree* tree)
49064907
return;
49074908
}
49084909
}
4909-
else if (tree->OperIsShift() && compiler->compOpportunisticallyDependsOn(InstructionSet_BMI2) && !tree->gtSetFlags())
4910+
else if (tree->OperIsShift() && compiler->compOpportunisticallyDependsOn(InstructionSet_BMI2) &&
4911+
!tree->gtSetFlags())
49104912
{
49114913
// Emit shlx, sarx, shrx if BMI2 is available instead of mov+shl, mov+sar, mov+shr.
49124914
switch (tree->OperGet())

src/coreclr/jit/fgehopt.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1889,9 +1889,12 @@ void Compiler::fgCleanupContinuation(BasicBlock* continuation)
18891889

18901890
// Remove the GT_END_LFIN from the continuation,
18911891
// Note we only expect to see one such statement.
1892+
//
18921893
bool foundEndLFin = false;
1894+
bool isEmpty = true;
18931895
for (Statement* const stmt : continuation->Statements())
18941896
{
1897+
isEmpty = false;
18951898
GenTree* expr = stmt->GetRootNode();
18961899
if (expr->gtOper == GT_END_LFIN)
18971900
{
@@ -1900,6 +1903,16 @@ void Compiler::fgCleanupContinuation(BasicBlock* continuation)
19001903
foundEndLFin = true;
19011904
}
19021905
}
1906+
1907+
// If the continuation is unreachable, morph may
1908+
// have changed the continuation to an empty BBJ_THROW.
1909+
// Tolerate.
1910+
//
1911+
if (isEmpty && continuation->KindIs(BBJ_THROW))
1912+
{
1913+
return;
1914+
}
1915+
19031916
assert(foundEndLFin);
19041917
}
19051918
#endif // FEATURE_EH_WINDOWS_X86

src/coreclr/jit/morph.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9212,7 +9212,7 @@ GenTree* Compiler::fgOptimizeRelationalComparisonWithConst(GenTreeOp* cmp)
92129212
// LE_UN/GT_UN(expr, int.MaxValue) => EQ/NE(RSZ(expr, 32), 0).
92139213
else if (opts.OptimizationEnabled() && (op1->TypeIs(TYP_LONG) && (op2Value == UINT_MAX)))
92149214
{
9215-
oper = (oper == GT_GT) ? GT_NE : GT_EQ;
9215+
oper = (oper == GT_GT) ? GT_NE : GT_EQ;
92169216
GenTree* icon32 = gtNewIconNode(32, TYP_INT);
92179217
icon32->SetMorphed(this);
92189218

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Generated by Fuzzlyn v3.0 on 2025-05-18 16:32:05
2+
// Run on X86 Windows
3+
// Seed: 16064612445952557242-vectort,vector128,vector256,x86aes,x86avx,x86avx2,x86avx512bw,x86avx512bwvl,x86avx512cd,x86avx512cdvl,x86avx512dq,x86avx512dqvl,x86avx512f,x86avx512fvl,x86bmi1,x86bmi2,x86fma,x86lzcnt,x86pclmulqdq,x86popcnt,x86sse,x86sse2,x86sse3,x86sse41,x86sse42,x86ssse3,x86x86base
4+
// Reduced from 104.0 KiB to 0.7 KiB in 00:06:27
5+
// Hits JIT assert in Release:
6+
// Assertion failed 'foundEndLFin' in 'Program:Main(Fuzzlyn.ExecutionServer.IRuntime)' during 'Remove empty try 2' (IL size 82; hash 0xade6b36b; FullOpts)
7+
//
8+
// File: D:\a\_work\1\s\src\coreclr\jit\fgehopt.cpp Line: 1903
9+
//
10+
using System;
11+
using System.Runtime.CompilerServices;
12+
using Xunit;
13+
14+
public class C0
15+
{
16+
public bool F5;
17+
public uint F6;
18+
}
19+
20+
public class Program
21+
{
22+
public static C0 s_3;
23+
public static ushort s_13;
24+
25+
[Fact]
26+
public static void Test()
27+
{
28+
try
29+
{
30+
Problem();
31+
}
32+
catch (System.Exception)
33+
{
34+
}
35+
}
36+
37+
[MethodImpl(MethodImplOptions.NoInlining)]
38+
static void Problem()
39+
{
40+
C0 vr0 = new C0();
41+
try
42+
{
43+
vr0.F6 = 0;
44+
}
45+
finally
46+
{
47+
for (uint vr1 = 0; vr1 < 1; vr1++)
48+
{
49+
s_13 -= s_13;
50+
s_3.F5 |= false;
51+
vr0.F5 = vr0.F5 && false;
52+
throw new System.Exception();
53+
}
54+
}
55+
}
56+
}
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)