Skip to content

Commit 2caf85a

Browse files
committed
[ARM] implement LOAD_STACK_GUARD for remaining targets
Currently, LOAD_STACK_GUARD on ARM is only implemented for Mach-O targets, and other targets rely on the generic support which may result in spilling of the stack canary value or address, or may cause it to be kept in a callee save register across function calls, which means they essentially get spilled as well, only by the callee when it wants to free up this register. So let's implement LOAD_STACK GUARD for other targets as well. This ensures that the load of the stack canary is rematerialized fully in the epilogue. This code was split off from D112768: [ARM] implement support for TLS register based stack protector for which it is a prerequisite. Reviewed By: nickdesaulniers Differential Revision: https://reviews.llvm.org/D112811
1 parent 9a3cb73 commit 2caf85a

File tree

9 files changed

+50
-37
lines changed

9 files changed

+50
-37
lines changed

llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1682,8 +1682,6 @@ void ARMBaseInstrInfo::expandMEMCPY(MachineBasicBlock::iterator MI) const {
16821682

16831683
bool ARMBaseInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
16841684
if (MI.getOpcode() == TargetOpcode::LOAD_STACK_GUARD) {
1685-
assert(getSubtarget().getTargetTriple().isOSBinFormatMachO() &&
1686-
"LOAD_STACK_GUARD currently supported only for MachO.");
16871685
expandLoadStackGuard(MI);
16881686
MI.getParent()->erase(MI);
16891687
return true;
@@ -4883,8 +4881,6 @@ bool ARMBaseInstrInfo::verifyInstruction(const MachineInstr &MI,
48834881
return true;
48844882
}
48854883

4886-
// LoadStackGuard has so far only been implemented for MachO. Different code
4887-
// sequence is needed for other targets.
48884884
void ARMBaseInstrInfo::expandLoadStackGuardBase(MachineBasicBlock::iterator MI,
48894885
unsigned LoadImmOpc,
48904886
unsigned LoadOpc) const {
@@ -4896,12 +4892,25 @@ void ARMBaseInstrInfo::expandLoadStackGuardBase(MachineBasicBlock::iterator MI,
48964892
Register Reg = MI->getOperand(0).getReg();
48974893
const GlobalValue *GV =
48984894
cast<GlobalValue>((*MI->memoperands_begin())->getValue());
4895+
bool IsIndirect = Subtarget.isGVIndirectSymbol(GV);
48994896
MachineInstrBuilder MIB;
49004897

4898+
unsigned TargetFlags = ARMII::MO_NO_FLAG;
4899+
if (Subtarget.isTargetMachO()) {
4900+
TargetFlags |= ARMII::MO_NONLAZY;
4901+
} else if (Subtarget.isTargetCOFF()) {
4902+
if (GV->hasDLLImportStorageClass())
4903+
TargetFlags |= ARMII::MO_DLLIMPORT;
4904+
else if (IsIndirect)
4905+
TargetFlags |= ARMII::MO_COFFSTUB;
4906+
} else if (Subtarget.isGVInGOT(GV)) {
4907+
TargetFlags |= ARMII::MO_GOT;
4908+
}
4909+
49014910
BuildMI(MBB, MI, DL, get(LoadImmOpc), Reg)
4902-
.addGlobalAddress(GV, 0, ARMII::MO_NONLAZY);
4911+
.addGlobalAddress(GV, 0, TargetFlags);
49034912

4904-
if (Subtarget.isGVIndirectSymbol(GV)) {
4913+
if (IsIndirect) {
49054914
MIB = BuildMI(MBB, MI, DL, get(LoadOpc), Reg);
49064915
MIB.addReg(Reg, RegState::Kill).addImm(0);
49074916
auto Flags = MachineMemOperand::MOLoad |

llvm/lib/Target/ARM/ARMISelLowering.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20682,10 +20682,7 @@ bool ARMTargetLowering::shouldInsertFencesForAtomic(
2068220682
return InsertFencesForAtomic;
2068320683
}
2068420684

20685-
// This has so far only been implemented for MachO.
20686-
bool ARMTargetLowering::useLoadStackGuardNode() const {
20687-
return Subtarget->isTargetMachO();
20688-
}
20685+
bool ARMTargetLowering::useLoadStackGuardNode() const { return true; }
2068920686

2069020687
void ARMTargetLowering::insertSSPDeclarations(Module &M) const {
2069120688
if (!Subtarget->getTargetTriple().isWindowsMSVCEnvironment())

llvm/lib/Target/ARM/ARMInstrInfo.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,10 @@ void ARMInstrInfo::expandLoadStackGuard(MachineBasicBlock::iterator MI) const {
9696
const ARMSubtarget &Subtarget = MF.getSubtarget<ARMSubtarget>();
9797
const TargetMachine &TM = MF.getTarget();
9898

99-
if (!Subtarget.useMovt()) {
99+
const GlobalValue *GV =
100+
cast<GlobalValue>((*MI->memoperands_begin())->getValue());
101+
102+
if (!Subtarget.useMovt() || Subtarget.isGVInGOT(GV)) {
100103
if (TM.isPositionIndependent())
101104
expandLoadStackGuardBase(MI, ARM::LDRLIT_ga_pcrel, ARM::LDRi12);
102105
else
@@ -109,9 +112,6 @@ void ARMInstrInfo::expandLoadStackGuard(MachineBasicBlock::iterator MI) const {
109112
return;
110113
}
111114

112-
const GlobalValue *GV =
113-
cast<GlobalValue>((*MI->memoperands_begin())->getValue());
114-
115115
if (!Subtarget.isGVIndirectSymbol(GV)) {
116116
expandLoadStackGuardBase(MI, ARM::MOV_ga_pcrel, ARM::LDRi12);
117117
return;

llvm/lib/Target/ARM/Thumb2InstrInfo.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,12 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
250250
void Thumb2InstrInfo::expandLoadStackGuard(
251251
MachineBasicBlock::iterator MI) const {
252252
MachineFunction &MF = *MI->getParent()->getParent();
253-
if (MF.getTarget().isPositionIndependent())
253+
const GlobalValue *GV =
254+
cast<GlobalValue>((*MI->memoperands_begin())->getValue());
255+
256+
if (MF.getSubtarget<ARMSubtarget>().isGVInGOT(GV))
257+
expandLoadStackGuardBase(MI, ARM::tLDRLIT_ga_pcrel, ARM::t2LDRi12);
258+
else if (MF.getTarget().isPositionIndependent())
254259
expandLoadStackGuardBase(MI, ARM::t2MOV_ga_pcrel, ARM::t2LDRi12);
255260
else
256261
expandLoadStackGuardBase(MI, ARM::t2MOVi32imm, ARM::t2LDRi12);

llvm/test/CodeGen/ARM/ssp-data-layout.ll

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@
2121
define void @layout_ssp() ssp {
2222
entry:
2323
; Expected stack layout for ssp is
24-
; 176 large_char . Group 1, nested arrays, arrays >= ssp-buffer-size
25-
; 168 struct_large_char .
26-
; 164 scalar1 | Everything else
27-
; 160 scalar2
28-
; 156 scalar3
29-
; 152 addr-of
30-
; 148 small_nonchar
24+
; 180 large_char . Group 1, nested arrays, arrays >= ssp-buffer-size
25+
; 172 struct_large_char .
26+
; 168 scalar1 | Everything else
27+
; 164 scalar2
28+
; 160 scalar3
29+
; 156 addr-of
30+
; 152 small_nonchar
3131
; 112 large_nonchar
3232
; 110 small_char
3333
; 108 struct_small_char
@@ -37,23 +37,23 @@ entry:
3737
; CHECK: layout_ssp:
3838

3939
; CHECK: bl get_scalar1
40-
; CHECK: str r0, [sp, #164]
40+
; CHECK: str r0, [sp, #168]
4141
; CHECK: bl end_scalar1
4242

4343
; CHECK: bl get_scalar2
44-
; CHECK: str r0, [sp, #160]
45-
; CHECK: bl end_scalar2
44+
; CHECK: str r0, [sp, #164]
45+
; CHECK: bl end_scalar
4646

4747
; CHECK: bl get_scalar3
48-
; CHECK: str r0, [sp, #156]
48+
; CHECK: str r0, [sp, #160]
4949
; CHECK: bl end_scalar3
5050

5151
; CHECK: bl get_addrof
52-
; CHECK: str r0, [sp, #152]
52+
; CHECK: str r0, [sp, #156]
5353
; CHECK: bl end_addrof
5454

5555
; CHECK: get_small_nonchar
56-
; CHECK: strh r0, [sp, #148]
56+
; CHECK: strh r0, [sp, #152]
5757
; CHECK: bl end_small_nonchar
5858

5959
; CHECK: bl get_large_nonchar
@@ -65,11 +65,11 @@ entry:
6565
; CHECK: bl end_small_char
6666

6767
; CHECK: bl get_large_char
68-
; CHECK: strb r0, [sp, #176]
68+
; CHECK: strb r0, [sp, #180]
6969
; CHECK: bl end_large_char
7070

7171
; CHECK: bl get_struct_large_char
72-
; CHECK: strb r0, [sp, #168]
72+
; CHECK: strb r0, [sp, #172]
7373
; CHECK: bl end_struct_large_char
7474

7575
; CHECK: bl get_struct_small_char

llvm/test/CodeGen/ARM/stack-guard-reassign.ll

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,11 @@
33
; Verify that the offset assigned to the stack protector is at the top of the
44
; frame, covering the locals.
55
; CHECK-LABEL: fn:
6-
; CHECK: sub sp, sp, #24
6+
; CHECK: sub sp, sp, #16
77
; CHECK-NEXT: sub sp, sp, #65536
88
; CHECK-NEXT: ldr r1, .LCPI0_0
9-
; CHECK-NEXT: str r1, [sp, #8]
109
; CHECK-NEXT: ldr r1, [r1]
1110
; CHECK-NEXT: add lr, sp, #65536
12-
; CHECK-NEXT: str r1, [lr, #20]
11+
; CHECK-NEXT: str r1, [lr, #12]
1312
; CHECK: .LCPI0_0:
1413
; CHECK-NEXT: .long __stack_chk_guard

llvm/test/CodeGen/ARM/struct_byval.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ entry:
3131
; NACL-LABEL: g:
3232
; Ensure that use movw instead of constpool for the loop trip count. But don't
3333
; match the __stack_chk_guard movw
34-
; NACL: movw r{{[1-9]}}, #
34+
; NACL: movw {{r[0-9]+|lr}}, #
3535
; NACL: ldr
3636
; NACL: sub
3737
; NACL: str
@@ -49,7 +49,7 @@ entry:
4949
; CHECK: sub
5050
; CHECK: vst1
5151
; CHECK: bne
52-
; NACL: movw r{{[1-9]}}, #
52+
; NACL: movw {{r[0-9]+|lr}}, #
5353
; NACL: vld1
5454
; NACL: sub
5555
; NACL: vst1

llvm/test/CodeGen/ARM/tail-call-scheduling.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ target triple = "armv6kz-unknown-unknown-gnueabihf"
55
; Unfortunately, this test is sort of fragile... the original issue only
66
; shows up if scheduling happens in a very specific order. But including
77
; it anyway just to demonstrate the issue.
8-
; CHECK: pop {r4, lr}
8+
; CHECK: pop {r{{[0-9]+}}, lr}
99

1010
@e = external local_unnamed_addr constant [0 x i32 (i32, i32)*], align 4
1111

llvm/test/CodeGen/ARM/win32-ssp.ll

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ entry:
1212
; MINGW: ldr [[REG2:r[0-9]+]], {{\[}}[[REG]]]
1313
; MINGW: ldr {{r[0-9]+}}, {{\[}}[[REG2]]]
1414
; MINGW: bl other
15-
; MINGW: ldr {{r[0-9]+}}, {{\[}}[[REG2]]]
15+
; MINGW: movw [[REG3:r[0-9]+]], :lower16:.refptr.__stack_chk_guard
16+
; MINGW: movt [[REG3]], :upper16:.refptr.__stack_chk_guard
17+
; MINGW: ldr [[REG4:r[0-9]+]], {{\[}}[[REG3]]]
18+
; MINGW: ldr {{r[0-9]+}}, {{\[}}[[REG4]]]
1619
; MINGW: bl __stack_chk_fail
1720

1821
%c = alloca i8, align 1

0 commit comments

Comments
 (0)