diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h index 88691b931a8d8..fd697a6ead3e9 100644 --- a/llvm/include/llvm/CodeGen/TargetLowering.h +++ b/llvm/include/llvm/CodeGen/TargetLowering.h @@ -5770,7 +5770,7 @@ class LLVM_ABI TargetLowering : public TargetLoweringBase { virtual bool useLoadStackGuardNode(const Module &M) const { return false; } virtual SDValue emitStackGuardXorFP(SelectionDAG &DAG, SDValue Val, - const SDLoc &DL) const { + const SDLoc &DL, bool FailureBB) const { llvm_unreachable("not implemented for this target"); } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index c21890a0d856f..649866de4e097 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -3087,7 +3087,7 @@ void SelectionDAGBuilder::visitSPDescriptorParent(StackProtectorDescriptor &SPD, MachineMemOperand::MOVolatile); if (TLI.useStackGuardXorFP()) - GuardVal = TLI.emitStackGuardXorFP(DAG, GuardVal, dl); + GuardVal = TLI.emitStackGuardXorFP(DAG, GuardVal, dl, false); // If we're using function-based instrumentation, call the guard check // function @@ -3192,7 +3192,7 @@ void SelectionDAGBuilder::visitSPDescriptorFailure( MachineMemOperand::MOVolatile); if (TLI.useStackGuardXorFP()) - GuardVal = TLI.emitStackGuardXorFP(DAG, GuardVal, dl); + GuardVal = TLI.emitStackGuardXorFP(DAG, GuardVal, dl, true); // The target provides a guard check function to validate the guard value. // Generate a call to that function with the content of the guard slot as @@ -7354,7 +7354,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, MachineMemOperand::MOVolatile); } if (TLI.useStackGuardXorFP()) - Res = TLI.emitStackGuardXorFP(DAG, Res, sdl); + Res = TLI.emitStackGuardXorFP(DAG, Res, sdl, false); DAG.setRoot(Chain); setValue(&I, Res); return; diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index 31b3d1807933b..dc3410933342a 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -28968,6 +28968,24 @@ 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() && + !getTargetMachine().Options.EnableGlobalISel; +} + +SDValue AArch64TargetLowering::emitStackGuardXorFP(SelectionDAG &DAG, + SDValue Val, const SDLoc &DL, + bool FailureBB) const { + if (FailureBB) { + return DAG.getNode( + ISD::XOR, DL, Val.getValueType(), Val, + DAG.getCopyFromReg(DAG.getEntryNode(), DL, + getStackPointerRegisterToSaveRestore(), MVT::i64)); + } + return Val; +} + unsigned AArch64TargetLowering::combineRepeatedFPDivisors() const { // Combine multiple FDIVs with the same divisor into multiple FMULs by the // reciprocal if there are three or more FDIVs. diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h index e472e7d565d9b..6339f94a7fd94 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h @@ -359,6 +359,9 @@ class AArch64TargetLowering : public TargetLowering { shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const override; bool useLoadStackGuardNode(const Module &M) const override; + bool useStackGuardXorFP() const override; + SDValue emitStackGuardXorFP(SelectionDAG &DAG, SDValue Val, const SDLoc &DL, + bool FailureBB) const override; TargetLoweringBase::LegalizeTypeAction getPreferredVectorAction(MVT VT) const override; diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp index b8761d971a67d..afcbccd1fa149 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -2276,6 +2276,15 @@ bool AArch64InstrInfo::expandPostRAPseudo(MachineInstr &MI) const { .addMemOperand(*MI.memoperands_begin()); } } + // To match MSVC + if (Subtarget.getTargetTriple().isOSMSVCRT() && + !Subtarget.getTargetLowering() + ->getTargetMachine() + .Options.EnableGlobalISel) { + BuildMI(MBB, MI, DL, get(AArch64::EORXrr), Reg) + .addReg(Reg, RegState::Kill) + .addReg(AArch64::SP); + } MBB.erase(MI); diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 9580adebba712..66f22f8aa8bf9 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -2739,7 +2739,8 @@ bool X86TargetLowering::useStackGuardXorFP() const { } SDValue X86TargetLowering::emitStackGuardXorFP(SelectionDAG &DAG, SDValue Val, - const SDLoc &DL) const { + const SDLoc &DL, + bool FailureBB) const { EVT PtrTy = getPointerTy(DAG.getDataLayout()); unsigned XorOp = Subtarget.is64Bit() ? X86::XOR64_FP : X86::XOR32_FP; MachineSDNode *Node = DAG.getMachineNode(XorOp, DL, PtrTy, Val); diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h index b55556aadd867..3840b9bdf0502 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.h +++ b/llvm/lib/Target/X86/X86ISelLowering.h @@ -1594,9 +1594,8 @@ namespace llvm { bool useStackGuardXorFP() const override; void insertSSPDeclarations(Module &M) const override; Function *getSSPStackGuardCheck(const Module &M) const override; - SDValue emitStackGuardXorFP(SelectionDAG &DAG, SDValue Val, - const SDLoc &DL) const override; - + SDValue emitStackGuardXorFP(SelectionDAG &DAG, SDValue Val, const SDLoc &DL, + bool FailureBB) const override; /// Return true if the target stores SafeStack pointer at a fixed offset in /// some non-standard address space, and populates the address space and diff --git a/llvm/test/CodeGen/AArch64/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 diff --git a/llvm/test/CodeGen/AArch64/stack-protector-target.ll b/llvm/test/CodeGen/AArch64/stack-protector-target.ll index b1ddd1d0d160f..201950a6355a3 100644 --- a/llvm/test/CodeGen/AArch64/stack-protector-target.ll +++ b/llvm/test/CodeGen/AArch64/stack-protector-target.ll @@ -31,14 +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: 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 ; 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 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"