From 51821afc67cfc34180e5c0c429627d4103b6db00 Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Wed, 1 Jul 2026 11:25:19 +0200 Subject: [PATCH 1/5] JIT: Disallow splitting prologs while generating unwind --- src/coreclr/jit/emit.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index d80cba4cb00e6c..d1e5314d0a7bde 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -1705,8 +1705,9 @@ void* emitter::emitAllocAnyInstr(size_t sz, emitAttr opsz) { #ifdef DEBUG // Under STRESS_EMITTER, put every instruction in its own instruction group. + // We do not support splitting the prolog while we are still generating unwind info. if (m_compiler->compStressCompile(Compiler::STRESS_EMITTER, 1) && (emitCurIGinsCnt != 0) && - !emitCurIG->endsWithAlignInstr()) + !emitCurIG->endsWithAlignInstr() && !m_compiler->compGeneratingUnwindProlog) { emitNxtIG(true); } From 5a11f0938016388913b02e292a0bbef7b2c0a6c2 Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Wed, 1 Jul 2026 11:34:56 +0200 Subject: [PATCH 2/5] Add assert --- src/coreclr/jit/emit.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index d1e5314d0a7bde..4a71e37bb47705 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -9995,6 +9995,11 @@ void emitter::emitNxtIG(bool extend) emitInitByrefRegs = emitThisByrefRegs; } + // We cannot start a new IG while we are still generating unwind info. + // It would result in creating a new fragment, and all fragments are + // expected to be unwindable by executing all unwind codes. + assert(!m_compiler->compGeneratingUnwindProlog); + /* Start generating the new group */ emitNewIG(); From e810fae5bd2a7c6e0bbed22d90851692b2409020 Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Wed, 1 Jul 2026 11:39:20 +0200 Subject: [PATCH 3/5] Less misleading comment --- src/coreclr/jit/emit.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index 4a71e37bb47705..5e5cd625c26cff 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -9995,9 +9995,9 @@ void emitter::emitNxtIG(bool extend) emitInitByrefRegs = emitThisByrefRegs; } - // We cannot start a new IG while we are still generating unwind info. - // It would result in creating a new fragment, and all fragments are - // expected to be unwindable by executing all unwind codes. + // Disallow starting a new IG while we are still generating unwind info, + // as that could allow our stress fragment splitting to split the prolog + // which is not supported. assert(!m_compiler->compGeneratingUnwindProlog); /* Start generating the new group */ From f025153249b5970d534b34e515857a23708eba4b Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Wed, 1 Jul 2026 11:43:44 +0200 Subject: [PATCH 4/5] Fix inside emitSplit instead --- src/coreclr/jit/emit.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index 5e5cd625c26cff..19e718a2271c33 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -1705,9 +1705,8 @@ void* emitter::emitAllocAnyInstr(size_t sz, emitAttr opsz) { #ifdef DEBUG // Under STRESS_EMITTER, put every instruction in its own instruction group. - // We do not support splitting the prolog while we are still generating unwind info. if (m_compiler->compStressCompile(Compiler::STRESS_EMITTER, 1) && (emitCurIGinsCnt != 0) && - !emitCurIG->endsWithAlignInstr() && !m_compiler->compGeneratingUnwindProlog) + !emitCurIG->endsWithAlignInstr()) { emitNxtIG(true); } @@ -3107,7 +3106,8 @@ void emitter::emitSplit(emitLocation* startLoc, // IGs are marked as prolog or epilog. We don't actually know if two adjacent // IGs are part of the *same* prolog or epilog, so we have to assume they are. - if (igPrev && (((igPrev->igFlags & IGF_FUNCLET_PROLOG) && (ig->igFlags & IGF_FUNCLET_PROLOG)) || + if (igPrev && (((igPrev->igFlags & IGF_PROLOG) && (ig->igFlags & IGF_PROLOG)) || + ((igPrev->igFlags & IGF_FUNCLET_PROLOG) && (ig->igFlags & IGF_FUNCLET_PROLOG)) || ((igPrev->igFlags & IGF_EPILOG) && (ig->igFlags & IGF_EPILOG)))) { // We can't update the candidate @@ -9995,11 +9995,6 @@ void emitter::emitNxtIG(bool extend) emitInitByrefRegs = emitThisByrefRegs; } - // Disallow starting a new IG while we are still generating unwind info, - // as that could allow our stress fragment splitting to split the prolog - // which is not supported. - assert(!m_compiler->compGeneratingUnwindProlog); - /* Start generating the new group */ emitNewIG(); From 7435887177286d903aeb039ed3f3a68d5ecfff75 Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Wed, 1 Jul 2026 12:00:29 +0200 Subject: [PATCH 5/5] Copilot feedback --- src/coreclr/jit/emit.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index 19e718a2271c33..e8d89a8d6d5365 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -3107,8 +3107,9 @@ void emitter::emitSplit(emitLocation* startLoc, // IGs are part of the *same* prolog or epilog, so we have to assume they are. if (igPrev && (((igPrev->igFlags & IGF_PROLOG) && (ig->igFlags & IGF_PROLOG)) || + ((igPrev->igFlags & IGF_EPILOG) && (ig->igFlags & IGF_EPILOG)) || ((igPrev->igFlags & IGF_FUNCLET_PROLOG) && (ig->igFlags & IGF_FUNCLET_PROLOG)) || - ((igPrev->igFlags & IGF_EPILOG) && (ig->igFlags & IGF_EPILOG)))) + ((igPrev->igFlags & IGF_FUNCLET_EPILOG) && (ig->igFlags & IGF_FUNCLET_EPILOG)))) { // We can't update the candidate }