[llvm] 2caf85a - [ARM] implement LOAD_STACK_GUARD for remaining targets
Ard Biesheuvel via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 8 14:04:24 PST 2021
Author: Ard Biesheuvel
Date: 2021-11-08T22:59:15+01:00
New Revision: 2caf85ad7ab83c441cb8e3550916d7028dfb8525
URL: https://github.com/llvm/llvm-project/commit/2caf85ad7ab83c441cb8e3550916d7028dfb8525
DIFF: https://github.com/llvm/llvm-project/commit/2caf85ad7ab83c441cb8e3550916d7028dfb8525.diff
LOG: [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
Added:
Modified:
llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
llvm/lib/Target/ARM/ARMISelLowering.cpp
llvm/lib/Target/ARM/ARMInstrInfo.cpp
llvm/lib/Target/ARM/Thumb2InstrInfo.cpp
llvm/test/CodeGen/ARM/ssp-data-layout.ll
llvm/test/CodeGen/ARM/stack-guard-reassign.ll
llvm/test/CodeGen/ARM/struct_byval.ll
llvm/test/CodeGen/ARM/tail-call-scheduling.ll
llvm/test/CodeGen/ARM/win32-ssp.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
index a94e1012b236c..6fed6483c7835 100644
--- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
@@ -1682,8 +1682,6 @@ void ARMBaseInstrInfo::expandMEMCPY(MachineBasicBlock::iterator MI) const {
bool ARMBaseInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
if (MI.getOpcode() == TargetOpcode::LOAD_STACK_GUARD) {
- assert(getSubtarget().getTargetTriple().isOSBinFormatMachO() &&
- "LOAD_STACK_GUARD currently supported only for MachO.");
expandLoadStackGuard(MI);
MI.getParent()->erase(MI);
return true;
@@ -4883,8 +4881,6 @@ bool ARMBaseInstrInfo::verifyInstruction(const MachineInstr &MI,
return true;
}
-// LoadStackGuard has so far only been implemented for MachO. Different code
-// sequence is needed for other targets.
void ARMBaseInstrInfo::expandLoadStackGuardBase(MachineBasicBlock::iterator MI,
unsigned LoadImmOpc,
unsigned LoadOpc) const {
@@ -4896,12 +4892,25 @@ void ARMBaseInstrInfo::expandLoadStackGuardBase(MachineBasicBlock::iterator MI,
Register Reg = MI->getOperand(0).getReg();
const GlobalValue *GV =
cast<GlobalValue>((*MI->memoperands_begin())->getValue());
+ bool IsIndirect = Subtarget.isGVIndirectSymbol(GV);
MachineInstrBuilder MIB;
+ unsigned TargetFlags = ARMII::MO_NO_FLAG;
+ if (Subtarget.isTargetMachO()) {
+ TargetFlags |= ARMII::MO_NONLAZY;
+ } else if (Subtarget.isTargetCOFF()) {
+ if (GV->hasDLLImportStorageClass())
+ TargetFlags |= ARMII::MO_DLLIMPORT;
+ else if (IsIndirect)
+ TargetFlags |= ARMII::MO_COFFSTUB;
+ } else if (Subtarget.isGVInGOT(GV)) {
+ TargetFlags |= ARMII::MO_GOT;
+ }
+
BuildMI(MBB, MI, DL, get(LoadImmOpc), Reg)
- .addGlobalAddress(GV, 0, ARMII::MO_NONLAZY);
+ .addGlobalAddress(GV, 0, TargetFlags);
- if (Subtarget.isGVIndirectSymbol(GV)) {
+ if (IsIndirect) {
MIB = BuildMI(MBB, MI, DL, get(LoadOpc), Reg);
MIB.addReg(Reg, RegState::Kill).addImm(0);
auto Flags = MachineMemOperand::MOLoad |
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index f49d39a4a8386..28a60bf9857bc 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -20682,10 +20682,7 @@ bool ARMTargetLowering::shouldInsertFencesForAtomic(
return InsertFencesForAtomic;
}
-// This has so far only been implemented for MachO.
-bool ARMTargetLowering::useLoadStackGuardNode() const {
- return Subtarget->isTargetMachO();
-}
+bool ARMTargetLowering::useLoadStackGuardNode() const { return true; }
void ARMTargetLowering::insertSSPDeclarations(Module &M) const {
if (!Subtarget->getTargetTriple().isWindowsMSVCEnvironment())
diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.cpp b/llvm/lib/Target/ARM/ARMInstrInfo.cpp
index 3c6c6960b80fc..106ba87107f85 100644
--- a/llvm/lib/Target/ARM/ARMInstrInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMInstrInfo.cpp
@@ -96,7 +96,10 @@ void ARMInstrInfo::expandLoadStackGuard(MachineBasicBlock::iterator MI) const {
const ARMSubtarget &Subtarget = MF.getSubtarget<ARMSubtarget>();
const TargetMachine &TM = MF.getTarget();
- if (!Subtarget.useMovt()) {
+ const GlobalValue *GV =
+ cast<GlobalValue>((*MI->memoperands_begin())->getValue());
+
+ if (!Subtarget.useMovt() || Subtarget.isGVInGOT(GV)) {
if (TM.isPositionIndependent())
expandLoadStackGuardBase(MI, ARM::LDRLIT_ga_pcrel, ARM::LDRi12);
else
@@ -109,9 +112,6 @@ void ARMInstrInfo::expandLoadStackGuard(MachineBasicBlock::iterator MI) const {
return;
}
- const GlobalValue *GV =
- cast<GlobalValue>((*MI->memoperands_begin())->getValue());
-
if (!Subtarget.isGVIndirectSymbol(GV)) {
expandLoadStackGuardBase(MI, ARM::MOV_ga_pcrel, ARM::LDRi12);
return;
diff --git a/llvm/lib/Target/ARM/Thumb2InstrInfo.cpp b/llvm/lib/Target/ARM/Thumb2InstrInfo.cpp
index 4898a4b77761f..e3b2f77b70495 100644
--- a/llvm/lib/Target/ARM/Thumb2InstrInfo.cpp
+++ b/llvm/lib/Target/ARM/Thumb2InstrInfo.cpp
@@ -250,7 +250,12 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
void Thumb2InstrInfo::expandLoadStackGuard(
MachineBasicBlock::iterator MI) const {
MachineFunction &MF = *MI->getParent()->getParent();
- if (MF.getTarget().isPositionIndependent())
+ const GlobalValue *GV =
+ cast<GlobalValue>((*MI->memoperands_begin())->getValue());
+
+ if (MF.getSubtarget<ARMSubtarget>().isGVInGOT(GV))
+ expandLoadStackGuardBase(MI, ARM::tLDRLIT_ga_pcrel, ARM::t2LDRi12);
+ else if (MF.getTarget().isPositionIndependent())
expandLoadStackGuardBase(MI, ARM::t2MOV_ga_pcrel, ARM::t2LDRi12);
else
expandLoadStackGuardBase(MI, ARM::t2MOVi32imm, ARM::t2LDRi12);
diff --git a/llvm/test/CodeGen/ARM/ssp-data-layout.ll b/llvm/test/CodeGen/ARM/ssp-data-layout.ll
index 8a850c48db80b..ccae951d5c6cf 100644
--- a/llvm/test/CodeGen/ARM/ssp-data-layout.ll
+++ b/llvm/test/CodeGen/ARM/ssp-data-layout.ll
@@ -21,13 +21,13 @@
define void @layout_ssp() ssp {
entry:
; Expected stack layout for ssp is
-; 176 large_char . Group 1, nested arrays, arrays >= ssp-buffer-size
-; 168 struct_large_char .
-; 164 scalar1 | Everything else
-; 160 scalar2
-; 156 scalar3
-; 152 addr-of
-; 148 small_nonchar
+; 180 large_char . Group 1, nested arrays, arrays >= ssp-buffer-size
+; 172 struct_large_char .
+; 168 scalar1 | Everything else
+; 164 scalar2
+; 160 scalar3
+; 156 addr-of
+; 152 small_nonchar
; 112 large_nonchar
; 110 small_char
; 108 struct_small_char
@@ -37,23 +37,23 @@ entry:
; CHECK: layout_ssp:
; CHECK: bl get_scalar1
-; CHECK: str r0, [sp, #164]
+; CHECK: str r0, [sp, #168]
; CHECK: bl end_scalar1
; CHECK: bl get_scalar2
-; CHECK: str r0, [sp, #160]
-; CHECK: bl end_scalar2
+; CHECK: str r0, [sp, #164]
+; CHECK: bl end_scalar
; CHECK: bl get_scalar3
-; CHECK: str r0, [sp, #156]
+; CHECK: str r0, [sp, #160]
; CHECK: bl end_scalar3
; CHECK: bl get_addrof
-; CHECK: str r0, [sp, #152]
+; CHECK: str r0, [sp, #156]
; CHECK: bl end_addrof
; CHECK: get_small_nonchar
-; CHECK: strh r0, [sp, #148]
+; CHECK: strh r0, [sp, #152]
; CHECK: bl end_small_nonchar
; CHECK: bl get_large_nonchar
@@ -65,11 +65,11 @@ entry:
; CHECK: bl end_small_char
; CHECK: bl get_large_char
-; CHECK: strb r0, [sp, #176]
+; CHECK: strb r0, [sp, #180]
; CHECK: bl end_large_char
; CHECK: bl get_struct_large_char
-; CHECK: strb r0, [sp, #168]
+; CHECK: strb r0, [sp, #172]
; CHECK: bl end_struct_large_char
; CHECK: bl get_struct_small_char
diff --git a/llvm/test/CodeGen/ARM/stack-guard-reassign.ll b/llvm/test/CodeGen/ARM/stack-guard-reassign.ll
index f2d9a5c0f7fd3..4e4d61dd46b7f 100644
--- a/llvm/test/CodeGen/ARM/stack-guard-reassign.ll
+++ b/llvm/test/CodeGen/ARM/stack-guard-reassign.ll
@@ -3,12 +3,11 @@
; Verify that the offset assigned to the stack protector is at the top of the
; frame, covering the locals.
; CHECK-LABEL: fn:
-; CHECK: sub sp, sp, #24
+; CHECK: sub sp, sp, #16
; CHECK-NEXT: sub sp, sp, #65536
; CHECK-NEXT: ldr r1, .LCPI0_0
-; CHECK-NEXT: str r1, [sp, #8]
; CHECK-NEXT: ldr r1, [r1]
; CHECK-NEXT: add lr, sp, #65536
-; CHECK-NEXT: str r1, [lr, #20]
+; CHECK-NEXT: str r1, [lr, #12]
; CHECK: .LCPI0_0:
; CHECK-NEXT: .long __stack_chk_guard
diff --git a/llvm/test/CodeGen/ARM/struct_byval.ll b/llvm/test/CodeGen/ARM/struct_byval.ll
index 69fdd2435594b..6d3c7121fac77 100644
--- a/llvm/test/CodeGen/ARM/struct_byval.ll
+++ b/llvm/test/CodeGen/ARM/struct_byval.ll
@@ -31,7 +31,7 @@ entry:
; NACL-LABEL: g:
; Ensure that use movw instead of constpool for the loop trip count. But don't
; match the __stack_chk_guard movw
-; NACL: movw r{{[1-9]}}, #
+; NACL: movw {{r[0-9]+|lr}}, #
; NACL: ldr
; NACL: sub
; NACL: str
@@ -49,7 +49,7 @@ entry:
; CHECK: sub
; CHECK: vst1
; CHECK: bne
-; NACL: movw r{{[1-9]}}, #
+; NACL: movw {{r[0-9]+|lr}}, #
; NACL: vld1
; NACL: sub
; NACL: vst1
diff --git a/llvm/test/CodeGen/ARM/tail-call-scheduling.ll b/llvm/test/CodeGen/ARM/tail-call-scheduling.ll
index 591da10256ba4..cd50ced0fa769 100644
--- a/llvm/test/CodeGen/ARM/tail-call-scheduling.ll
+++ b/llvm/test/CodeGen/ARM/tail-call-scheduling.ll
@@ -5,7 +5,7 @@ target triple = "armv6kz-unknown-unknown-gnueabihf"
; Unfortunately, this test is sort of fragile... the original issue only
; shows up if scheduling happens in a very specific order. But including
; it anyway just to demonstrate the issue.
-; CHECK: pop {r4, lr}
+; CHECK: pop {r{{[0-9]+}}, lr}
@e = external local_unnamed_addr constant [0 x i32 (i32, i32)*], align 4
diff --git a/llvm/test/CodeGen/ARM/win32-ssp.ll b/llvm/test/CodeGen/ARM/win32-ssp.ll
index 292ef9f65df1a..679f2ea4011ba 100644
--- a/llvm/test/CodeGen/ARM/win32-ssp.ll
+++ b/llvm/test/CodeGen/ARM/win32-ssp.ll
@@ -12,7 +12,10 @@ entry:
; MINGW: ldr [[REG2:r[0-9]+]], {{\[}}[[REG]]]
; MINGW: ldr {{r[0-9]+}}, {{\[}}[[REG2]]]
; MINGW: bl other
-; MINGW: ldr {{r[0-9]+}}, {{\[}}[[REG2]]]
+; MINGW: movw [[REG3:r[0-9]+]], :lower16:.refptr.__stack_chk_guard
+; MINGW: movt [[REG3]], :upper16:.refptr.__stack_chk_guard
+; MINGW: ldr [[REG4:r[0-9]+]], {{\[}}[[REG3]]]
+; MINGW: ldr {{r[0-9]+}}, {{\[}}[[REG4]]]
; MINGW: bl __stack_chk_fail
%c = alloca i8, align 1
More information about the llvm-commits
mailing list