From 713fc3b3618156a3acf7445034365d98e6bcf39d Mon Sep 17 00:00:00 2001 From: "Pan, Tao" Date: Mon, 29 Sep 2025 09:43:17 +0800 Subject: [PATCH 1/7] [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 31b3d1807933b..e542c5c56e6fb 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -28965,7 +28965,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 e472e7d565d9b..63ba5f94ccbec 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h @@ -359,6 +359,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 d3b1aa621b61a..163de52386221 100644 --- a/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp @@ -32,7 +32,7 @@ AArch64SelectionDAGInfo::AArch64SelectionDAGInfo() void AArch64SelectionDAGInfo::verifyTargetNode(const SelectionDAG &DAG, const SDNode *N) const { - SelectionDAGGenTargetInfo::verifyTargetNode(DAG, N); + // SelectionDAGGenTargetInfo::verifyTargetNode(DAG, N); #ifndef NDEBUG // Some additional checks not yet implemented by verifyTargetNode. From a33d03e1cd38a1ffa6fe3836eb47518d128b49d3 Mon Sep 17 00:00:00 2001 From: "Pan, Tao" Date: Mon, 29 Sep 2025 15:21:25 +0800 Subject: [PATCH 2/7] 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 e542c5c56e6fb..1e91d4555b9c5 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -28973,9 +28973,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 309524a3dcd8e9f3f5edb55c1b39ec648468c944 Mon Sep 17 00:00:00 2001 From: "Pan, Tao" Date: Fri, 10 Oct 2025 08:58:21 +0800 Subject: [PATCH 3/7] Fix failed tests --- .../Target/AArch64/AArch64ISelLowering.cpp | 11 +++++-- llvm/test/CodeGen/AArch64/mingw-refptr.ll | 30 +++++++++++-------- .../CodeGen/AArch64/stack-protector-target.ll | 12 ++++---- 3 files changed, 33 insertions(+), 20 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index 1e91d4555b9c5..8739d98b10260 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -28965,10 +28965,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 cc9fac0506ff5..445888845f001 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 @@ -82,25 +82,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 Folded Spill +; CHECK-NEXT: .seh_save_reg x19, 16 +; CHECK-NEXT: str x30, [sp, #24] // 8-byte Folded 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 Folded Reload -; CHECK-NEXT: .seh_save_reg x30, 16 +; CHECK-NEXT: ldr x30, [sp, #24] // 8-byte Folded Reload +; CHECK-NEXT: .seh_save_reg x30, 24 +; CHECK-NEXT: ldr x19, [sp, #16] // 8-byte Folded 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 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 6469adcdc3f8f10192059af539bd37d7f4865d4d Mon Sep 17 00:00:00 2001 From: "Pan, Tao" Date: Thu, 16 Oct 2025 09:09:33 +0800 Subject: [PATCH 4/7] 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 8739d98b10260..31b3d1807933b 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -28965,25 +28965,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 63ba5f94ccbec..e472e7d565d9b 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h @@ -359,9 +359,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 b8761d971a67d..c19a7aaa7171c 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -2275,6 +2275,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 163de52386221..d3b1aa621b61a 100644 --- a/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp @@ -32,7 +32,7 @@ AArch64SelectionDAGInfo::AArch64SelectionDAGInfo() void AArch64SelectionDAGInfo::verifyTargetNode(const SelectionDAG &DAG, const SDNode *N) const { - // 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 445888845f001..cc9fac0506ff5 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 @@ -82,31 +82,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 Folded Spill -; CHECK-NEXT: .seh_save_reg x19, 16 -; CHECK-NEXT: str x30, [sp, #24] // 8-byte Folded 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 Folded Reload -; CHECK-NEXT: .seh_save_reg x30, 24 -; CHECK-NEXT: ldr x19, [sp, #16] // 8-byte Folded 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 9dfdc66624435962a57cf8053283070fff5864c2 Mon Sep 17 00:00:00 2001 From: "Pan, Tao" Date: Thu, 16 Oct 2025 14:17:29 +0800 Subject: [PATCH 5/7] 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 c19a7aaa7171c..aa75f1e81ddeb 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -2275,14 +2275,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 cc9fac0506ff5..fb95d945b8e22 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 @@ -89,12 +89,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 ba7a7c683281526cd4133cc6e5d77e0c8b680ccb Mon Sep 17 00:00:00 2001 From: "Pan, Tao" Date: Fri, 17 Oct 2025 09:45:22 +0800 Subject: [PATCH 6/7] 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 88691b931a8d8..fd697a6ead3e9 100644 --- a/llvm/include/llvm/CodeGen/TargetLowering.h +++ b/llvm/include/llvm/CodeGen/TargetLowering.h @@ -5770,7 +5770,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 c21890a0d856f..649866de4e097 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -3087,7 +3087,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 @@ -3192,7 +3192,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 @@ -7354,7 +7354,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 31b3d1807933b..67d69efb6e6eb 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -28968,6 +28968,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 e472e7d565d9b..6339f94a7fd94 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h @@ -359,6 +359,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 9580adebba712..66f22f8aa8bf9 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -2739,7 +2739,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 b55556aadd867..3840b9bdf0502 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.h +++ b/llvm/lib/Target/X86/X86ISelLowering.h @@ -1594,9 +1594,8 @@ namespace llvm { bool useStackGuardXorFP() const override; void insertSSPDeclarations(Module &M) const override; Function *getSSPStackGuardCheck(const 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 f273fa9cd4cc437f12f6d970369fcf5ba1f83d16 Mon Sep 17 00:00:00 2001 From: "Pan, Tao" Date: Tue, 21 Oct 2025 09:17:57 +0800 Subject: [PATCH 7/7] 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 67d69efb6e6eb..dc3410933342a 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -28971,7 +28971,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 aa75f1e81ddeb..afcbccd1fa149 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -2281,7 +2281,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); }