[clang] [llvm] [ARM] Add support for Windows SEH (PR #184953)
Trung Nguyen via cfe-commits
cfe-commits at lists.llvm.org
Tue Apr 7 04:11:01 PDT 2026
================
@@ -0,0 +1,57 @@
+; RUN: llc -mtriple thumbv7-windows-msvc -o - %s
+; XFAIL: *
+
+; FIXME: C++ EH is not supported on thumbv7-windows-msvc yet.
+
+; FIXME: Windows SEH for armv7 does not preserve the frame register R11 in
+; handlers. This may affect C++ EH when accessing arguments on the stack in
+; functions with stack realignment.
+
+; C++ source:
+; struct X { int x[100]; };
+; void f(X x, void (*a)(), void (*g)(int*)) {
+; alignas(64) int aligned;
+; try {
+; a();
+; } catch (...) {
+; g(&x.x[11]);
+; }
+; }
+
+%struct.X = type { [100 x i32] }
+
+define void @"?f@@YAXUX@@P6AXXZP6AXPAH at Z@Z"(ptr byval(%struct.X) align 4 %x, ptr %a, ptr %g) personality ptr @__CxxFrameHandler3 {
----------------
trungnt2910 wrote:
Thanks for the suggestion. Your idea works, but it fundamentally changes how the variables are accessed.
This is a link of trying to do the same for AArch64: https://godbolt.org/z/nv1a8GYdx
x86_64 shows a similar behavior: https://godbolt.org/z/KvWj88drf
When forcibly changing the personality function to `__C_specific_handler`, the code treats the exception handling block as being in the same scope as the parent function. The stack variable will be accessed from a non-reserved, non-volatile general purpose register, potentially set up by the parent. In the linked example, the register is AArch64 `x19`. When I tried my fork, the register for ARM was `r4`.
```
.LBB0_2: // %catch
ldr x8, [x29, #32]
add x0, x19, #44
blr x8
b .LBB0_1
```
Meanwhile, the `__CxxFrameHandler3` version is split into a separate function. The variable is accessed differently by offsetting `x29` to gradually recover the original offset.
```
"?catch$2@?0??f@@YAXUX@@P6AXXZP6AXPAH at Z@Z at 4HA":
.LBB0_2: // %catch
stp x29, x30, [sp, #-16]! // 16-byte Folded Spill
ldur x8, [x29, #-8]
add x9, x29, #32
add x0, x9, #44
blr x8
adrp x0, .LBB0_1
add x0, x0, .LBB0_1
ldp x29, x30, [sp], #16 // 16-byte Folded Reload
ret
```
I don't know how this will be beneficial to future C++ EH attempts, and how it demonstrates the shortcomings of forcing R6.
https://github.com/llvm/llvm-project/pull/184953
More information about the cfe-commits
mailing list