Skip to content

Commit 44b020a

Browse files
[PowerPC][ISelLowering] Support -mstack-protector-guard=tls (#110928)
Add support for using a thread-local variable with a specified offset for holding the stack guard canary value. This supports both 32- and 64- bit PowerPC targets. This mirrors changes from #108942 but targeting PowerPC instead of RISCV. Because both of these PRs modify the same driver functions, this series is stack on top of the RISC-V one. --------- Signed-off-by: Keith Packard <[email protected]>
1 parent 70865c4 commit 44b020a

File tree

20 files changed

+354
-36
lines changed

20 files changed

+354
-36
lines changed

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3595,7 +3595,7 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
35953595
StringRef Value = A->getValue();
35963596
if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
35973597
!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
3598-
!EffectiveTriple.isRISCV())
3598+
!EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC())
35993599
D.Diag(diag::err_drv_unsupported_opt_for_target)
36003600
<< A->getAsString(Args) << TripleStr;
36013601
if ((EffectiveTriple.isX86() || EffectiveTriple.isARM() ||
@@ -3635,7 +3635,7 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
36353635
<< A->getOption().getName() << Value << "sysreg global";
36363636
return;
36373637
}
3638-
if (EffectiveTriple.isRISCV()) {
3638+
if (EffectiveTriple.isRISCV() || EffectiveTriple.isPPC()) {
36393639
if (Value != "tls" && Value != "global") {
36403640
D.Diag(diag::err_drv_invalid_value_with_suggestion)
36413641
<< A->getOption().getName() << Value << "tls global";
@@ -3656,7 +3656,7 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
36563656
StringRef Value = A->getValue();
36573657
if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
36583658
!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
3659-
!EffectiveTriple.isRISCV())
3659+
!EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC())
36603660
D.Diag(diag::err_drv_unsupported_opt_for_target)
36613661
<< A->getAsString(Args) << TripleStr;
36623662
int Offset;
@@ -3676,7 +3676,7 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
36763676
if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_reg_EQ)) {
36773677
StringRef Value = A->getValue();
36783678
if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
3679-
!EffectiveTriple.isRISCV())
3679+
!EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC())
36803680
D.Diag(diag::err_drv_unsupported_opt_for_target)
36813681
<< A->getAsString(Args) << TripleStr;
36823682
if (EffectiveTriple.isX86() && (Value != "fs" && Value != "gs")) {
@@ -3693,6 +3693,16 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
36933693
<< A->getOption().getName() << Value << "tp";
36943694
return;
36953695
}
3696+
if (EffectiveTriple.isPPC64() && Value != "r13") {
3697+
D.Diag(diag::err_drv_invalid_value_with_suggestion)
3698+
<< A->getOption().getName() << Value << "r13";
3699+
return;
3700+
}
3701+
if (EffectiveTriple.isPPC32() && Value != "r2") {
3702+
D.Diag(diag::err_drv_invalid_value_with_suggestion)
3703+
<< A->getOption().getName() << Value << "r2";
3704+
return;
3705+
}
36963706
A->render(Args, CmdArgs);
36973707
}
36983708

clang/test/CodeGen/stack-protector-guard.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@
1212
// RUN: %clang_cc1 -mstack-protector-guard=tls -triple riscv64-unknown-elf \
1313
// RUN: -mstack-protector-guard-offset=44 -mstack-protector-guard-reg=tp \
1414
// RUN: -emit-llvm %s -o - | FileCheck %s --check-prefix=RISCV
15+
// RUN: %clang_cc1 -mstack-protector-guard=tls -triple powerpc64-unknown-elf \
16+
// RUN: -mstack-protector-guard-offset=52 -mstack-protector-guard-reg=r13 \
17+
// RUN: -emit-llvm %s -o - | FileCheck %s --check-prefix=POWERPC64
18+
// RUN: %clang_cc1 -mstack-protector-guard=tls -triple ppc32-unknown-elf \
19+
// RUN: -mstack-protector-guard-offset=16 -mstack-protector-guard-reg=r2 \
20+
// RUN: -emit-llvm %s -o - | FileCheck %s --check-prefix=POWERPC32
1521
void foo(int*);
1622
void bar(int x) {
1723
int baz[x];
@@ -31,3 +37,13 @@ void bar(int x) {
3137
// RISCV: [[ATTR1]] = !{i32 1, !"stack-protector-guard", !"tls"}
3238
// RISCV: [[ATTR2]] = !{i32 1, !"stack-protector-guard-reg", !"tp"}
3339
// RISCV: [[ATTR3]] = !{i32 1, !"stack-protector-guard-offset", i32 44}
40+
41+
// POWERPC64: !llvm.module.flags = !{{{.*}}[[ATTR1:![0-9]+]], [[ATTR2:![0-9]+]], [[ATTR3:![0-9]+]], [[ATTR4:![0-9]+]]}
42+
// POWERPC64: [[ATTR2]] = !{i32 1, !"stack-protector-guard", !"tls"}
43+
// POWERPC64: [[ATTR3]] = !{i32 1, !"stack-protector-guard-reg", !"r13"}
44+
// POWERPC64: [[ATTR4]] = !{i32 1, !"stack-protector-guard-offset", i32 52}
45+
46+
// POWERPC32: !llvm.module.flags = !{{{.*}}[[ATTR1:![0-9]+]], [[ATTR2:![0-9]+]], [[ATTR3:![0-9]+]], [[ATTR4:![0-9]+]]}
47+
// POWERPC32: [[ATTR2]] = !{i32 1, !"stack-protector-guard", !"tls"}
48+
// POWERPC32: [[ATTR3]] = !{i32 1, !"stack-protector-guard-reg", !"r2"}
49+
// POWERPC32: [[ATTR4]] = !{i32 1, !"stack-protector-guard-offset", i32 16}

clang/test/Driver/stack-protector-guard.c

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@
1717
// RUN: FileCheck -check-prefix=CHECK-SYM %s
1818

1919
// Invalid arch
20-
// RUN: not %clang -target powerpc64le-linux-gnu -mstack-protector-guard=tls %s 2>&1 | \
20+
// RUN: not %clang -target mipsel-linux-gnu -mstack-protector-guard=tls %s 2>&1 | \
2121
// RUN: FileCheck -check-prefix=INVALID-ARCH %s
2222
// INVALID-ARCH: unsupported option '-mstack-protector-guard=tls' for target
2323

24-
// RUN: not %clang -target powerpc64le-linux-gnu -mstack-protector-guard-reg=fs %s 2>&1 | \
24+
// RUN: not %clang -target mipsel-linux-gnu -mstack-protector-guard-reg=fs %s 2>&1 | \
2525
// RUN: FileCheck -check-prefix=INVALID-ARCH2 %s
2626
// INVALID-ARCH2: unsupported option '-mstack-protector-guard-reg=fs' for target
2727

28-
// RUN: not %clang -target powerpc64le-linux-gnu -mstack-protector-guard-offset=10 %s 2>&1 | \
28+
// RUN: not %clang -target mipsel-linux-gnu -mstack-protector-guard-offset=10 %s 2>&1 | \
2929
// RUN: FileCheck -check-prefix=INVALID-ARCH3 %s
3030
// INVALID-ARCH3: unsupported option '-mstack-protector-guard-offset=10' for target
3131

@@ -104,3 +104,54 @@
104104
// RUN: FileCheck -check-prefix=INVALID-REG-RISCV %s
105105

106106
// INVALID-REG-RISCV: error: invalid value 'sp' in 'mstack-protector-guard-reg=', expected one of: tp
107+
108+
// RUN: %clang -### -target powerpc64-unknown-elf -mstack-protector-guard=tls -mstack-protector-guard-offset=24 -mstack-protector-guard-reg=r13 %s 2>&1 | \
109+
// RUN: FileCheck -v -check-prefix=CHECK-TLS-POWERPC64 %s
110+
// RUN: %clang -### -target powerpc64-unknown-linux-gnu -mstack-protector-guard=global %s 2>&1 | \
111+
// RUN: FileCheck -check-prefix=CHECK-GLOBAL %s
112+
113+
// RUN: not %clang -target powerpc64-unknown-linux-gnu -mstack-protector-guard=tls %s 2>&1 | \
114+
// RUN: FileCheck -check-prefix=MISSING-OFFSET %s
115+
116+
// RUN: not %clang -target powerpc64-unknown-elf -mstack-protector-guard=sysreg %s 2>&1 | \
117+
// RUN: FileCheck -check-prefix=INVALID-VALUE2 %s
118+
119+
// RUN: not %clang -target powerpc64-unknown-elf -mstack-protector-guard=tls \
120+
// RUN: -mstack-protector-guard-offset=20 -mstack-protector-guard-reg=r12 %s 2>&1 | \
121+
// RUN: FileCheck -check-prefix=INVALID-REG-POWERPC64 %s
122+
123+
// CHECK-TLS-POWERPC64: "-cc1" {{.*}}"-mstack-protector-guard=tls" "-mstack-protector-guard-offset=24" "-mstack-protector-guard-reg=r13"
124+
// INVALID-REG-POWERPC64: error: invalid value 'r12' in 'mstack-protector-guard-reg=', expected one of: r13
125+
126+
// RUN: %clang -### -target powerpc64le-unknown-elf -mstack-protector-guard=tls -mstack-protector-guard-offset=24 -mstack-protector-guard-reg=r13 %s 2>&1 | \
127+
// RUN: FileCheck -v -check-prefix=CHECK-TLS-POWERPC64 %s
128+
// RUN: %clang -### -target powerpc64le-unknown-elf -mstack-protector-guard=global %s 2>&1 | \
129+
// RUN: FileCheck -check-prefix=CHECK-GLOBAL %s
130+
131+
// RUN: not %clang -target powerpc64le-unknown-elf -mstack-protector-guard=tls %s 2>&1 | \
132+
// RUN: FileCheck -check-prefix=MISSING-OFFSET %s
133+
134+
// RUN: not %clang -target powerpc64le-unknown-elf -mstack-protector-guard=sysreg %s 2>&1 | \
135+
// RUN: FileCheck -check-prefix=INVALID-VALUE2 %s
136+
137+
// RUN: not %clang -target powerpc64le-unknown-elf -mstack-protector-guard=tls \
138+
// RUN: -mstack-protector-guard-offset=20 -mstack-protector-guard-reg=r12 %s 2>&1 | \
139+
// RUN: FileCheck -check-prefix=INVALID-REG-POWERPC64 %s
140+
141+
// RUN: %clang -### -target ppc32-unknown-elf -mstack-protector-guard=tls -mstack-protector-guard-offset=24 -mstack-protector-guard-reg=r2 %s 2>&1 | \
142+
// RUN: FileCheck -v -check-prefix=CHECK-TLS-POWERPC32 %s
143+
// RUN: %clang -### -target ppc32-unknown-elf -mstack-protector-guard=global %s 2>&1 | \
144+
// RUN: FileCheck -check-prefix=CHECK-GLOBAL %s
145+
146+
// RUN: not %clang -target ppc32-unknown-elf -mstack-protector-guard=tls %s 2>&1 | \
147+
// RUN: FileCheck -check-prefix=MISSING-OFFSET %s
148+
149+
// RUN: not %clang -target ppc32-unknown-elf -mstack-protector-guard=sysreg %s 2>&1 | \
150+
// RUN: FileCheck -check-prefix=INVALID-VALUE2 %s
151+
152+
// RUN: not %clang -target ppc32-unknown-elf -mstack-protector-guard=tls \
153+
// RUN: -mstack-protector-guard-offset=20 -mstack-protector-guard-reg=r3 %s 2>&1 | \
154+
// RUN: FileCheck -check-prefix=INVALID-REG-POWERPC32 %s
155+
156+
// CHECK-TLS-POWERPC32: "-cc1" {{.*}}"-mstack-protector-guard=tls" "-mstack-protector-guard-offset=24" "-mstack-protector-guard-reg=r2"
157+
// INVALID-REG-POWERPC32: error: invalid value 'r3' in 'mstack-protector-guard-reg=', expected one of: r2

llvm/include/llvm/CodeGen/TargetLowering.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5567,9 +5567,7 @@ class TargetLowering : public TargetLoweringBase {
55675567

55685568
/// If this function returns true, SelectionDAGBuilder emits a
55695569
/// LOAD_STACK_GUARD node when it is lowering Intrinsic::stackprotector.
5570-
virtual bool useLoadStackGuardNode() const {
5571-
return false;
5572-
}
5570+
virtual bool useLoadStackGuardNode(const Module &M) const { return false; }
55735571

55745572
virtual SDValue emitStackGuardXorFP(SelectionDAG &DAG, SDValue Val,
55755573
const SDLoc &DL) const {

llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2378,7 +2378,7 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
23782378
case Intrinsic::stackprotector: {
23792379
LLT PtrTy = getLLTForType(*CI.getArgOperand(0)->getType(), *DL);
23802380
Register GuardVal;
2381-
if (TLI->useLoadStackGuardNode()) {
2381+
if (TLI->useLoadStackGuardNode(*CI.getModule())) {
23822382
GuardVal = MRI->createGenericVirtualRegister(PtrTy);
23832383
getStackGuard(GuardVal, MIRBuilder);
23842384
} else
@@ -3869,7 +3869,7 @@ bool IRTranslator::emitSPDescriptorParent(StackProtectorDescriptor &SPD,
38693869

38703870
// If useLoadStackGuardNode returns true, generate LOAD_STACK_GUARD.
38713871
// Otherwise, emit a volatile load to retrieve the stack guard value.
3872-
if (TLI->useLoadStackGuardNode()) {
3872+
if (TLI->useLoadStackGuardNode(*ParentBB->getBasicBlock()->getModule())) {
38733873
Guard =
38743874
MRI->createGenericVirtualRegister(LLT::scalar(PtrTy.getSizeInBits()));
38753875
getStackGuard(Guard, *CurBuilder);

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3138,7 +3138,7 @@ void SelectionDAGBuilder::visitSPDescriptorParent(StackProtectorDescriptor &SPD,
31383138
// If useLoadStackGuardNode returns true, generate LOAD_STACK_GUARD.
31393139
// Otherwise, emit a volatile load to retrieve the stack guard value.
31403140
SDValue Chain = DAG.getEntryNode();
3141-
if (TLI.useLoadStackGuardNode()) {
3141+
if (TLI.useLoadStackGuardNode(M)) {
31423142
Guard = getLoadStackGuard(DAG, dl, Chain);
31433143
} else {
31443144
const Value *IRGuard = TLI.getSDagStackGuard(M);
@@ -7349,7 +7349,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
73497349
const Module &M = *MF.getFunction().getParent();
73507350
EVT PtrTy = TLI.getValueType(DAG.getDataLayout(), I.getType());
73517351
SDValue Chain = getRoot();
7352-
if (TLI.useLoadStackGuardNode()) {
7352+
if (TLI.useLoadStackGuardNode(M)) {
73537353
Res = getLoadStackGuard(DAG, sdl, Chain);
73547354
Res = DAG.getPtrExtOrTrunc(Res, sdl, PtrTy);
73557355
} else {
@@ -7369,9 +7369,10 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
73697369
// Emit code into the DAG to store the stack guard onto the stack.
73707370
MachineFunction &MF = DAG.getMachineFunction();
73717371
MachineFrameInfo &MFI = MF.getFrameInfo();
7372+
const Module &M = *MF.getFunction().getParent();
73727373
SDValue Src, Chain = getRoot();
73737374

7374-
if (TLI.useLoadStackGuardNode())
7375+
if (TLI.useLoadStackGuardNode(M))
73757376
Src = getLoadStackGuard(DAG, sdl, Chain);
73767377
else
73777378
Src = getValue(I.getArgOperand(0)); // The guard's value.

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26982,9 +26982,9 @@ void AArch64TargetLowering::ReplaceNodeResults(
2698226982
}
2698326983
}
2698426984

26985-
bool AArch64TargetLowering::useLoadStackGuardNode() const {
26985+
bool AArch64TargetLowering::useLoadStackGuardNode(const Module &M) const {
2698626986
if (Subtarget->isTargetAndroid() || Subtarget->isTargetFuchsia())
26987-
return TargetLowering::useLoadStackGuardNode();
26987+
return TargetLowering::useLoadStackGuardNode(M);
2698826988
return true;
2698926989
}
2699026990

llvm/lib/Target/AArch64/AArch64ISelLowering.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -811,7 +811,7 @@ class AArch64TargetLowering : public TargetLowering {
811811
TargetLoweringBase::AtomicExpansionKind
812812
shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const override;
813813

814-
bool useLoadStackGuardNode() const override;
814+
bool useLoadStackGuardNode(const Module &M) const override;
815815
TargetLoweringBase::LegalizeTypeAction
816816
getPreferredVectorAction(MVT VT) const override;
817817

llvm/lib/Target/ARM/ARMISelLowering.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21305,7 +21305,7 @@ bool ARMTargetLowering::shouldInsertFencesForAtomic(
2130521305
return InsertFencesForAtomic;
2130621306
}
2130721307

21308-
bool ARMTargetLowering::useLoadStackGuardNode() const {
21308+
bool ARMTargetLowering::useLoadStackGuardNode(const Module &M) const {
2130921309
// ROPI/RWPI are not supported currently.
2131021310
return !Subtarget->isROPI() && !Subtarget->isRWPI();
2131121311
}

llvm/lib/Target/ARM/ARMISelLowering.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,7 @@ class VectorType;
675675
TargetLoweringBase::AtomicExpansionKind
676676
shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const override;
677677

678-
bool useLoadStackGuardNode() const override;
678+
bool useLoadStackGuardNode(const Module &M) const override;
679679

680680
void insertSSPDeclarations(Module &M) const override;
681681
Value *getSDagStackGuard(const Module &M) const override;

0 commit comments

Comments
 (0)