[llvm-branch-commits] [llvm] [AArch64] Apply the Windows SEH and CRT codegen constraints to UEFI (PR #232704)

Prabhu Rajasekaran via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Oct 16 04:57:06 PDT 2026


https://github.com/Prabhuk created https://github.com/llvm/llvm-project/pull/232704

aarch64-unknown-uefi uses SEH unwind information and has no C runtime
library, so the remaining Windows specific codegen decisions that follow
from this apply to it too:

* do not align loops or basic blocks, since SEH unwind info generation
  needs the exact function layout before alignment padding is inserted,
* sign return addresses with the B key by default and reject A key
  signing, matching the pac_sign_lr unwind code used by the unwinder,
* do not lower wide shifts to libcalls at -Oz, as those helpers are not
  available.

The corresponding Windows tests gain aarch64-unknown-uefi run lines and
the LLVM release notes announce the new target, which completes the
backend side of aarch64-unknown-uefi support.

Assisted-by: Claude

---

<sub>Stack created with <a href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub>

>From 85fcdc31e9b8733b85f2ab9c85704cb91667aa50 Mon Sep 17 00:00:00 2001
From: prabhukr <prabhukr at google.com>
Date: Fri, 16 Oct 2026 04:49:24 -0700
Subject: [PATCH] [AArch64] Apply the Windows SEH and CRT codegen constraints
 to UEFI

aarch64-unknown-uefi uses SEH unwind information and has no C runtime
library, so the remaining Windows specific codegen decisions that follow
from this apply to it too:

* do not align loops or basic blocks, since SEH unwind info generation
  needs the exact function layout before alignment padding is inserted,
* sign return addresses with the B key by default and reject A key
  signing, matching the pac_sign_lr unwind code used by the unwinder,
* do not lower wide shifts to libcalls at -Oz, as those helpers are not
  available.

The corresponding Windows tests gain aarch64-unknown-uefi run lines and
the LLVM release notes announce the new target, which completes the
backend side of aarch64-unknown-uefi support.

Assisted-by: Claude
---
 llvm/docs/ReleaseNotes.md                              |  4 ++++
 llvm/lib/Target/AArch64/AArch64CodeLayoutOpt.cpp       |  2 +-
 llvm/lib/Target/AArch64/AArch64ISelLowering.cpp        | 10 +++++-----
 llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp |  4 ++--
 llvm/test/CodeGen/AArch64/windows-pac-invalid-a-key.ll |  1 +
 llvm/test/CodeGen/AArch64/windows-trap.ll              |  1 +
 llvm/test/CodeGen/AArch64/wineh-pac.ll                 |  1 +
 7 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 302aa57396105e..0b41fd223d3030 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -271,6 +271,10 @@ Makes programs 10x faster by doing Special New Thing.
 * Assembler/disassembler support has been added for Armv9.8-A (2026)
   architecture extensions.
 
+* Added support for the `aarch64-unknown-uefi` target. It follows the Windows
+  ARM64 ABI (calling convention, callee saved registers, stack probing and SEH
+  unwind information) and produces PE/COFF objects.
+
 ### Changes to the AMDGPU Backend
 
 * Replaced `xnack` and `sramecc` target features with `amdgpu.xnack`
diff --git a/llvm/lib/Target/AArch64/AArch64CodeLayoutOpt.cpp b/llvm/lib/Target/AArch64/AArch64CodeLayoutOpt.cpp
index 73e641da816063..cdbdd0994e77f2 100644
--- a/llvm/lib/Target/AArch64/AArch64CodeLayoutOpt.cpp
+++ b/llvm/lib/Target/AArch64/AArch64CodeLayoutOpt.cpp
@@ -163,7 +163,7 @@ bool AArch64CodeLayoutOpt::runOnMachineFunction(MachineFunction &MF) {
   const auto *Subtarget = &MF.getSubtarget<AArch64Subtarget>();
 
   // Aligning basic blocks currently isn't compatible with Windows unwind info.
-  if (Subtarget->isTargetWindows())
+  if (Subtarget->isTargetWindowsOrUEFI())
     return false;
 
   TII = Subtarget->getInstrInfo();
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 6d6cd21f25be20..8a2677f647aec0 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -1171,10 +1171,10 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
   setMinFunctionAlignment(Align(4));
   // Set preferred alignments.
 
-  // Don't align loops on Windows. The SEH unwind info generation needs to
-  // know the exact length of functions before the alignments have been
-  // expanded.
-  if (!Subtarget->isTargetWindows())
+  // Don't align loops on Windows and UEFI. The SEH unwind info generation
+  // needs to know the exact length of functions before the alignments have
+  // been expanded.
+  if (!Subtarget->isTargetWindowsOrUEFI())
     setPrefLoopAlignment(STI.getPrefLoopAlignment());
   setMaxBytesForAlignment(STI.getMaxBytesForLoopAlignment());
   setPrefFunctionAlignment(STI.getPrefFunctionAlignment());
@@ -33850,7 +33850,7 @@ TargetLowering::ShiftLegalizationStrategy
 AArch64TargetLowering::preferredShiftLegalizationStrategy(
     SelectionDAG &DAG, SDNode *N, unsigned int ExpansionFactor) const {
   if (DAG.getMachineFunction().getFunction().hasMinSize() &&
-      !Subtarget->isTargetWindows() && !Subtarget->isTargetDarwin())
+      !Subtarget->isTargetWindowsOrUEFI() && !Subtarget->isTargetDarwin())
     return ShiftLegalizationStrategy::LowerToLibcall;
   return TargetLowering::preferredShiftLegalizationStrategy(DAG, N,
                                                             ExpansionFactor);
diff --git a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp
index 07a9230b63dc97..7129e332585fa8 100644
--- a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp
@@ -86,7 +86,7 @@ static bool ShouldSignWithBKey(const Function &F, const AArch64Subtarget &STI) {
   if (F.hasFnAttribute("ptrauth-returns"))
     return true;
   if (!F.hasFnAttribute("sign-return-address-key")) {
-    if (STI.getTargetTriple().isOSWindows())
+    if (STI.getTargetTriple().isOSWindowsOrUEFI())
       return true;
     return false;
   }
@@ -94,7 +94,7 @@ static bool ShouldSignWithBKey(const Function &F, const AArch64Subtarget &STI) {
   const StringRef Key =
       F.getFnAttribute("sign-return-address-key").getValueAsString();
   assert(Key == "a_key" || Key == "b_key");
-  if (STI.getTargetTriple().isOSWindows() && Key == "a_key" &&
+  if (STI.getTargetTriple().isOSWindowsOrUEFI() && Key == "a_key" &&
       GetSignReturnAddress(F) != SignReturnAddress::None) {
     F.getContext().diagnose(DiagnosticInfoUnsupported{
         F, "A-key return address signing is unsupported on AArch64 Windows"});
diff --git a/llvm/test/CodeGen/AArch64/windows-pac-invalid-a-key.ll b/llvm/test/CodeGen/AArch64/windows-pac-invalid-a-key.ll
index 7203e10e4b2003..5b8ab7fdf6b15a 100644
--- a/llvm/test/CodeGen/AArch64/windows-pac-invalid-a-key.ll
+++ b/llvm/test/CodeGen/AArch64/windows-pac-invalid-a-key.ll
@@ -1,4 +1,5 @@
 ; RUN: not llc -mtriple=aarch64-windows-msvc -filetype=null %s 2>&1 | FileCheck %s
+; RUN: not llc -mtriple=aarch64-unknown-uefi -filetype=null %s 2>&1 | FileCheck %s
 
 ; CHECK: error:
 ; CHECK-SAME: A-key return address signing is unsupported on AArch64 Windows
diff --git a/llvm/test/CodeGen/AArch64/windows-trap.ll b/llvm/test/CodeGen/AArch64/windows-trap.ll
index 5cf0ece48e97d1..9165fb0d2e7cdb 100644
--- a/llvm/test/CodeGen/AArch64/windows-trap.ll
+++ b/llvm/test/CodeGen/AArch64/windows-trap.ll
@@ -1,4 +1,5 @@
 ; RUN: llc -mtriple=aarch64-win32 %s -o - | FileCheck %s
+; RUN: llc -mtriple=aarch64-unknown-uefi %s -o - | FileCheck %s
 
 declare void @callee() noreturn
 
diff --git a/llvm/test/CodeGen/AArch64/wineh-pac.ll b/llvm/test/CodeGen/AArch64/wineh-pac.ll
index 71dcaa3b826512..13075447eeef41 100644
--- a/llvm/test/CodeGen/AArch64/wineh-pac.ll
+++ b/llvm/test/CodeGen/AArch64/wineh-pac.ll
@@ -1,5 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
 ; RUN: llc < %s -mtriple=aarch64-windows | FileCheck %s
+; RUN: llc < %s -mtriple=aarch64-unknown-uefi | FileCheck %s
 
 define dso_local i32 @func(ptr %g, i32 %a) "sign-return-address"="non-leaf" "sign-return-address-key"="b_key" {
 ; CHECK-LABEL: func:



More information about the llvm-branch-commits mailing list