[llvm] [aarch64] XOR the frame pointer with the stack cookie when protecting the stack (PR #161114)

Pan Tao via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 18 07:18:29 PST 2025


https://github.com/PanTao2 updated https://github.com/llvm/llvm-project/pull/161114

>From c27d13d6e4836fcfac7e79ceb8b2563b5a13779d Mon Sep 17 00:00:00 2001
From: "Pan, Tao" <tao.pan at intel.com>
Date: Mon, 29 Sep 2025 09:43:17 +0800
Subject: [PATCH 01/11] [aarch64] XOR the frame pointer with the stack cookie
 when protecting the stack

---
 llvm/lib/Target/AArch64/AArch64ISelLowering.cpp     | 12 +++++++++++-
 llvm/lib/Target/AArch64/AArch64ISelLowering.h       |  3 +++
 llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp |  2 +-
 3 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index d21e19b2ecd46..59b41ab5ea442 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -29239,7 +29239,17 @@ void AArch64TargetLowering::ReplaceNodeResults(
 bool AArch64TargetLowering::useLoadStackGuardNode(const Module &M) const {
   if (Subtarget->isTargetAndroid() || Subtarget->isTargetFuchsia())
     return TargetLowering::useLoadStackGuardNode(M);
-  return true;
+  return false;
+}
+
+bool AArch64TargetLowering::useStackGuardXorFP() const { return true; }
+
+SDValue AArch64TargetLowering::emitStackGuardXorFP(SelectionDAG &DAG,
+                                                   SDValue Val,
+                                                   const SDLoc &DL) const {
+  return DAG.getNode(
+      ISD::XOR, DL, Val.getValueType(), Val,
+      DAG.getRegister(getStackPointerRegisterToSaveRestore(), MVT::i64));
 }
 
 unsigned AArch64TargetLowering::combineRepeatedFPDivisors() const {
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
index be198e54cbcbf..7e5a275a397a8 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
@@ -363,6 +363,9 @@ class AArch64TargetLowering : public TargetLowering {
   shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const override;
 
   bool useLoadStackGuardNode(const Module &M) const override;
+  bool useStackGuardXorFP() const override;
+  SDValue emitStackGuardXorFP(SelectionDAG &DAG, SDValue Val,
+                              const SDLoc &DL) const override;
   TargetLoweringBase::LegalizeTypeAction
   getPreferredVectorAction(MVT VT) const override;
 
diff --git a/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp b/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp
index 48e03ad853d26..2c75637505b0f 100644
--- a/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp
@@ -38,7 +38,7 @@ void AArch64SelectionDAGInfo::verifyTargetNode(const SelectionDAG &DAG,
     return;
   }
 
-  SelectionDAGGenTargetInfo::verifyTargetNode(DAG, N);
+  //  SelectionDAGGenTargetInfo::verifyTargetNode(DAG, N);
 
 #ifndef NDEBUG
   // Some additional checks not yet implemented by verifyTargetNode.

>From 6536678731bd9e9c1e0c0c78285e1b91aed646b4 Mon Sep 17 00:00:00 2001
From: "Pan, Tao" <tao.pan at intel.com>
Date: Mon, 29 Sep 2025 15:21:25 +0800
Subject: [PATCH 02/11] Change DAG.getRegister to DAG.getCopyFromReg

---
 llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 59b41ab5ea442..7707a5d7d02f7 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -29247,9 +29247,10 @@ bool AArch64TargetLowering::useStackGuardXorFP() const { return true; }
 SDValue AArch64TargetLowering::emitStackGuardXorFP(SelectionDAG &DAG,
                                                    SDValue Val,
                                                    const SDLoc &DL) const {
-  return DAG.getNode(
-      ISD::XOR, DL, Val.getValueType(), Val,
-      DAG.getRegister(getStackPointerRegisterToSaveRestore(), MVT::i64));
+  return DAG.getNode(ISD::XOR, DL, Val.getValueType(), Val,
+                     DAG.getCopyFromReg(DAG.getEntryNode(), DL,
+                                        getStackPointerRegisterToSaveRestore(),
+                                        MVT::i64));
 }
 
 unsigned AArch64TargetLowering::combineRepeatedFPDivisors() const {

>From 4493e860c4526eca97ba8979d9b179051a0451cc Mon Sep 17 00:00:00 2001
From: "Pan, Tao" <tao.pan at intel.com>
Date: Fri, 10 Oct 2025 08:58:21 +0800
Subject: [PATCH 03/11] Fix failed tests

---
 .../Target/AArch64/AArch64ISelLowering.cpp    |  11 +-
 llvm/test/CodeGen/AArch64/mingw-refptr.ll     | 101 +++++++++++++++---
 .../CodeGen/AArch64/stack-protector-target.ll |  12 +--
 3 files changed, 103 insertions(+), 21 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 7707a5d7d02f7..f04672a7396c5 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -29239,10 +29239,17 @@ void AArch64TargetLowering::ReplaceNodeResults(
 bool AArch64TargetLowering::useLoadStackGuardNode(const Module &M) const {
   if (Subtarget->isTargetAndroid() || Subtarget->isTargetFuchsia())
     return TargetLowering::useLoadStackGuardNode(M);
-  return false;
+  return !Subtarget->getTargetTriple().isOSMSVCRT() ||
+         Subtarget->isTargetMachO() ||
+         getTargetMachine().Options.EnableGlobalISel;
 }
 
-bool AArch64TargetLowering::useStackGuardXorFP() const { return true; }
+bool AArch64TargetLowering::useStackGuardXorFP() const {
+  // Currently only MSVC CRTs XOR the frame pointer into the stack guard value.
+  return Subtarget->getTargetTriple().isOSMSVCRT() &&
+         !Subtarget->isTargetMachO() &&
+         !getTargetMachine().Options.EnableGlobalISel;
+}
 
 SDValue AArch64TargetLowering::emitStackGuardXorFP(SelectionDAG &DAG,
                                                    SDValue Val,
diff --git a/llvm/test/CodeGen/AArch64/mingw-refptr.ll b/llvm/test/CodeGen/AArch64/mingw-refptr.ll
index 02c81440dd753..4a203d74876a7 100644
--- a/llvm/test/CodeGen/AArch64/mingw-refptr.ll
+++ b/llvm/test/CodeGen/AArch64/mingw-refptr.ll
@@ -1,6 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
 ; RUN: llc < %s -mtriple=aarch64-w64-mingw32 | FileCheck %s --check-prefixes=CHECK,CHECK-SD
-; RUN: llc < %s -mtriple=aarch64-w64-mingw32 -global-isel | FileCheck %s --check-prefixes=CHECK,CHECK-GI
+; RUN: llc < %s -mtriple=aarch64-w64-mingw32 -global-isel | FileCheck %s --check-prefixes=CHECK-GI
 
 @var = external local_unnamed_addr global i32, align 4
 @dsolocalvar = external dso_local local_unnamed_addr global i32, align 4
@@ -15,6 +15,13 @@ define dso_local i32 @getVar() {
 ; CHECK-NEXT:    ldr x8, [x8, :lo12:.refptr.var]
 ; CHECK-NEXT:    ldr w0, [x8]
 ; CHECK-NEXT:    ret
+;
+; CHECK-GI-LABEL: getVar:
+; CHECK-GI:       // %bb.0: // %entry
+; CHECK-GI-NEXT:    adrp x8, .refptr.var
+; CHECK-GI-NEXT:    ldr x8, [x8, :lo12:.refptr.var]
+; CHECK-GI-NEXT:    ldr w0, [x8]
+; CHECK-GI-NEXT:    ret
 entry:
   %0 = load i32, ptr @var, align 4
   ret i32 %0
@@ -26,6 +33,12 @@ define dso_local i32 @getDsoLocalVar() {
 ; CHECK-NEXT:    adrp x8, dsolocalvar
 ; CHECK-NEXT:    ldr w0, [x8, :lo12:dsolocalvar]
 ; CHECK-NEXT:    ret
+;
+; CHECK-GI-LABEL: getDsoLocalVar:
+; CHECK-GI:       // %bb.0: // %entry
+; CHECK-GI-NEXT:    adrp x8, dsolocalvar
+; CHECK-GI-NEXT:    ldr w0, [x8, :lo12:dsolocalvar]
+; CHECK-GI-NEXT:    ret
 entry:
   %0 = load i32, ptr @dsolocalvar, align 4
   ret i32 %0
@@ -37,6 +50,12 @@ define dso_local i32 @getLocalVar() {
 ; CHECK-NEXT:    adrp x8, localvar
 ; CHECK-NEXT:    ldr w0, [x8, :lo12:localvar]
 ; CHECK-NEXT:    ret
+;
+; CHECK-GI-LABEL: getLocalVar:
+; CHECK-GI:       // %bb.0: // %entry
+; CHECK-GI-NEXT:    adrp x8, localvar
+; CHECK-GI-NEXT:    ldr w0, [x8, :lo12:localvar]
+; CHECK-GI-NEXT:    ret
 entry:
   %0 = load i32, ptr @localvar, align 4
   ret i32 %0
@@ -48,6 +67,12 @@ define dso_local i32 @getLocalCommon() {
 ; CHECK-NEXT:    adrp x8, localcommon
 ; CHECK-NEXT:    ldr w0, [x8, :lo12:localcommon]
 ; CHECK-NEXT:    ret
+;
+; CHECK-GI-LABEL: getLocalCommon:
+; CHECK-GI:       // %bb.0: // %entry
+; CHECK-GI-NEXT:    adrp x8, localcommon
+; CHECK-GI-NEXT:    ldr w0, [x8, :lo12:localcommon]
+; CHECK-GI-NEXT:    ret
 entry:
   %0 = load i32, ptr @localcommon, align 4
   ret i32 %0
@@ -60,6 +85,13 @@ define dso_local i32 @getExtVar() {
 ; CHECK-NEXT:    ldr x8, [x8, :lo12:__imp_extvar]
 ; CHECK-NEXT:    ldr w0, [x8]
 ; CHECK-NEXT:    ret
+;
+; CHECK-GI-LABEL: getExtVar:
+; CHECK-GI:       // %bb.0: // %entry
+; CHECK-GI-NEXT:    adrp x8, __imp_extvar
+; CHECK-GI-NEXT:    ldr x8, [x8, :lo12:__imp_extvar]
+; CHECK-GI-NEXT:    ldr w0, [x8]
+; CHECK-GI-NEXT:    ret
 entry:
   %0 = load i32, ptr @extvar, align 4
   ret i32 %0
@@ -69,6 +101,10 @@ define dso_local void @callFunc() {
 ; CHECK-LABEL: callFunc:
 ; CHECK:       // %bb.0: // %entry
 ; CHECK-NEXT:    b otherFunc
+;
+; CHECK-GI-LABEL: callFunc:
+; CHECK-GI:       // %bb.0: // %entry
+; CHECK-GI-NEXT:    b otherFunc
 entry:
   tail call void @otherFunc()
   ret void
@@ -82,25 +118,31 @@ define dso_local void @sspFunc() #0 {
 ; CHECK-NEXT:  // %bb.0: // %entry
 ; CHECK-NEXT:    sub sp, sp, #32
 ; CHECK-NEXT:    .seh_stackalloc 32
-; CHECK-NEXT:    str x30, [sp, #16] // 8-byte Spill
-; CHECK-NEXT:    .seh_save_reg x30, 16
+; CHECK-NEXT:    str x19, [sp, #16] // 8-byte Spill
+; CHECK-NEXT:    .seh_save_reg x19, 16
+; CHECK-NEXT:    str x30, [sp, #24] // 8-byte Spill
+; CHECK-NEXT:    .seh_save_reg x30, 24
 ; CHECK-NEXT:    .seh_endprologue
-; CHECK-NEXT:    adrp x8, .refptr.__stack_chk_guard
+; CHECK-NEXT:    adrp x19, .refptr.__stack_chk_guard
+; CHECK-NEXT:    mov x9, sp
 ; CHECK-NEXT:    add x0, sp, #7
-; CHECK-NEXT:    ldr x8, [x8, :lo12:.refptr.__stack_chk_guard]
-; CHECK-NEXT:    ldr x8, [x8]
+; CHECK-NEXT:    ldr x19, [x19, :lo12:.refptr.__stack_chk_guard]
+; CHECK-NEXT:    ldr x8, [x19]
+; CHECK-NEXT:    eor x8, x8, x9
 ; CHECK-NEXT:    str x8, [sp, #8]
 ; CHECK-NEXT:    bl ptrUser
-; CHECK-NEXT:    adrp x8, .refptr.__stack_chk_guard
-; CHECK-NEXT:    ldr x8, [x8, :lo12:.refptr.__stack_chk_guard]
 ; CHECK-NEXT:    ldr x9, [sp, #8]
-; CHECK-NEXT:    ldr x8, [x8]
-; CHECK-NEXT:    cmp x8, x9
+; CHECK-NEXT:    mov x8, sp
+; CHECK-NEXT:    ldr x10, [x19]
+; CHECK-NEXT:    eor x8, x9, x8
+; CHECK-NEXT:    cmp x10, x8
 ; CHECK-NEXT:    b.ne .LBB6_2
 ; CHECK-NEXT:  // %bb.1: // %entry
 ; CHECK-NEXT:    .seh_startepilogue
-; CHECK-NEXT:    ldr x30, [sp, #16] // 8-byte Reload
-; CHECK-NEXT:    .seh_save_reg x30, 16
+; CHECK-NEXT:    ldr x30, [sp, #24] // 8-byte Reload
+; CHECK-NEXT:    .seh_save_reg x30, 24
+; CHECK-NEXT:    ldr x19, [sp, #16] // 8-byte Reload
+; CHECK-NEXT:    .seh_save_reg x19, 16
 ; CHECK-NEXT:    add sp, sp, #32
 ; CHECK-NEXT:    .seh_stackalloc 32
 ; CHECK-NEXT:    .seh_endepilogue
@@ -110,6 +152,40 @@ define dso_local void @sspFunc() #0 {
 ; CHECK-NEXT:    brk #0x1
 ; CHECK-NEXT:    .seh_endfunclet
 ; CHECK-NEXT:    .seh_endproc
+;
+; CHECK-GI-LABEL: sspFunc:
+; CHECK-GI:       .seh_proc sspFunc
+; CHECK-GI-NEXT:  // %bb.0: // %entry
+; CHECK-GI-NEXT:    sub sp, sp, #32
+; CHECK-GI-NEXT:    .seh_stackalloc 32
+; CHECK-GI-NEXT:    str x30, [sp, #16] // 8-byte Spill
+; CHECK-GI-NEXT:    .seh_save_reg x30, 16
+; CHECK-GI-NEXT:    .seh_endprologue
+; CHECK-GI-NEXT:    adrp x8, .refptr.__stack_chk_guard
+; CHECK-GI-NEXT:    add x0, sp, #7
+; CHECK-GI-NEXT:    ldr x8, [x8, :lo12:.refptr.__stack_chk_guard]
+; CHECK-GI-NEXT:    ldr x8, [x8]
+; CHECK-GI-NEXT:    str x8, [sp, #8]
+; CHECK-GI-NEXT:    bl ptrUser
+; CHECK-GI-NEXT:    adrp x8, .refptr.__stack_chk_guard
+; CHECK-GI-NEXT:    ldr x8, [x8, :lo12:.refptr.__stack_chk_guard]
+; CHECK-GI-NEXT:    ldr x9, [sp, #8]
+; CHECK-GI-NEXT:    ldr x8, [x8]
+; CHECK-GI-NEXT:    cmp x8, x9
+; CHECK-GI-NEXT:    b.ne .LBB6_2
+; CHECK-GI-NEXT:  // %bb.1: // %entry
+; CHECK-GI-NEXT:    .seh_startepilogue
+; CHECK-GI-NEXT:    ldr x30, [sp, #16] // 8-byte Reload
+; CHECK-GI-NEXT:    .seh_save_reg x30, 16
+; CHECK-GI-NEXT:    add sp, sp, #32
+; CHECK-GI-NEXT:    .seh_stackalloc 32
+; CHECK-GI-NEXT:    .seh_endepilogue
+; CHECK-GI-NEXT:    ret
+; CHECK-GI-NEXT:  .LBB6_2: // %entry
+; CHECK-GI-NEXT:    bl __stack_chk_fail
+; CHECK-GI-NEXT:    brk #0x1
+; CHECK-GI-NEXT:    .seh_endfunclet
+; CHECK-GI-NEXT:    .seh_endproc
 entry:
   %c = alloca i8, align 1
   call void @llvm.lifetime.start.p0(i64 1, ptr nonnull %c)
@@ -134,5 +210,4 @@ attributes #0 = { sspstrong }
 ; CHECK:        .xword  var
 
 ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
-; CHECK-GI: {{.*}}
 ; CHECK-SD: {{.*}}
diff --git a/llvm/test/CodeGen/AArch64/stack-protector-target.ll b/llvm/test/CodeGen/AArch64/stack-protector-target.ll
index b1ddd1d0d160f..9940a4d75d09b 100644
--- a/llvm/test/CodeGen/AArch64/stack-protector-target.ll
+++ b/llvm/test/CodeGen/AArch64/stack-protector-target.ll
@@ -29,16 +29,16 @@ declare void @_Z7CapturePi(ptr)
 ; FUCHSIA-AARCH64-COMMON: ldr [[D:.*]], [sp,
 ; FUCHSIA-AARCH64-COMMON: cmp [[C]], [[D]]
 
-; WINDOWS-AARCH64: adrp x8, __security_cookie
-; WINDOWS-AARCH64: ldr x8, [x8, :lo12:__security_cookie]
+; WINDOWS-AARCH64: adrp x19, __security_cookie
+; WINDOWS-AARCH64: ldr x8, [x19, :lo12:__security_cookie]
 ; WINDOWS-AARCH64: str x8, [sp, #8]
 ; WINDOWS-AARCH64: bl  _Z7CapturePi
-; WINDOWS-AARCH64: ldr x0, [sp, #8]
+; WINDOWS-AARCH64: ldr x8, [sp, #8]
 ; WINDOWS-AARCH64: bl  __security_check_cookie
 
-; WINDOWS-ARM64EC: adrp x8, __security_cookie
-; WINDOWS-ARM64EC: ldr x8, [x8, :lo12:__security_cookie]
+; WINDOWS-ARM64EC: adrp x19, __security_cookie
+; WINDOWS-ARM64EC: ldr x8, [x19, :lo12:__security_cookie]
 ; WINDOWS-ARM64EC: str x8, [sp, #8]
 ; WINDOWS-ARM64EC: bl "#_Z7CapturePi"
-; WINDOWS-ARM64EC: ldr x0, [sp, #8]
+; WINDOWS-ARM64EC: ldr x8, [sp, #8]
 ; WINDOWS-ARM64EC: bl "#__security_check_cookie_arm64ec"

>From c5b61ae18aa0ab66f27591ef20f4ff3028c3aaa4 Mon Sep 17 00:00:00 2001
From: "Pan, Tao" <tao.pan at intel.com>
Date: Thu, 16 Oct 2025 09:09:33 +0800
Subject: [PATCH 04/11] Add the EOR instruction in
 AArch64InstrInfo::expandPostRAPseudo

---
 .../Target/AArch64/AArch64ISelLowering.cpp    | 20 +------------
 llvm/lib/Target/AArch64/AArch64ISelLowering.h |  3 --
 llvm/lib/Target/AArch64/AArch64InstrInfo.cpp  |  8 +++++
 .../AArch64/AArch64SelectionDAGInfo.cpp       |  2 +-
 llvm/test/CodeGen/AArch64/mingw-refptr.ll     | 30 ++++++++-----------
 .../CodeGen/AArch64/stack-protector-target.ll | 14 +++++----
 6 files changed, 30 insertions(+), 47 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index f04672a7396c5..d21e19b2ecd46 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -29239,25 +29239,7 @@ void AArch64TargetLowering::ReplaceNodeResults(
 bool AArch64TargetLowering::useLoadStackGuardNode(const Module &M) const {
   if (Subtarget->isTargetAndroid() || Subtarget->isTargetFuchsia())
     return TargetLowering::useLoadStackGuardNode(M);
-  return !Subtarget->getTargetTriple().isOSMSVCRT() ||
-         Subtarget->isTargetMachO() ||
-         getTargetMachine().Options.EnableGlobalISel;
-}
-
-bool AArch64TargetLowering::useStackGuardXorFP() const {
-  // Currently only MSVC CRTs XOR the frame pointer into the stack guard value.
-  return Subtarget->getTargetTriple().isOSMSVCRT() &&
-         !Subtarget->isTargetMachO() &&
-         !getTargetMachine().Options.EnableGlobalISel;
-}
-
-SDValue AArch64TargetLowering::emitStackGuardXorFP(SelectionDAG &DAG,
-                                                   SDValue Val,
-                                                   const SDLoc &DL) const {
-  return DAG.getNode(ISD::XOR, DL, Val.getValueType(), Val,
-                     DAG.getCopyFromReg(DAG.getEntryNode(), DL,
-                                        getStackPointerRegisterToSaveRestore(),
-                                        MVT::i64));
+  return true;
 }
 
 unsigned AArch64TargetLowering::combineRepeatedFPDivisors() const {
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
index 7e5a275a397a8..be198e54cbcbf 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
@@ -363,9 +363,6 @@ class AArch64TargetLowering : public TargetLowering {
   shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const override;
 
   bool useLoadStackGuardNode(const Module &M) const override;
-  bool useStackGuardXorFP() const override;
-  SDValue emitStackGuardXorFP(SelectionDAG &DAG, SDValue Val,
-                              const SDLoc &DL) const override;
   TargetLoweringBase::LegalizeTypeAction
   getPreferredVectorAction(MVT VT) const override;
 
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
index 00fe8ee8b9b4d..7e55daf6232ce 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
@@ -2496,6 +2496,14 @@ bool AArch64InstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
           .addGlobalAddress(GV, 0, LoFlags)
           .addMemOperand(*MI.memoperands_begin());
     }
+    if (Subtarget.getTargetTriple().isOSMSVCRT() &&
+        !Subtarget.getTargetLowering()
+             ->getTargetMachine()
+             .Options.EnableGlobalISel) {
+      BuildMI(MBB, MI, DL, get(AArch64::EORWrr), Reg)
+          .addReg(Reg, RegState::Kill)
+          .addReg(AArch64::SP);
+    }
   }
 
   MBB.erase(MI);
diff --git a/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp b/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp
index 2c75637505b0f..48e03ad853d26 100644
--- a/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp
@@ -38,7 +38,7 @@ void AArch64SelectionDAGInfo::verifyTargetNode(const SelectionDAG &DAG,
     return;
   }
 
-  //  SelectionDAGGenTargetInfo::verifyTargetNode(DAG, N);
+  SelectionDAGGenTargetInfo::verifyTargetNode(DAG, N);
 
 #ifndef NDEBUG
   // Some additional checks not yet implemented by verifyTargetNode.
diff --git a/llvm/test/CodeGen/AArch64/mingw-refptr.ll b/llvm/test/CodeGen/AArch64/mingw-refptr.ll
index 4a203d74876a7..208f629c0c47b 100644
--- a/llvm/test/CodeGen/AArch64/mingw-refptr.ll
+++ b/llvm/test/CodeGen/AArch64/mingw-refptr.ll
@@ -1,6 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
 ; RUN: llc < %s -mtriple=aarch64-w64-mingw32 | FileCheck %s --check-prefixes=CHECK,CHECK-SD
-; RUN: llc < %s -mtriple=aarch64-w64-mingw32 -global-isel | FileCheck %s --check-prefixes=CHECK-GI
+; RUN: llc < %s -mtriple=aarch64-w64-mingw32 -global-isel | FileCheck %s --check-prefixes=CHECK,CHECK-GI
 
 @var = external local_unnamed_addr global i32, align 4
 @dsolocalvar = external dso_local local_unnamed_addr global i32, align 4
@@ -118,31 +118,25 @@ define dso_local void @sspFunc() #0 {
 ; CHECK-NEXT:  // %bb.0: // %entry
 ; CHECK-NEXT:    sub sp, sp, #32
 ; CHECK-NEXT:    .seh_stackalloc 32
-; CHECK-NEXT:    str x19, [sp, #16] // 8-byte Spill
-; CHECK-NEXT:    .seh_save_reg x19, 16
-; CHECK-NEXT:    str x30, [sp, #24] // 8-byte Spill
-; CHECK-NEXT:    .seh_save_reg x30, 24
+; CHECK-NEXT:    str x30, [sp, #16] // 8-byte Folded Spill
+; CHECK-NEXT:    .seh_save_reg x30, 16
 ; CHECK-NEXT:    .seh_endprologue
-; CHECK-NEXT:    adrp x19, .refptr.__stack_chk_guard
-; CHECK-NEXT:    mov x9, sp
+; CHECK-NEXT:    adrp x8, .refptr.__stack_chk_guard
 ; CHECK-NEXT:    add x0, sp, #7
-; CHECK-NEXT:    ldr x19, [x19, :lo12:.refptr.__stack_chk_guard]
-; CHECK-NEXT:    ldr x8, [x19]
-; CHECK-NEXT:    eor x8, x8, x9
+; CHECK-NEXT:    ldr x8, [x8, :lo12:.refptr.__stack_chk_guard]
+; CHECK-NEXT:    ldr x8, [x8]
 ; CHECK-NEXT:    str x8, [sp, #8]
 ; CHECK-NEXT:    bl ptrUser
+; CHECK-NEXT:    adrp x8, .refptr.__stack_chk_guard
+; CHECK-NEXT:    ldr x8, [x8, :lo12:.refptr.__stack_chk_guard]
 ; CHECK-NEXT:    ldr x9, [sp, #8]
-; CHECK-NEXT:    mov x8, sp
-; CHECK-NEXT:    ldr x10, [x19]
-; CHECK-NEXT:    eor x8, x9, x8
-; CHECK-NEXT:    cmp x10, x8
+; CHECK-NEXT:    ldr x8, [x8]
+; CHECK-NEXT:    cmp x8, x9
 ; CHECK-NEXT:    b.ne .LBB6_2
 ; CHECK-NEXT:  // %bb.1: // %entry
 ; CHECK-NEXT:    .seh_startepilogue
-; CHECK-NEXT:    ldr x30, [sp, #24] // 8-byte Reload
-; CHECK-NEXT:    .seh_save_reg x30, 24
-; CHECK-NEXT:    ldr x19, [sp, #16] // 8-byte Reload
-; CHECK-NEXT:    .seh_save_reg x19, 16
+; CHECK-NEXT:    ldr x30, [sp, #16] // 8-byte Folded Reload
+; CHECK-NEXT:    .seh_save_reg x30, 16
 ; CHECK-NEXT:    add sp, sp, #32
 ; CHECK-NEXT:    .seh_stackalloc 32
 ; CHECK-NEXT:    .seh_endepilogue
diff --git a/llvm/test/CodeGen/AArch64/stack-protector-target.ll b/llvm/test/CodeGen/AArch64/stack-protector-target.ll
index 9940a4d75d09b..59045190c8892 100644
--- a/llvm/test/CodeGen/AArch64/stack-protector-target.ll
+++ b/llvm/test/CodeGen/AArch64/stack-protector-target.ll
@@ -29,16 +29,18 @@ declare void @_Z7CapturePi(ptr)
 ; FUCHSIA-AARCH64-COMMON: ldr [[D:.*]], [sp,
 ; FUCHSIA-AARCH64-COMMON: cmp [[C]], [[D]]
 
-; WINDOWS-AARCH64: adrp x19, __security_cookie
-; WINDOWS-AARCH64: ldr x8, [x19, :lo12:__security_cookie]
+; WINDOWS-AARCH64: adrp x8, __security_cookie
+; WINDOWS-AARCH64: ldr x8, [x8, :lo12:__security_cookie]
+; WINDOWS-AARCH64: eor x8, x8, sp
 ; WINDOWS-AARCH64: str x8, [sp, #8]
 ; WINDOWS-AARCH64: bl  _Z7CapturePi
-; WINDOWS-AARCH64: ldr x8, [sp, #8]
+; WINDOWS-AARCH64: ldr x0, [sp, #8]
 ; WINDOWS-AARCH64: bl  __security_check_cookie
 
-; WINDOWS-ARM64EC: adrp x19, __security_cookie
-; WINDOWS-ARM64EC: ldr x8, [x19, :lo12:__security_cookie]
+; WINDOWS-ARM64EC: adrp x8, __security_cookie
+; WINDOWS-ARM64EC: ldr x8, [x8, :lo12:__security_cookie]
+; WINDOWS-ARM64EC: eor x8, x8, sp
 ; WINDOWS-ARM64EC: str x8, [sp, #8]
 ; WINDOWS-ARM64EC: bl "#_Z7CapturePi"
-; WINDOWS-ARM64EC: ldr x8, [sp, #8]
+; WINDOWS-ARM64EC: ldr x0, [sp, #8]
 ; WINDOWS-ARM64EC: bl "#__security_check_cookie_arm64ec"

>From 276396403748e9c0c16730db1656ea32888ceefc Mon Sep 17 00:00:00 2001
From: "Pan, Tao" <tao.pan at intel.com>
Date: Thu, 16 Oct 2025 14:17:29 +0800
Subject: [PATCH 05/11] Add the eor instruction to any code model

---
 llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | 17 +++++++++--------
 llvm/test/CodeGen/AArch64/mingw-refptr.ll    |  4 +++-
 2 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
index 7e55daf6232ce..c1ae0477e4aac 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
@@ -2496,14 +2496,15 @@ bool AArch64InstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
           .addGlobalAddress(GV, 0, LoFlags)
           .addMemOperand(*MI.memoperands_begin());
     }
-    if (Subtarget.getTargetTriple().isOSMSVCRT() &&
-        !Subtarget.getTargetLowering()
-             ->getTargetMachine()
-             .Options.EnableGlobalISel) {
-      BuildMI(MBB, MI, DL, get(AArch64::EORWrr), Reg)
-          .addReg(Reg, RegState::Kill)
-          .addReg(AArch64::SP);
-    }
+  }
+  // To match MSVC
+  if (Subtarget.getTargetTriple().isOSMSVCRT() &&
+      !Subtarget.getTargetLowering()
+           ->getTargetMachine()
+           .Options.EnableGlobalISel) {
+    BuildMI(MBB, MI, DL, get(AArch64::EORWrr), Reg)
+        .addReg(Reg, RegState::Kill)
+        .addReg(AArch64::SP);
   }
 
   MBB.erase(MI);
diff --git a/llvm/test/CodeGen/AArch64/mingw-refptr.ll b/llvm/test/CodeGen/AArch64/mingw-refptr.ll
index 208f629c0c47b..c7603b8c9ab17 100644
--- a/llvm/test/CodeGen/AArch64/mingw-refptr.ll
+++ b/llvm/test/CodeGen/AArch64/mingw-refptr.ll
@@ -1,6 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
 ; RUN: llc < %s -mtriple=aarch64-w64-mingw32 | FileCheck %s --check-prefixes=CHECK,CHECK-SD
-; RUN: llc < %s -mtriple=aarch64-w64-mingw32 -global-isel | FileCheck %s --check-prefixes=CHECK,CHECK-GI
+; RUN: llc < %s -mtriple=aarch64-w64-mingw32 -global-isel | FileCheck %s --check-prefixes=CHECK-GI
 
 @var = external local_unnamed_addr global i32, align 4
 @dsolocalvar = external dso_local local_unnamed_addr global i32, align 4
@@ -125,12 +125,14 @@ define dso_local void @sspFunc() #0 {
 ; CHECK-NEXT:    add x0, sp, #7
 ; CHECK-NEXT:    ldr x8, [x8, :lo12:.refptr.__stack_chk_guard]
 ; CHECK-NEXT:    ldr x8, [x8]
+; CHECK-NEXT:    eor x8, x8, sp
 ; CHECK-NEXT:    str x8, [sp, #8]
 ; CHECK-NEXT:    bl ptrUser
 ; CHECK-NEXT:    adrp x8, .refptr.__stack_chk_guard
 ; CHECK-NEXT:    ldr x8, [x8, :lo12:.refptr.__stack_chk_guard]
 ; CHECK-NEXT:    ldr x9, [sp, #8]
 ; CHECK-NEXT:    ldr x8, [x8]
+; CHECK-NEXT:    eor x8, x8, sp
 ; CHECK-NEXT:    cmp x8, x9
 ; CHECK-NEXT:    b.ne .LBB6_2
 ; CHECK-NEXT:  // %bb.1: // %entry

>From 414995a9c17b460d5e66b2370ea75adb8fad9b26 Mon Sep 17 00:00:00 2001
From: "Pan, Tao" <tao.pan at intel.com>
Date: Fri, 17 Oct 2025 09:45:22 +0800
Subject: [PATCH 06/11] Add the eor instruction in the failure BB

---
 llvm/include/llvm/CodeGen/TargetLowering.h    |  2 +-
 .../SelectionDAG/SelectionDAGBuilder.cpp      |  6 +++---
 .../Target/AArch64/AArch64ISelLowering.cpp    | 19 +++++++++++++++++++
 llvm/lib/Target/AArch64/AArch64ISelLowering.h |  3 +++
 llvm/lib/Target/X86/X86ISelLowering.cpp       |  3 ++-
 llvm/lib/Target/X86/X86ISelLowering.h         |  5 ++---
 .../CodeGen/AArch64/stack-protector-target.ll |  8 ++++++--
 7 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index 4c932c523e423..0814b9ea162b4 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -5828,7 +5828,7 @@ class LLVM_ABI TargetLowering : public TargetLoweringBase {
   virtual bool useLoadStackGuardNode(const Module &M) const { return false; }
 
   virtual SDValue emitStackGuardXorFP(SelectionDAG &DAG, SDValue Val,
-                                      const SDLoc &DL) const {
+                                      const SDLoc &DL, bool FailureBB) const {
     llvm_unreachable("not implemented for this target");
   }
 
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 4f13f3b128ea4..d76125d2a2a03 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -3129,7 +3129,7 @@ void SelectionDAGBuilder::visitSPDescriptorParent(StackProtectorDescriptor &SPD,
       MachineMemOperand::MOVolatile);
 
   if (TLI.useStackGuardXorFP())
-    GuardVal = TLI.emitStackGuardXorFP(DAG, GuardVal, dl);
+    GuardVal = TLI.emitStackGuardXorFP(DAG, GuardVal, dl, false);
 
   // If we're using function-based instrumentation, call the guard check
   // function
@@ -3238,7 +3238,7 @@ void SelectionDAGBuilder::visitSPDescriptorFailure(
         MachineMemOperand::MOVolatile);
 
     if (TLI.useStackGuardXorFP())
-      GuardVal = TLI.emitStackGuardXorFP(DAG, GuardVal, dl);
+      GuardVal = TLI.emitStackGuardXorFP(DAG, GuardVal, dl, true);
 
     // The target provides a guard check function to validate the guard value.
     // Generate a call to that function with the content of the guard slot as
@@ -7429,7 +7429,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
                         MachineMemOperand::MOVolatile);
     }
     if (TLI.useStackGuardXorFP())
-      Res = TLI.emitStackGuardXorFP(DAG, Res, sdl);
+      Res = TLI.emitStackGuardXorFP(DAG, Res, sdl, false);
     DAG.setRoot(Chain);
     setValue(&I, Res);
     return;
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index d21e19b2ecd46..5382ecbc428b6 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -29242,6 +29242,25 @@ bool AArch64TargetLowering::useLoadStackGuardNode(const Module &M) const {
   return true;
 }
 
+bool AArch64TargetLowering::useStackGuardXorFP() const {
+  // Currently only MSVC CRTs XOR the frame pointer into the stack guard value.
+  return Subtarget->getTargetTriple().isOSMSVCRT() &&
+         !Subtarget->isTargetMachO() &&
+         !getTargetMachine().Options.EnableGlobalISel;
+}
+
+SDValue AArch64TargetLowering::emitStackGuardXorFP(SelectionDAG &DAG,
+                                                   SDValue Val, const SDLoc &DL,
+                                                   bool FailureBB) const {
+  if (FailureBB) {
+    return DAG.getNode(
+        ISD::XOR, DL, Val.getValueType(), Val,
+        DAG.getCopyFromReg(DAG.getEntryNode(), DL,
+                           getStackPointerRegisterToSaveRestore(), MVT::i64));
+  }
+  return Val;
+}
+
 unsigned AArch64TargetLowering::combineRepeatedFPDivisors() const {
   // Combine multiple FDIVs with the same divisor into multiple FMULs by the
   // reciprocal if there are three or more FDIVs.
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
index be198e54cbcbf..07253799e1142 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
@@ -363,6 +363,9 @@ class AArch64TargetLowering : public TargetLowering {
   shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const override;
 
   bool useLoadStackGuardNode(const Module &M) const override;
+  bool useStackGuardXorFP() const override;
+  SDValue emitStackGuardXorFP(SelectionDAG &DAG, SDValue Val, const SDLoc &DL,
+                              bool FailureBB) const override;
   TargetLoweringBase::LegalizeTypeAction
   getPreferredVectorAction(MVT VT) const override;
 
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 864e5dc67682c..fa7ac175ec7fd 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -2744,7 +2744,8 @@ bool X86TargetLowering::useStackGuardXorFP() const {
 }
 
 SDValue X86TargetLowering::emitStackGuardXorFP(SelectionDAG &DAG, SDValue Val,
-                                               const SDLoc &DL) const {
+                                               const SDLoc &DL,
+                                               bool FailureBB) const {
   EVT PtrTy = getPointerTy(DAG.getDataLayout());
   unsigned XorOp = Subtarget.is64Bit() ? X86::XOR64_FP : X86::XOR32_FP;
   MachineSDNode *Node = DAG.getMachineNode(XorOp, DL, PtrTy, Val);
diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h
index b7151f65942b4..752b94520c4c4 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.h
+++ b/llvm/lib/Target/X86/X86ISelLowering.h
@@ -1592,9 +1592,8 @@ namespace llvm {
     bool useLoadStackGuardNode(const Module &M) const override;
     bool useStackGuardXorFP() const override;
     void insertSSPDeclarations(Module &M) const override;
-    SDValue emitStackGuardXorFP(SelectionDAG &DAG, SDValue Val,
-                                const SDLoc &DL) const override;
-
+    SDValue emitStackGuardXorFP(SelectionDAG &DAG, SDValue Val, const SDLoc &DL,
+                                bool FailureBB) const override;
 
     /// Return true if the target stores SafeStack pointer at a fixed offset in
     /// some non-standard address space, and populates the address space and
diff --git a/llvm/test/CodeGen/AArch64/stack-protector-target.ll b/llvm/test/CodeGen/AArch64/stack-protector-target.ll
index 59045190c8892..201950a6355a3 100644
--- a/llvm/test/CodeGen/AArch64/stack-protector-target.ll
+++ b/llvm/test/CodeGen/AArch64/stack-protector-target.ll
@@ -34,7 +34,9 @@ declare void @_Z7CapturePi(ptr)
 ; WINDOWS-AARCH64: eor x8, x8, sp
 ; WINDOWS-AARCH64: str x8, [sp, #8]
 ; WINDOWS-AARCH64: bl  _Z7CapturePi
-; WINDOWS-AARCH64: ldr x0, [sp, #8]
+; WINDOWS-AARCH64: ldr x8, [sp, #8]
+; WINDOWS-AARCH64: mov x9, sp
+; WINDOWS-AARCH64: eor x0, x8, x9
 ; WINDOWS-AARCH64: bl  __security_check_cookie
 
 ; WINDOWS-ARM64EC: adrp x8, __security_cookie
@@ -42,5 +44,7 @@ declare void @_Z7CapturePi(ptr)
 ; WINDOWS-ARM64EC: eor x8, x8, sp
 ; WINDOWS-ARM64EC: str x8, [sp, #8]
 ; WINDOWS-ARM64EC: bl "#_Z7CapturePi"
-; WINDOWS-ARM64EC: ldr x0, [sp, #8]
+; WINDOWS-ARM64EC: ldr x8, [sp, #8]
+; WINDOWS-ARM64EC: mov x9, sp
+; WINDOWS-ARM64EC: eor x0, x8, x9
 ; WINDOWS-ARM64EC: bl "#__security_check_cookie_arm64ec"

>From 65acb8c87d40e495c6ce36267d54ad4eb4274494 Mon Sep 17 00:00:00 2001
From: "Pan, Tao" <tao.pan at intel.com>
Date: Tue, 21 Oct 2025 09:17:57 +0800
Subject: [PATCH 07/11] Remove the isTargetMachO() check and change EORWrr to
 EORXrr

---
 llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 1 -
 llvm/lib/Target/AArch64/AArch64InstrInfo.cpp    | 2 +-
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 5382ecbc428b6..211e82feb77f5 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -29245,7 +29245,6 @@ bool AArch64TargetLowering::useLoadStackGuardNode(const Module &M) const {
 bool AArch64TargetLowering::useStackGuardXorFP() const {
   // Currently only MSVC CRTs XOR the frame pointer into the stack guard value.
   return Subtarget->getTargetTriple().isOSMSVCRT() &&
-         !Subtarget->isTargetMachO() &&
          !getTargetMachine().Options.EnableGlobalISel;
 }
 
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
index c1ae0477e4aac..1f105cb8eae05 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
@@ -2502,7 +2502,7 @@ bool AArch64InstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
       !Subtarget.getTargetLowering()
            ->getTargetMachine()
            .Options.EnableGlobalISel) {
-    BuildMI(MBB, MI, DL, get(AArch64::EORWrr), Reg)
+    BuildMI(MBB, MI, DL, get(AArch64::EORXrr), Reg)
         .addReg(Reg, RegState::Kill)
         .addReg(AArch64::SP);
   }

>From df095478396bd40a4971ed665044db9e6b9331bf Mon Sep 17 00:00:00 2001
From: "Pan, Tao" <tao.pan at intel.com>
Date: Mon, 3 Nov 2025 12:44:48 +0800
Subject: [PATCH 08/11] Change the mixed instruction from xor to sub and change
 interface name from xor to mix

---
 llvm/include/llvm/CodeGen/TargetLowering.h           | 10 +++++-----
 llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp         |  5 +++--
 .../lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 12 ++++++------
 llvm/lib/CodeGen/StackProtector.cpp                  |  2 +-
 llvm/lib/Target/AArch64/AArch64ISelLowering.cpp      | 11 ++++++-----
 llvm/lib/Target/AArch64/AArch64ISelLowering.h        |  7 ++++---
 llvm/lib/Target/AArch64/AArch64InstrInfo.cpp         |  6 +++---
 llvm/lib/Target/X86/X86ISelLowering.cpp              |  8 ++++----
 llvm/lib/Target/X86/X86ISelLowering.h                |  7 ++++---
 llvm/test/CodeGen/AArch64/mingw-refptr.ll            |  4 ++--
 llvm/test/CodeGen/AArch64/stack-protector-target.ll  |  8 ++++----
 11 files changed, 42 insertions(+), 38 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index 0814b9ea162b4..140198f4d0e07 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -2134,11 +2134,10 @@ class LLVM_ABI TargetLoweringBase {
   /// getIRStackGuard returns nullptr.
   virtual Value *getSDagStackGuard(const Module &M) const;
 
-  /// If this function returns true, stack protection checks should XOR the
-  /// frame pointer (or whichever pointer is used to address locals) into the
+  /// If this function returns true, stack protection checks should mix the
   /// stack guard value before checking it. getIRStackGuard must return nullptr
   /// if this returns true.
-  virtual bool useStackGuardXorFP() const { return false; }
+  virtual bool useStackGuardMixCookie() const { return false; }
 
   /// If the target has a standard stack protection check function that
   /// performs validation and error handling, returns the function. Otherwise,
@@ -5827,8 +5826,9 @@ class LLVM_ABI TargetLowering : public TargetLoweringBase {
   /// LOAD_STACK_GUARD node when it is lowering Intrinsic::stackprotector.
   virtual bool useLoadStackGuardNode(const Module &M) const { return false; }
 
-  virtual SDValue emitStackGuardXorFP(SelectionDAG &DAG, SDValue Val,
-                                      const SDLoc &DL, bool FailureBB) const {
+  virtual SDValue emitStackGuardMixCookie(SelectionDAG &DAG, SDValue Val,
+                                          const SDLoc &DL,
+                                          bool FailureBB) const {
     llvm_unreachable("not implemented for this target");
   }
 
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 2ec138b6e186d..645c67df968f0 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -3963,8 +3963,9 @@ bool IRTranslator::emitSPDescriptorParent(StackProtectorDescriptor &SPD,
                       MachineMemOperand::MOLoad | MachineMemOperand::MOVolatile)
           .getReg(0);
 
-  if (TLI->useStackGuardXorFP()) {
-    LLVM_DEBUG(dbgs() << "Stack protector xor'ing with FP not yet implemented");
+  if (TLI->useStackGuardMixCookie()) {
+    LLVM_DEBUG(
+        dbgs() << "Stack protector mix'ing the cookie not yet implemented");
     return false;
   }
 
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index d76125d2a2a03..ac3e2c3a158f4 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -3128,8 +3128,8 @@ void SelectionDAGBuilder::visitSPDescriptorParent(StackProtectorDescriptor &SPD,
       MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI), Align,
       MachineMemOperand::MOVolatile);
 
-  if (TLI.useStackGuardXorFP())
-    GuardVal = TLI.emitStackGuardXorFP(DAG, GuardVal, dl, false);
+  if (TLI.useStackGuardMixCookie())
+    GuardVal = TLI.emitStackGuardMixCookie(DAG, GuardVal, dl, false);
 
   // If we're using function-based instrumentation, call the guard check
   // function
@@ -3237,8 +3237,8 @@ void SelectionDAGBuilder::visitSPDescriptorFailure(
         MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI), Align,
         MachineMemOperand::MOVolatile);
 
-    if (TLI.useStackGuardXorFP())
-      GuardVal = TLI.emitStackGuardXorFP(DAG, GuardVal, dl, true);
+    if (TLI.useStackGuardMixCookie())
+      GuardVal = TLI.emitStackGuardMixCookie(DAG, GuardVal, dl, true);
 
     // The target provides a guard check function to validate the guard value.
     // Generate a call to that function with the content of the guard slot as
@@ -7428,8 +7428,8 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
                         MachinePointerInfo(Global, 0), Align,
                         MachineMemOperand::MOVolatile);
     }
-    if (TLI.useStackGuardXorFP())
-      Res = TLI.emitStackGuardXorFP(DAG, Res, sdl, false);
+    if (TLI.useStackGuardMixCookie())
+      Res = TLI.emitStackGuardMixCookie(DAG, Res, sdl, false);
     DAG.setRoot(Chain);
     setValue(&I, Res);
     return;
diff --git a/llvm/lib/CodeGen/StackProtector.cpp b/llvm/lib/CodeGen/StackProtector.cpp
index 5fd5d6cce23df..971c3e58b10ef 100644
--- a/llvm/lib/CodeGen/StackProtector.cpp
+++ b/llvm/lib/CodeGen/StackProtector.cpp
@@ -576,7 +576,7 @@ bool InsertStackProtectors(const TargetMachine *TM, Function *F,
   // impossible to emit the check in IR, so the target *must* support stack
   // protection in SDAG.
   bool SupportsSelectionDAGSP =
-      TLI->useStackGuardXorFP() ||
+      TLI->useStackGuardMixCookie() ||
       (EnableSelectionDAGSP && !TM->Options.EnableFastISel);
   AllocaInst *AI = nullptr; // Place on stack that stores the stack guard.
   BasicBlock *FailBB = nullptr;
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 211e82feb77f5..53a52fb36a77c 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -29242,18 +29242,19 @@ bool AArch64TargetLowering::useLoadStackGuardNode(const Module &M) const {
   return true;
 }
 
-bool AArch64TargetLowering::useStackGuardXorFP() const {
+bool AArch64TargetLowering::useStackGuardMixCookie() const {
   // Currently only MSVC CRTs XOR the frame pointer into the stack guard value.
   return Subtarget->getTargetTriple().isOSMSVCRT() &&
          !getTargetMachine().Options.EnableGlobalISel;
 }
 
-SDValue AArch64TargetLowering::emitStackGuardXorFP(SelectionDAG &DAG,
-                                                   SDValue Val, const SDLoc &DL,
-                                                   bool FailureBB) const {
+SDValue AArch64TargetLowering::emitStackGuardMixCookie(SelectionDAG &DAG,
+                                                       SDValue Val,
+                                                       const SDLoc &DL,
+                                                       bool FailureBB) const {
   if (FailureBB) {
     return DAG.getNode(
-        ISD::XOR, DL, Val.getValueType(), Val,
+        ISD::ADD, DL, Val.getValueType(), Val,
         DAG.getCopyFromReg(DAG.getEntryNode(), DL,
                            getStackPointerRegisterToSaveRestore(), MVT::i64));
   }
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
index 07253799e1142..13beabe45aa15 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
@@ -363,9 +363,10 @@ class AArch64TargetLowering : public TargetLowering {
   shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const override;
 
   bool useLoadStackGuardNode(const Module &M) const override;
-  bool useStackGuardXorFP() const override;
-  SDValue emitStackGuardXorFP(SelectionDAG &DAG, SDValue Val, const SDLoc &DL,
-                              bool FailureBB) const override;
+  bool useStackGuardMixCookie() const override;
+  SDValue emitStackGuardMixCookie(SelectionDAG &DAG, SDValue Val,
+                                  const SDLoc &DL,
+                                  bool FailureBB) const override;
   TargetLoweringBase::LegalizeTypeAction
   getPreferredVectorAction(MVT VT) const override;
 
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
index 1f105cb8eae05..265d50c833eb5 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
@@ -2502,9 +2502,9 @@ bool AArch64InstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
       !Subtarget.getTargetLowering()
            ->getTargetMachine()
            .Options.EnableGlobalISel) {
-    BuildMI(MBB, MI, DL, get(AArch64::EORXrr), Reg)
-        .addReg(Reg, RegState::Kill)
-        .addReg(AArch64::SP);
+    BuildMI(MBB, MI, DL, get(AArch64::SUBXrr), Reg)
+        .addReg(AArch64::SP)
+        .addReg(Reg, RegState::Kill);
   }
 
   MBB.erase(MI);
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index fa7ac175ec7fd..611bae1d48e68 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -2738,14 +2738,14 @@ bool X86TargetLowering::useLoadStackGuardNode(const Module &M) const {
   return Subtarget.isTargetMachO() && Subtarget.is64Bit();
 }
 
-bool X86TargetLowering::useStackGuardXorFP() const {
+bool X86TargetLowering::useStackGuardMixCookie() const {
   // Currently only MSVC CRTs XOR the frame pointer into the stack guard value.
   return Subtarget.getTargetTriple().isOSMSVCRT() && !Subtarget.isTargetMachO();
 }
 
-SDValue X86TargetLowering::emitStackGuardXorFP(SelectionDAG &DAG, SDValue Val,
-                                               const SDLoc &DL,
-                                               bool FailureBB) const {
+SDValue X86TargetLowering::emitStackGuardMixCookie(SelectionDAG &DAG,
+                                                   SDValue Val, const SDLoc &DL,
+                                                   bool FailureBB) const {
   EVT PtrTy = getPointerTy(DAG.getDataLayout());
   unsigned XorOp = Subtarget.is64Bit() ? X86::XOR64_FP : X86::XOR32_FP;
   MachineSDNode *Node = DAG.getMachineNode(XorOp, DL, PtrTy, Val);
diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h
index 752b94520c4c4..0b8ffe74512a4 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.h
+++ b/llvm/lib/Target/X86/X86ISelLowering.h
@@ -1590,10 +1590,11 @@ namespace llvm {
     Value *getIRStackGuard(IRBuilderBase &IRB) const override;
 
     bool useLoadStackGuardNode(const Module &M) const override;
-    bool useStackGuardXorFP() const override;
+    bool useStackGuardMixCookie() const override;
     void insertSSPDeclarations(Module &M) const override;
-    SDValue emitStackGuardXorFP(SelectionDAG &DAG, SDValue Val, const SDLoc &DL,
-                                bool FailureBB) const override;
+    SDValue emitStackGuardMixCookie(SelectionDAG &DAG, SDValue Val,
+                                    const SDLoc &DL,
+                                    bool FailureBB) const override;
 
     /// Return true if the target stores SafeStack pointer at a fixed offset in
     /// some non-standard address space, and populates the address space and
diff --git a/llvm/test/CodeGen/AArch64/mingw-refptr.ll b/llvm/test/CodeGen/AArch64/mingw-refptr.ll
index c7603b8c9ab17..5d85b231ecc4f 100644
--- a/llvm/test/CodeGen/AArch64/mingw-refptr.ll
+++ b/llvm/test/CodeGen/AArch64/mingw-refptr.ll
@@ -125,14 +125,14 @@ define dso_local void @sspFunc() #0 {
 ; CHECK-NEXT:    add x0, sp, #7
 ; CHECK-NEXT:    ldr x8, [x8, :lo12:.refptr.__stack_chk_guard]
 ; CHECK-NEXT:    ldr x8, [x8]
-; CHECK-NEXT:    eor x8, x8, sp
+; CHECK-NEXT:    sub x8, sp, x8
 ; CHECK-NEXT:    str x8, [sp, #8]
 ; CHECK-NEXT:    bl ptrUser
 ; CHECK-NEXT:    adrp x8, .refptr.__stack_chk_guard
 ; CHECK-NEXT:    ldr x8, [x8, :lo12:.refptr.__stack_chk_guard]
 ; CHECK-NEXT:    ldr x9, [sp, #8]
 ; CHECK-NEXT:    ldr x8, [x8]
-; CHECK-NEXT:    eor x8, x8, sp
+; CHECK-NEXT:    sub x8, sp, x8
 ; CHECK-NEXT:    cmp x8, x9
 ; CHECK-NEXT:    b.ne .LBB6_2
 ; CHECK-NEXT:  // %bb.1: // %entry
diff --git a/llvm/test/CodeGen/AArch64/stack-protector-target.ll b/llvm/test/CodeGen/AArch64/stack-protector-target.ll
index 201950a6355a3..4c8c25a31faa1 100644
--- a/llvm/test/CodeGen/AArch64/stack-protector-target.ll
+++ b/llvm/test/CodeGen/AArch64/stack-protector-target.ll
@@ -31,20 +31,20 @@ declare void @_Z7CapturePi(ptr)
 
 ; WINDOWS-AARCH64: adrp x8, __security_cookie
 ; WINDOWS-AARCH64: ldr x8, [x8, :lo12:__security_cookie]
-; WINDOWS-AARCH64: eor x8, x8, sp
+; WINDOWS-AARCH64: sub x8, sp, x8
 ; WINDOWS-AARCH64: str x8, [sp, #8]
 ; WINDOWS-AARCH64: bl  _Z7CapturePi
 ; WINDOWS-AARCH64: ldr x8, [sp, #8]
 ; WINDOWS-AARCH64: mov x9, sp
-; WINDOWS-AARCH64: eor x0, x8, x9
+; WINDOWS-AARCH64: add x0, x8, x9
 ; WINDOWS-AARCH64: bl  __security_check_cookie
 
 ; WINDOWS-ARM64EC: adrp x8, __security_cookie
 ; WINDOWS-ARM64EC: ldr x8, [x8, :lo12:__security_cookie]
-; WINDOWS-ARM64EC: eor x8, x8, sp
+; WINDOWS-ARM64EC: sub x8, sp, x8
 ; WINDOWS-ARM64EC: str x8, [sp, #8]
 ; WINDOWS-ARM64EC: bl "#_Z7CapturePi"
 ; WINDOWS-ARM64EC: ldr x8, [sp, #8]
 ; WINDOWS-ARM64EC: mov x9, sp
-; WINDOWS-ARM64EC: eor x0, x8, x9
+; WINDOWS-ARM64EC: add x0, x8, x9
 ; WINDOWS-ARM64EC: bl "#__security_check_cookie_arm64ec"

>From 2e737b9b4cdf9487844206e1c3186e85ecabd002 Mon Sep 17 00:00:00 2001
From: "Pan, Tao" <tao.pan at intel.com>
Date: Fri, 14 Nov 2025 14:52:10 +0800
Subject: [PATCH 09/11] Commute the operands of the add and regenerate
 mingw-refptr.ll with update_llc_test_checks.py

---
 .../Target/AArch64/AArch64ISelLowering.cpp    |  5 ++--
 llvm/test/CodeGen/AArch64/mingw-refptr.ll     | 30 +++++++++++--------
 .../CodeGen/AArch64/stack-protector-target.ll |  4 +--
 3 files changed, 22 insertions(+), 17 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 53a52fb36a77c..590efff1b5612 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -29254,9 +29254,10 @@ SDValue AArch64TargetLowering::emitStackGuardMixCookie(SelectionDAG &DAG,
                                                        bool FailureBB) const {
   if (FailureBB) {
     return DAG.getNode(
-        ISD::ADD, DL, Val.getValueType(), Val,
+        ISD::ADD, DL, Val.getValueType(),
         DAG.getCopyFromReg(DAG.getEntryNode(), DL,
-                           getStackPointerRegisterToSaveRestore(), MVT::i64));
+                           getStackPointerRegisterToSaveRestore(), MVT::i64),
+        Val);
   }
   return Val;
 }
diff --git a/llvm/test/CodeGen/AArch64/mingw-refptr.ll b/llvm/test/CodeGen/AArch64/mingw-refptr.ll
index 5d85b231ecc4f..4a203d74876a7 100644
--- a/llvm/test/CodeGen/AArch64/mingw-refptr.ll
+++ b/llvm/test/CodeGen/AArch64/mingw-refptr.ll
@@ -118,27 +118,31 @@ define dso_local void @sspFunc() #0 {
 ; CHECK-NEXT:  // %bb.0: // %entry
 ; CHECK-NEXT:    sub sp, sp, #32
 ; CHECK-NEXT:    .seh_stackalloc 32
-; CHECK-NEXT:    str x30, [sp, #16] // 8-byte Folded Spill
-; CHECK-NEXT:    .seh_save_reg x30, 16
+; CHECK-NEXT:    str x19, [sp, #16] // 8-byte Spill
+; CHECK-NEXT:    .seh_save_reg x19, 16
+; CHECK-NEXT:    str x30, [sp, #24] // 8-byte Spill
+; CHECK-NEXT:    .seh_save_reg x30, 24
 ; CHECK-NEXT:    .seh_endprologue
-; CHECK-NEXT:    adrp x8, .refptr.__stack_chk_guard
+; CHECK-NEXT:    adrp x19, .refptr.__stack_chk_guard
+; CHECK-NEXT:    mov x9, sp
 ; CHECK-NEXT:    add x0, sp, #7
-; CHECK-NEXT:    ldr x8, [x8, :lo12:.refptr.__stack_chk_guard]
-; CHECK-NEXT:    ldr x8, [x8]
-; CHECK-NEXT:    sub x8, sp, x8
+; CHECK-NEXT:    ldr x19, [x19, :lo12:.refptr.__stack_chk_guard]
+; CHECK-NEXT:    ldr x8, [x19]
+; CHECK-NEXT:    eor x8, x8, x9
 ; CHECK-NEXT:    str x8, [sp, #8]
 ; CHECK-NEXT:    bl ptrUser
-; CHECK-NEXT:    adrp x8, .refptr.__stack_chk_guard
-; CHECK-NEXT:    ldr x8, [x8, :lo12:.refptr.__stack_chk_guard]
 ; CHECK-NEXT:    ldr x9, [sp, #8]
-; CHECK-NEXT:    ldr x8, [x8]
-; CHECK-NEXT:    sub x8, sp, x8
-; CHECK-NEXT:    cmp x8, x9
+; CHECK-NEXT:    mov x8, sp
+; CHECK-NEXT:    ldr x10, [x19]
+; CHECK-NEXT:    eor x8, x9, x8
+; CHECK-NEXT:    cmp x10, x8
 ; CHECK-NEXT:    b.ne .LBB6_2
 ; CHECK-NEXT:  // %bb.1: // %entry
 ; CHECK-NEXT:    .seh_startepilogue
-; CHECK-NEXT:    ldr x30, [sp, #16] // 8-byte Folded Reload
-; CHECK-NEXT:    .seh_save_reg x30, 16
+; CHECK-NEXT:    ldr x30, [sp, #24] // 8-byte Reload
+; CHECK-NEXT:    .seh_save_reg x30, 24
+; CHECK-NEXT:    ldr x19, [sp, #16] // 8-byte Reload
+; CHECK-NEXT:    .seh_save_reg x19, 16
 ; CHECK-NEXT:    add sp, sp, #32
 ; CHECK-NEXT:    .seh_stackalloc 32
 ; CHECK-NEXT:    .seh_endepilogue
diff --git a/llvm/test/CodeGen/AArch64/stack-protector-target.ll b/llvm/test/CodeGen/AArch64/stack-protector-target.ll
index 4c8c25a31faa1..821aebe702537 100644
--- a/llvm/test/CodeGen/AArch64/stack-protector-target.ll
+++ b/llvm/test/CodeGen/AArch64/stack-protector-target.ll
@@ -36,7 +36,7 @@ declare void @_Z7CapturePi(ptr)
 ; WINDOWS-AARCH64: bl  _Z7CapturePi
 ; WINDOWS-AARCH64: ldr x8, [sp, #8]
 ; WINDOWS-AARCH64: mov x9, sp
-; WINDOWS-AARCH64: add x0, x8, x9
+; WINDOWS-AARCH64: add x0, x9, x8
 ; WINDOWS-AARCH64: bl  __security_check_cookie
 
 ; WINDOWS-ARM64EC: adrp x8, __security_cookie
@@ -46,5 +46,5 @@ declare void @_Z7CapturePi(ptr)
 ; WINDOWS-ARM64EC: bl "#_Z7CapturePi"
 ; WINDOWS-ARM64EC: ldr x8, [sp, #8]
 ; WINDOWS-ARM64EC: mov x9, sp
-; WINDOWS-ARM64EC: add x0, x8, x9
+; WINDOWS-ARM64EC: add x0, x9, x8
 ; WINDOWS-ARM64EC: bl "#__security_check_cookie_arm64ec"

>From b9ae3ff1b34af5c3fbcb5a5e9011ba6c40975a30 Mon Sep 17 00:00:00 2001
From: "Pan, Tao" <tao.pan at intel.com>
Date: Tue, 18 Nov 2025 15:59:31 +0800
Subject: [PATCH 10/11] Remove the extra instruction that copy from sp

---
 llvm/lib/Target/AArch64/AArch64ISelLowering.cpp     | 4 +---
 llvm/test/CodeGen/AArch64/stack-protector-target.ll | 6 ++----
 2 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 590efff1b5612..b63a623975911 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -29255,9 +29255,7 @@ SDValue AArch64TargetLowering::emitStackGuardMixCookie(SelectionDAG &DAG,
   if (FailureBB) {
     return DAG.getNode(
         ISD::ADD, DL, Val.getValueType(),
-        DAG.getCopyFromReg(DAG.getEntryNode(), DL,
-                           getStackPointerRegisterToSaveRestore(), MVT::i64),
-        Val);
+        DAG.getRegister(getStackPointerRegisterToSaveRestore(), MVT::i64), Val);
   }
   return Val;
 }
diff --git a/llvm/test/CodeGen/AArch64/stack-protector-target.ll b/llvm/test/CodeGen/AArch64/stack-protector-target.ll
index 821aebe702537..98ffaf830b495 100644
--- a/llvm/test/CodeGen/AArch64/stack-protector-target.ll
+++ b/llvm/test/CodeGen/AArch64/stack-protector-target.ll
@@ -35,8 +35,7 @@ declare void @_Z7CapturePi(ptr)
 ; WINDOWS-AARCH64: str x8, [sp, #8]
 ; WINDOWS-AARCH64: bl  _Z7CapturePi
 ; WINDOWS-AARCH64: ldr x8, [sp, #8]
-; WINDOWS-AARCH64: mov x9, sp
-; WINDOWS-AARCH64: add x0, x9, x8
+; WINDOWS-AARCH64: add x0, sp, x8
 ; WINDOWS-AARCH64: bl  __security_check_cookie
 
 ; WINDOWS-ARM64EC: adrp x8, __security_cookie
@@ -45,6 +44,5 @@ declare void @_Z7CapturePi(ptr)
 ; WINDOWS-ARM64EC: str x8, [sp, #8]
 ; WINDOWS-ARM64EC: bl "#_Z7CapturePi"
 ; WINDOWS-ARM64EC: ldr x8, [sp, #8]
-; WINDOWS-ARM64EC: mov x9, sp
-; WINDOWS-ARM64EC: add x0, x9, x8
+; WINDOWS-ARM64EC: add x0, sp, x8
 ; WINDOWS-ARM64EC: bl "#__security_check_cookie_arm64ec"

>From bb1bf3094cbcdcf6595dc38ad11d68b7832bb573 Mon Sep 17 00:00:00 2001
From: "Pan, Tao" <tao.pan at intel.com>
Date: Tue, 18 Nov 2025 22:30:01 +0800
Subject: [PATCH 11/11] rebase

---
 .../CodeGen/AArch64/arm64ec-indirect-call.ll  |  1 +
 llvm/test/CodeGen/AArch64/mingw-refptr.ll     | 30 ++++++++-----------
 2 files changed, 14 insertions(+), 17 deletions(-)

diff --git a/llvm/test/CodeGen/AArch64/arm64ec-indirect-call.ll b/llvm/test/CodeGen/AArch64/arm64ec-indirect-call.ll
index e6a42c382e4f6..50e563847b853 100644
--- a/llvm/test/CodeGen/AArch64/arm64ec-indirect-call.ll
+++ b/llvm/test/CodeGen/AArch64/arm64ec-indirect-call.ll
@@ -32,6 +32,7 @@ define void @stackguard(ptr %g) sspreq {
 ; CHECK-NEXT:     adrp    x8, __security_cookie
 ; CHECK-NEXT:     ldr     x10, [sp, #8]
 ; CHECK-NEXT:     ldr     x8, [x8, :lo12:__security_cookie]
+; CHECK-NEXT:     sub     x8, sp, x8
 ; CHECK-NEXT:     cmp     x8, x10
 ; CHECK-NEXT:     b.ne    .LBB1_2
 ; CHECK-NEXT: // %bb.1:
diff --git a/llvm/test/CodeGen/AArch64/mingw-refptr.ll b/llvm/test/CodeGen/AArch64/mingw-refptr.ll
index 4a203d74876a7..c36ec51b2b320 100644
--- a/llvm/test/CodeGen/AArch64/mingw-refptr.ll
+++ b/llvm/test/CodeGen/AArch64/mingw-refptr.ll
@@ -118,31 +118,27 @@ define dso_local void @sspFunc() #0 {
 ; CHECK-NEXT:  // %bb.0: // %entry
 ; CHECK-NEXT:    sub sp, sp, #32
 ; CHECK-NEXT:    .seh_stackalloc 32
-; CHECK-NEXT:    str x19, [sp, #16] // 8-byte Spill
-; CHECK-NEXT:    .seh_save_reg x19, 16
-; CHECK-NEXT:    str x30, [sp, #24] // 8-byte Spill
-; CHECK-NEXT:    .seh_save_reg x30, 24
+; CHECK-NEXT:    str x30, [sp, #16] // 8-byte Spill
+; CHECK-NEXT:    .seh_save_reg x30, 16
 ; CHECK-NEXT:    .seh_endprologue
-; CHECK-NEXT:    adrp x19, .refptr.__stack_chk_guard
-; CHECK-NEXT:    mov x9, sp
+; CHECK-NEXT:    adrp x8, .refptr.__stack_chk_guard
 ; CHECK-NEXT:    add x0, sp, #7
-; CHECK-NEXT:    ldr x19, [x19, :lo12:.refptr.__stack_chk_guard]
-; CHECK-NEXT:    ldr x8, [x19]
-; CHECK-NEXT:    eor x8, x8, x9
+; CHECK-NEXT:    ldr x8, [x8, :lo12:.refptr.__stack_chk_guard]
+; CHECK-NEXT:    ldr x8, [x8]
+; CHECK-NEXT:    sub x8, sp, x8
 ; CHECK-NEXT:    str x8, [sp, #8]
 ; CHECK-NEXT:    bl ptrUser
+; CHECK-NEXT:    adrp x8, .refptr.__stack_chk_guard
+; CHECK-NEXT:    ldr x8, [x8, :lo12:.refptr.__stack_chk_guard]
 ; CHECK-NEXT:    ldr x9, [sp, #8]
-; CHECK-NEXT:    mov x8, sp
-; CHECK-NEXT:    ldr x10, [x19]
-; CHECK-NEXT:    eor x8, x9, x8
-; CHECK-NEXT:    cmp x10, x8
+; CHECK-NEXT:    ldr x8, [x8]
+; CHECK-NEXT:    sub x8, sp, x8
+; CHECK-NEXT:    cmp x8, x9
 ; CHECK-NEXT:    b.ne .LBB6_2
 ; CHECK-NEXT:  // %bb.1: // %entry
 ; CHECK-NEXT:    .seh_startepilogue
-; CHECK-NEXT:    ldr x30, [sp, #24] // 8-byte Reload
-; CHECK-NEXT:    .seh_save_reg x30, 24
-; CHECK-NEXT:    ldr x19, [sp, #16] // 8-byte Reload
-; CHECK-NEXT:    .seh_save_reg x19, 16
+; CHECK-NEXT:    ldr x30, [sp, #16] // 8-byte Reload
+; CHECK-NEXT:    .seh_save_reg x30, 16
 ; CHECK-NEXT:    add sp, sp, #32
 ; CHECK-NEXT:    .seh_stackalloc 32
 ; CHECK-NEXT:    .seh_endepilogue



More information about the llvm-commits mailing list