diff --git a/src/coreclr/jit/ifconversion.cpp b/src/coreclr/jit/ifconversion.cpp index 836643225d0b3f..53b1c0a25fc9f0 100644 --- a/src/coreclr/jit/ifconversion.cpp +++ b/src/coreclr/jit/ifconversion.cpp @@ -130,9 +130,22 @@ bool OptIfConversionDsc::IfConvertCheckFlow() return false; } + // The Then/Else blocks will be removed by if-conversion, so they must be in the same + // EH region as m_startBlock. Otherwise they may be the start of a try/handler region + // (and thus marked BBF_DONT_REMOVE), or removing them could leave dangling EH state. + if (!BasicBlock::sameEHRegion(falseBb, m_startBlock)) + { + return false; + } + m_doElseConversion = trueBb->GetUniquePred(m_compiler) != nullptr; m_finalBlock = m_doElseConversion ? trueBb->GetUniqueSucc() : trueBb; + if (m_doElseConversion && !BasicBlock::sameEHRegion(trueBb, m_startBlock)) + { + return false; + } + // m_finalBlock is only allowed to be null if both return. // E.g: Then block exits by throwing an exception => we bail here. if (m_finalBlock == nullptr && (!falseBb->KindIs(BBJ_RETURN) || !trueBb->KindIs(BBJ_RETURN))) diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_127446/Runtime_127446.cs b/src/tests/JIT/Regression/JitBlue/Runtime_127446/Runtime_127446.cs new file mode 100644 index 00000000000000..91104c1842847e --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_127446/Runtime_127446.cs @@ -0,0 +1,53 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Runtime_127446; + +using System; +using Xunit; + +public class Runtime_127446 +{ + // Regression test: the JIT's if-conversion phase used to assert when the + // "Then" block was the start of an EH region (and therefore marked + // BBF_DONT_REMOVE). Compilation should succeed without hitting the assert. + [Fact] + public static void TestEntryPoint() + { + try + { + M0(); + } + catch (NullReferenceException) + { + } + catch (DivideByZeroException) + { + } + } + + private static void M0() + { + int var1 = default(int); + bool[,] var4 = default(bool[,]); + if (var4[0, 0]) + { + try + { + var1 = 0; + } + catch (System.Exception) + { + try + { + var4[0, 0] = var4[0, 0]; + } + catch (System.Exception) + { + } + } + } + + var1 = (0 / var1); + } +} diff --git a/src/tests/JIT/Regression/Regression_o_3.csproj b/src/tests/JIT/Regression/Regression_o_3.csproj index 7628c13e375137..cdf1e59f474edd 100644 --- a/src/tests/JIT/Regression/Regression_o_3.csproj +++ b/src/tests/JIT/Regression/Regression_o_3.csproj @@ -150,6 +150,7 @@ +