[llvm] [X86] Refuse machine outlining under Windows CFI (PR #225263)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 21 18:55:22 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-x86
Author: Demetrios Chiuratto Agourakis (agourakis82)
<details>
<summary>Changes</summary>
### Summary
The X86 machine outliner did not refuse functions that use Windows CFI. Outlining from WinEH/SEH-bearing code can corrupt `.seh_*` frame state around MSVC C++ EH funclets, producing assembler failures such as `.seh_startepilogue` before `.seh_endprologue` and stray `.seh_endepilogue` (#<!-- -->213862).
AArch64 already has an explicit fence:
```cpp
// FIXME: Teach the outliner to generate/handle Windows unwind info.
if (MF.getTarget().getMCAsmInfo().usesWindowsCFI())
return false;
```
This PR mirrors that fence in `X86InstrInfo::isFunctionSafeToOutlineFrom`.
### Why this shape
Teaching the outliner to correctly rewrite Windows unwind/funclet metadata is a much larger project. Until that exists, refusing to outline under `usesWindowsCFI()` is the correctness-preserving fix (same policy AArch64 already shipped).
### Test plan
- New: `llvm/test/CodeGen/X86/machine-outliner-windows-cfi.ll`
- Windows MSVC triple: no `OUTLINED_FUNCTION`
- Darwin triple: outlining still happens
Fixes #<!-- -->213862
---
Full diff: https://github.com/llvm/llvm-project/pull/225263.diff
2 Files Affected:
- (modified) llvm/lib/Target/X86/X86InstrInfo.cpp (+7)
- (added) llvm/test/CodeGen/X86/machine-outliner-windows-cfi.ll (+36)
``````````diff
diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp
index 09a8ae6107020..7032764eeddad 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.cpp
+++ b/llvm/lib/Target/X86/X86InstrInfo.cpp
@@ -10841,6 +10841,13 @@ bool X86InstrInfo::isFunctionSafeToOutlineFrom(
if (!OutlineFromLinkOnceODRs && F.hasLinkOnceODRLinkage())
return false;
+ // FIXME: Teach the outliner to generate/handle Windows unwind info.
+ // Without this fence, outlining from WinEH/SEH-bearing code can corrupt
+ // .seh_* frame state (llvm/llvm-project#213862). AArch64 already refuses
+ // outlining when usesWindowsCFI() is true.
+ if (MF.getTarget().getMCAsmInfo().usesWindowsCFI())
+ return false;
+
// This function is viable for outlining, so return true.
return true;
}
diff --git a/llvm/test/CodeGen/X86/machine-outliner-windows-cfi.ll b/llvm/test/CodeGen/X86/machine-outliner-windows-cfi.ll
new file mode 100644
index 0000000000000..5ca540daf2729
--- /dev/null
+++ b/llvm/test/CodeGen/X86/machine-outliner-windows-cfi.ll
@@ -0,0 +1,36 @@
+; RUN: llc -enable-machine-outliner -mtriple=x86_64-pc-windows-msvc < %s | FileCheck %s
+; RUN: llc -enable-machine-outliner -mtriple=x86_64-apple-darwin < %s | FileCheck %s --check-prefix=DARWIN
+
+; X86 previously outlined from Windows-CFI functions, which can corrupt .seh_*
+; frame state around WinEH/funclets (#213862). Mirror AArch64 and refuse
+; outlining when usesWindowsCFI() is true.
+
+define i32 @f1(i32 %a, i32 %b) nounwind {
+entry:
+ %a2 = mul i32 %a, %b
+ %a3 = add i32 %a2, %b
+ %a4 = mul i32 %a3, %a2
+ %a5 = add i32 %a4, %a3
+ ret i32 %a5
+}
+
+define i32 @f2(i32 %a, i32 %b) nounwind {
+entry:
+ %a2 = mul i32 %a, %b
+ %a3 = add i32 %a2, %b
+ %a4 = mul i32 %a3, %a2
+ %a5 = add i32 %a4, %a3
+ ret i32 %a5
+}
+
+; CHECK-LABEL: f1:
+; CHECK-NOT: OUTLINED_FUNCTION
+; CHECK: imull
+; CHECK-LABEL: f2:
+; CHECK-NOT: OUTLINED_FUNCTION
+; CHECK: imull
+
+; DARWIN-LABEL: _f1:
+; DARWIN: OUTLINED_FUNCTION
+; DARWIN-LABEL: _f2:
+; DARWIN: OUTLINED_FUNCTION
``````````
</details>
https://github.com/llvm/llvm-project/pull/225263
More information about the llvm-commits
mailing list