From 9c6d4c7ef323e45a8171b63517e05a510aef1f84 Mon Sep 17 00:00:00 2001 From: "Pan, Tao" Date: Mon, 29 Sep 2025 09:43:17 +0800 Subject: [PATCH 01/23] [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 a4c1e265f0e63..fffc060bbe7cd 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -28818,7 +28818,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 d8072d15853ee..8073b0677a11b 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h @@ -349,6 +349,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 00ddddafaed3c5550750f1cc0e3251dc609df8b7 Mon Sep 17 00:00:00 2001 From: "Pan, Tao" Date: Mon, 29 Sep 2025 15:21:25 +0800 Subject: [PATCH 02/23] 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 a722b5f42fa65..59f5cca45fb45 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -29101,9 +29101,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 5c230aecd2bd8c18f0f1ccae16e75a15f62c9b32 Mon Sep 17 00:00:00 2001 From: "Pan, Tao" Date: Fri, 10 Oct 2025 08:58:21 +0800 Subject: [PATCH 03/23] 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 59f5cca45fb45..2ce9282c4156b 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -29093,10 +29093,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 12ded1eb51a757fee5229186589fc00b7cb38a76 Mon Sep 17 00:00:00 2001 From: "Pan, Tao" Date: Thu, 16 Oct 2025 09:09:33 +0800 Subject: [PATCH 04/23] 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 2ce9282c4156b..60aa61e993b26 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -29093,25 +29093,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 fe6ccdc5947fe..2cb8ed29f252a 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h @@ -358,9 +358,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 457e5402e0f46..ed1d9639500df 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -2310,6 +2310,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 23fbbbbf5e52dcdb04774f2d1041eba42df7cd1a Mon Sep 17 00:00:00 2001 From: "Pan, Tao" Date: Thu, 16 Oct 2025 14:17:29 +0800 Subject: [PATCH 05/23] 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 ed1d9639500df..8bc65f8b4c575 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -2310,14 +2310,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 c61707ae9c8a92770b66b28f4a8b3bd55d3708bc Mon Sep 17 00:00:00 2001 From: "Pan, Tao" Date: Fri, 17 Oct 2025 09:45:22 +0800 Subject: [PATCH 06/23] 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 1920b98c8a1ef..3dbae93c76efd 100644 --- a/llvm/include/llvm/CodeGen/TargetLowering.h +++ b/llvm/include/llvm/CodeGen/TargetLowering.h @@ -5798,7 +5798,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 a52265055c88a..d12a46ebfe66c 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 @@ -7381,7 +7381,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 60aa61e993b26..a8e98d92771a2 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -29096,6 +29096,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 2cb8ed29f252a..405a0103f1944 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h @@ -358,6 +358,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 5785440a20e43..4420cf628962a 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 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 2b02cb2b8d25c2ec222536d609f8cc4e40d24699 Mon Sep 17 00:00:00 2001 From: "Pan, Tao" Date: Tue, 21 Oct 2025 09:17:57 +0800 Subject: [PATCH 07/23] 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 a8e98d92771a2..37b9c01d730d3 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -29099,7 +29099,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 8bc65f8b4c575..312c159748cda 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -2316,7 +2316,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 823bd2f250d8d0ab9778a66aa2741fb1597a7ee7 Mon Sep 17 00:00:00 2001 From: "Pan, Tao" Date: Mon, 3 Nov 2025 12:44:48 +0800 Subject: [PATCH 08/23] 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 3dbae93c76efd..3eb39ca083416 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, @@ -5797,8 +5796,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 1fc90d0852aad..75c233f08f03d 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -3934,8 +3934,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 d12a46ebfe66c..62880dac62657 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 @@ -7380,8 +7380,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 2a8234a37a167..346f9eecb9af9 100644 --- a/llvm/lib/CodeGen/StackProtector.cpp +++ b/llvm/lib/CodeGen/StackProtector.cpp @@ -577,7 +577,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 37b9c01d730d3..4f5b6ebaf1917 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -29096,18 +29096,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 405a0103f1944..46057e2d89979 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h @@ -358,9 +358,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 312c159748cda..091608abcef74 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -2316,9 +2316,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 4420cf628962a..1aad8b694a107 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -2733,14 +2733,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 fb95d945b8e22..5689fcf7997ce 100644 --- a/llvm/test/CodeGen/AArch64/mingw-refptr.ll +++ b/llvm/test/CodeGen/AArch64/mingw-refptr.ll @@ -89,14 +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: 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 9f95a652e41460a2d784582ec5bfb854e84e52b0 Mon Sep 17 00:00:00 2001 From: "Pan, Tao" Date: Fri, 14 Nov 2025 14:52:10 +0800 Subject: [PATCH 09/23] 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 | 71 ++++++++++++++++++- .../CodeGen/AArch64/stack-protector-target.ll | 4 +- 3 files changed, 75 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index 4f5b6ebaf1917..f536532535a1c 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -29108,9 +29108,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 5689fcf7997ce..c8e30f0cf8d19 100644 --- a/llvm/test/CodeGen/AArch64/mingw-refptr.ll +++ b/llvm/test/CodeGen/AArch64/mingw-refptr.ll @@ -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 @@ -112,6 +148,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 Folded 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 Folded 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) @@ -136,5 +206,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 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 6606db97307f61f1da61884c40c7aefc91443a66 Mon Sep 17 00:00:00 2001 From: "Pan, Tao" Date: Tue, 18 Nov 2025 15:59:31 +0800 Subject: [PATCH 10/23] 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 f536532535a1c..b1ad653dea160 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -29109,9 +29109,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 c27d13d6e4836fcfac7e79ceb8b2563b5a13779d Mon Sep 17 00:00:00 2001 From: "Pan, Tao" Date: Mon, 29 Sep 2025 09:43:17 +0800 Subject: [PATCH 11/23] [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" Date: Mon, 29 Sep 2025 15:21:25 +0800 Subject: [PATCH 12/23] 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" Date: Fri, 10 Oct 2025 08:58:21 +0800 Subject: [PATCH 13/23] 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" Date: Thu, 16 Oct 2025 09:09:33 +0800 Subject: [PATCH 14/23] 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" Date: Thu, 16 Oct 2025 14:17:29 +0800 Subject: [PATCH 15/23] 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" Date: Fri, 17 Oct 2025 09:45:22 +0800 Subject: [PATCH 16/23] 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" Date: Tue, 21 Oct 2025 09:17:57 +0800 Subject: [PATCH 17/23] 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" Date: Mon, 3 Nov 2025 12:44:48 +0800 Subject: [PATCH 18/23] 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" Date: Fri, 14 Nov 2025 14:52:10 +0800 Subject: [PATCH 19/23] 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" Date: Tue, 18 Nov 2025 15:59:31 +0800 Subject: [PATCH 20/23] 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" Date: Tue, 18 Nov 2025 22:30:01 +0800 Subject: [PATCH 21/23] 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 From b41ab4272f6cce118fb511ce48c61a16c36d9965 Mon Sep 17 00:00:00 2001 From: "Pan, Tao" Date: Wed, 26 Nov 2025 16:18:49 +0800 Subject: [PATCH 22/23] Add add_uxtx complex pattern, SUBXrr -> SUBXrx64, re-generate mingw-refptr.ll --- llvm/include/llvm/CodeGen/SelectionDAG.h | 4 - .../Target/AArch64/AArch64ISelDAGToDAG.cpp | 14 +++ .../Target/AArch64/AArch64ISelLowering.cpp | 10 +- .../lib/Target/AArch64/AArch64InstrFormats.td | 2 + llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | 5 +- llvm/lib/Target/AArch64/AArch64InstrInfo.td | 5 + llvm/test/CodeGen/AArch64/mingw-refptr.ll | 110 ++++++------------ 7 files changed, 66 insertions(+), 84 deletions(-) diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h index 12d79e7c39c20..b024e8a68bd6e 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAG.h +++ b/llvm/include/llvm/CodeGen/SelectionDAG.h @@ -853,10 +853,6 @@ class SelectionDAG { ArrayRef(Ops, Glue.getNode() ? 3 : 2)); } - SDValue getAddToReg(const SDLoc &dl, Register Reg, EVT VT, SDValue Delta) { - return getNode(ISD::ADD, dl, VT, getRegister(Reg, VT), Delta); - } - LLVM_ABI SDValue getCondCode(ISD::CondCode Cond); /// Return an ISD::VECTOR_SHUFFLE node. The number of elements in VT, diff --git a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp index 08466667c0fa5..6a64440c9ae09 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp @@ -74,6 +74,8 @@ class AArch64DAGToDAGISel : public SelectionDAGISel { template bool SelectRDSVLShiftImm(SDValue N, SDValue &Imm); + bool SelectAddUXTXRegister(SDValue N, SDValue &Reg, SDValue &Shift); + bool SelectArithExtendedRegister(SDValue N, SDValue &Reg, SDValue &Shift); bool SelectArithUXTXRegister(SDValue N, SDValue &Reg, SDValue &Shift); bool SelectArithImmed(SDValue N, SDValue &Val, SDValue &Shift); @@ -959,6 +961,18 @@ bool AArch64DAGToDAGISel::SelectRDSVLShiftImm(SDValue N, SDValue &Imm) { return false; } +/// SelectAddUXTXRegister - Select a "UXTX register" operand. This +/// operand is referred by the instructions have SP operand +bool AArch64DAGToDAGISel::SelectAddUXTXRegister(SDValue N, SDValue &Reg, + SDValue &Shift) { + if (N.getOpcode() != ISD::LOAD) + return false; + Reg = N; + Shift = CurDAG->getTargetConstant(getArithExtendImm(AArch64_AM::UXTX, 0), + SDLoc(N), MVT::i32); + return true; +} + /// SelectArithExtendedRegister - Select a "extended register" operand. This /// operand folds in an extend followed by an optional left shift. bool AArch64DAGToDAGISel::SelectArithExtendedRegister(SDValue N, SDValue &Reg, diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index 70c048a731dd1..0e11b8c8c4e28 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -29252,10 +29252,12 @@ SDValue AArch64TargetLowering::emitStackGuardMixCookie(SelectionDAG &DAG, SDValue Val, const SDLoc &DL, bool FailureBB) const { - if (FailureBB) { - return DAG.getAddToReg(DL, getStackPointerRegisterToSaveRestore(), MVT::i64, - Val); - } + if (FailureBB) + return DAG.getNode( + ISD::ADD, DL, Val.getValueType(), + DAG.getCopyFromReg(DAG.getEntryNode(), DL, + getStackPointerRegisterToSaveRestore(), MVT::i64), + Val); return Val; } diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td index 6871c2d504cf6..f1a3239d7d248 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td +++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td @@ -1386,6 +1386,8 @@ def gi_arith_extended_reg32to64_i64 : def arith_uxtx : ComplexPattern; +def add_uxtx : ComplexPattern; + // Floating-point immediate. def fpimm16XForm : SDNodeXFormgetTargetMachine() .Options.EnableGlobalISel) { - BuildMI(MBB, MI, DL, get(AArch64::SUBXrr), Reg) + BuildMI(MBB, MI, DL, get(AArch64::SUBXrx64), Reg) .addReg(AArch64::SP) - .addReg(Reg, RegState::Kill); + .addReg(Reg, RegState::Kill) + .addImm(AArch64_AM::getArithExtendImm(AArch64_AM::UXTX, 0)); } MBB.erase(MI); diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index 50a3a4ab8d8b6..e6fce474a4f89 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -2752,6 +2752,11 @@ def : Pat<(AArch64sub_flag GPR64:$Rn, neg_addsub_shifted_imm64:$imm), (ADDSXri GPR64:$Rn, neg_addsub_shifted_imm64:$imm)>; } +let AddedComplexity = 1 in { +def : Pat<(add copyFromSP:$R2, (add_uxtx GPR64:$R3, arith_extendlsl64:$imm)), + (ADDXrx64 GPR64sp:$R2, GPR64:$R3, arith_extendlsl64:$imm)>; +} + def : InstAlias<"neg $dst, $src", (SUBWrs GPR32:$dst, WZR, (arith_shifted_reg32 GPR32:$src, 0)), 3>; diff --git a/llvm/test/CodeGen/AArch64/mingw-refptr.ll b/llvm/test/CodeGen/AArch64/mingw-refptr.ll index c36ec51b2b320..286039ce1e856 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 @@ -15,13 +15,6 @@ 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 @@ -33,12 +26,6 @@ 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 @@ -50,12 +37,6 @@ 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 @@ -67,12 +48,6 @@ 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 @@ -85,13 +60,6 @@ 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 @@ -101,10 +69,6 @@ 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 @@ -113,41 +77,41 @@ entry: declare dso_local void @otherFunc() define dso_local void @sspFunc() #0 { -; CHECK-LABEL: sspFunc: -; CHECK: .seh_proc sspFunc -; 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: .seh_endprologue -; CHECK-NEXT: adrp x8, .refptr.__stack_chk_guard -; 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: 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: 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: add sp, sp, #32 -; CHECK-NEXT: .seh_stackalloc 32 -; CHECK-NEXT: .seh_endepilogue -; CHECK-NEXT: ret -; CHECK-NEXT: .LBB6_2: // %entry -; CHECK-NEXT: bl __stack_chk_fail -; CHECK-NEXT: brk #0x1 -; CHECK-NEXT: .seh_endfunclet -; CHECK-NEXT: .seh_endproc +; CHECK-SD-LABEL: sspFunc: +; CHECK-SD: .seh_proc sspFunc +; CHECK-SD-NEXT: // %bb.0: // %entry +; CHECK-SD-NEXT: sub sp, sp, #32 +; CHECK-SD-NEXT: .seh_stackalloc 32 +; CHECK-SD-NEXT: str x30, [sp, #16] // 8-byte Spill +; CHECK-SD-NEXT: .seh_save_reg x30, 16 +; CHECK-SD-NEXT: .seh_endprologue +; CHECK-SD-NEXT: adrp x8, .refptr.__stack_chk_guard +; CHECK-SD-NEXT: add x0, sp, #7 +; CHECK-SD-NEXT: ldr x8, [x8, :lo12:.refptr.__stack_chk_guard] +; CHECK-SD-NEXT: ldr x8, [x8] +; CHECK-SD-NEXT: sub x8, sp, x8 +; CHECK-SD-NEXT: str x8, [sp, #8] +; CHECK-SD-NEXT: bl ptrUser +; CHECK-SD-NEXT: adrp x8, .refptr.__stack_chk_guard +; CHECK-SD-NEXT: ldr x8, [x8, :lo12:.refptr.__stack_chk_guard] +; CHECK-SD-NEXT: ldr x9, [sp, #8] +; CHECK-SD-NEXT: ldr x8, [x8] +; CHECK-SD-NEXT: sub x8, sp, x8 +; CHECK-SD-NEXT: cmp x8, x9 +; CHECK-SD-NEXT: b.ne .LBB6_2 +; CHECK-SD-NEXT: // %bb.1: // %entry +; CHECK-SD-NEXT: .seh_startepilogue +; CHECK-SD-NEXT: ldr x30, [sp, #16] // 8-byte Reload +; CHECK-SD-NEXT: .seh_save_reg x30, 16 +; CHECK-SD-NEXT: add sp, sp, #32 +; CHECK-SD-NEXT: .seh_stackalloc 32 +; CHECK-SD-NEXT: .seh_endepilogue +; CHECK-SD-NEXT: ret +; CHECK-SD-NEXT: .LBB6_2: // %entry +; CHECK-SD-NEXT: bl __stack_chk_fail +; CHECK-SD-NEXT: brk #0x1 +; CHECK-SD-NEXT: .seh_endfunclet +; CHECK-SD-NEXT: .seh_endproc ; ; CHECK-GI-LABEL: sspFunc: ; CHECK-GI: .seh_proc sspFunc @@ -205,5 +169,3 @@ attributes #0 = { sspstrong } ; CHECK: .refptr.var: ; CHECK: .xword var -;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: -; CHECK-SD: {{.*}} From 5076be45b0d0a6a57ca60e5bb37f4bfd45552866 Mon Sep 17 00:00:00 2001 From: "Pan, Tao" Date: Thu, 27 Nov 2025 13:07:29 +0800 Subject: [PATCH 23/23] Add more comment --- llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp index 0018e2ba78355..6325ff7de4e18 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -2497,7 +2497,9 @@ bool AArch64InstrInfo::expandPostRAPseudo(MachineInstr &MI) const { .addMemOperand(*MI.memoperands_begin()); } } - // To match MSVC + // To match MSVC. Unlike x86_64 which uses xor instruction to mix the cookie, + // we use sub instruction to mix the cookie on aarch64 for keeping the + // existing inlining logic intact. if (Subtarget.getTargetTriple().isOSMSVCRT() && !Subtarget.getTargetLowering() ->getTargetMachine()