Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
9c6d4c7
[aarch64] XOR the frame pointer with the stack cookie when protecting…
PanTao2 Sep 29, 2025
da07652
Merge branch 'main' of https://github.com/llvm/llvm-project
PanTao2 Oct 29, 2025
00dddda
Change DAG.getRegister to DAG.getCopyFromReg
PanTao2 Sep 29, 2025
5c230ae
Fix failed tests
PanTao2 Oct 10, 2025
12ded1e
Add the EOR instruction in AArch64InstrInfo::expandPostRAPseudo
PanTao2 Oct 16, 2025
23fbbbb
Add the eor instruction to any code model
PanTao2 Oct 16, 2025
c61707a
Add the eor instruction in the failure BB
PanTao2 Oct 17, 2025
2b02cb2
Remove the isTargetMachO() check and change EORWrr to EORXrr
PanTao2 Oct 21, 2025
823bd2f
Change the mixed instruction from xor to sub and change interface nam…
PanTao2 Nov 3, 2025
9f95a65
Commute the operands of the add and regenerate mingw-refptr.ll with u…
PanTao2 Nov 14, 2025
6606db9
Remove the extra instruction that copy from sp
PanTao2 Nov 18, 2025
c27d13d
[aarch64] XOR the frame pointer with the stack cookie when protecting…
PanTao2 Sep 29, 2025
6536678
Change DAG.getRegister to DAG.getCopyFromReg
PanTao2 Sep 29, 2025
4493e86
Fix failed tests
PanTao2 Oct 10, 2025
c5b61ae
Add the EOR instruction in AArch64InstrInfo::expandPostRAPseudo
PanTao2 Oct 16, 2025
2763964
Add the eor instruction to any code model
PanTao2 Oct 16, 2025
414995a
Add the eor instruction in the failure BB
PanTao2 Oct 17, 2025
65acb8c
Remove the isTargetMachO() check and change EORWrr to EORXrr
PanTao2 Oct 21, 2025
df09547
Change the mixed instruction from xor to sub and change interface nam…
PanTao2 Nov 3, 2025
2e737b9
Commute the operands of the add and regenerate mingw-refptr.ll with u…
PanTao2 Nov 14, 2025
b9ae3ff
Remove the extra instruction that copy from sp
PanTao2 Nov 18, 2025
bb1bf30
rebase
PanTao2 Nov 18, 2025
33de52f
Add function getAddToReg to the class SelectionDAG
PanTao2 Nov 25, 2025
b41ab42
Add add_uxtx complex pattern, SUBXrr -> SUBXrx64, re-generate mingw-r…
PanTao2 Nov 26, 2025
36782f4
Fix conflict
PanTao2 Nov 27, 2025
5076be4
Add more comment
PanTao2 Nov 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions llvm/include/llvm/CodeGen/TargetLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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) const {
virtual SDValue emitStackGuardMixCookie(SelectionDAG &DAG, SDValue Val,
const SDLoc &DL,
bool FailureBB) const {
llvm_unreachable("not implemented for this target");
}

Expand Down
5 changes: 3 additions & 2 deletions llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
12 changes: 6 additions & 6 deletions llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
if (TLI.useStackGuardMixCookie())
GuardVal = TLI.emitStackGuardMixCookie(DAG, GuardVal, dl, false);

// If we're using function-based instrumentation, call the guard check
// function
Expand Down Expand Up @@ -3237,8 +3237,8 @@ void SelectionDAGBuilder::visitSPDescriptorFailure(
MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI), Align,
MachineMemOperand::MOVolatile);

if (TLI.useStackGuardXorFP())
GuardVal = TLI.emitStackGuardXorFP(DAG, GuardVal, dl);
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
Expand Down Expand Up @@ -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);
if (TLI.useStackGuardMixCookie())
Res = TLI.emitStackGuardMixCookie(DAG, Res, sdl, false);
DAG.setRoot(Chain);
setValue(&I, Res);
return;
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/StackProtector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
19 changes: 19 additions & 0 deletions llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29096,6 +29096,25 @@ bool AArch64TargetLowering::useLoadStackGuardNode(const Module &M) const {
return true;
}

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::emitStackGuardMixCookie(SelectionDAG &DAG,
SDValue Val,
const SDLoc &DL,
bool FailureBB) const {
if (FailureBB) {
return DAG.getNode(
ISD::ADD, 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.
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/AArch64/AArch64ISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,10 @@ class AArch64TargetLowering : public TargetLowering {
shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const override;

bool useLoadStackGuardNode(const Module &M) 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;

Expand Down
9 changes: 9 additions & 0 deletions llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2311,6 +2311,15 @@ bool AArch64InstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
.addMemOperand(*MI.memoperands_begin());
}
}
// To match MSVC
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe extend this comment a little to explain what exactly we're matching.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please review the added comment?

if (Subtarget.getTargetTriple().isOSMSVCRT() &&
!Subtarget.getTargetLowering()
->getTargetMachine()
.Options.EnableGlobalISel) {
BuildMI(MBB, MI, DL, get(AArch64::SUBXrr), Reg)
.addReg(AArch64::SP)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this actually produce the correct instruction? I'm not sure SP is in the right register class; I suspect you end up subtracting from zero. The wouldn't show up in assembly output, but it would show up in disassembly. (SUBXrx64 can refer to SP this way, though.)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reply here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed SUBXrr to SUBXrx64. Could you please check it?

.addReg(Reg, RegState::Kill);
}

MBB.erase(MI);

Expand Down
7 changes: 4 additions & 3 deletions llvm/lib/Target/X86/X86ISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2733,13 +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) 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);
Expand Down
8 changes: 4 additions & 4 deletions llvm/lib/Target/X86/X86ISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -1590,11 +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) 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
Expand Down
4 changes: 3 additions & 1 deletion llvm/test/CodeGen/AArch64/mingw-refptr.ll
Original file line number Diff line number Diff line change
@@ -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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please regenerate with update_llc_test_checks.py ; don't edit check lines of autogenerated tests by hand.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I regenerate this file with update_llc_test_checks.py.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is update_llc_test_checks.py not happy if you write --check-prefixes=CHECK,CHECK-GI. If that doesn't work, this is fine, I guess.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for making unnecessary changes. I changed it back to --check-prefixes=CHECK,CHECK-GI and regenerated this file.


@var = external local_unnamed_addr global i32, align 4
@dsolocalvar = external dso_local local_unnamed_addr global i32, align 4
Expand Down Expand Up @@ -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: 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
Expand Down
10 changes: 8 additions & 2 deletions llvm/test/CodeGen/AArch64/stack-protector-target.ll
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,20 @@ declare void @_Z7CapturePi(ptr)

; WINDOWS-AARCH64: adrp x8, __security_cookie
; WINDOWS-AARCH64: ldr x8, [x8, :lo12:__security_cookie]
; WINDOWS-AARCH64: sub x8, sp, x8
; 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: add x0, x8, x9
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you commute the operands of the add? add x0, x8, sp is not a legal instruction, but add x0, sp, x8 is legal.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for correcting.

; WINDOWS-AARCH64: bl __security_check_cookie

; WINDOWS-ARM64EC: adrp x8, __security_cookie
; WINDOWS-ARM64EC: ldr x8, [x8, :lo12:__security_cookie]
; WINDOWS-ARM64EC: sub x8, sp, x8
; 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: add x0, x8, x9
; WINDOWS-ARM64EC: bl "#__security_check_cookie_arm64ec"