-
Notifications
You must be signed in to change notification settings - Fork 11.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[PowerPC][ISelLowering] Support -mstack-protector-guard=tls #110928
base: main
Are you sure you want to change the base?
Conversation
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
@llvm/pr-subscribers-clang-driver @llvm/pr-subscribers-clang Author: Keith Packard (keith-packard) ChangesAdd 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. Patch is 25.26 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/110928.diff 10 Files Affected:
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index b9987288d82d10..183820e5d7f187 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3604,7 +3604,9 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_EQ)) {
StringRef Value = A->getValue();
if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
- !EffectiveTriple.isARM() && !EffectiveTriple.isThumb())
+ !EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
+ !EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC64() &&
+ !EffectiveTriple.isPPC32())
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< A->getAsString(Args) << TripleStr;
if ((EffectiveTriple.isX86() || EffectiveTriple.isARM() ||
@@ -3644,13 +3646,30 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
<< A->getOption().getName() << Value << "sysreg global";
return;
}
+ if (EffectiveTriple.isRISCV() || EffectiveTriple.isPPC64() ||
+ EffectiveTriple.isPPC32()) {
+ if (Value != "tls" && Value != "global") {
+ D.Diag(diag::err_drv_invalid_value_with_suggestion)
+ << A->getOption().getName() << Value << "tls global";
+ return;
+ }
+ if (Value == "tls") {
+ if (!Args.hasArg(options::OPT_mstack_protector_guard_offset_EQ)) {
+ D.Diag(diag::err_drv_ssp_missing_offset_argument)
+ << A->getAsString(Args);
+ return;
+ }
+ }
+ }
A->render(Args, CmdArgs);
}
if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_offset_EQ)) {
StringRef Value = A->getValue();
if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
- !EffectiveTriple.isARM() && !EffectiveTriple.isThumb())
+ !EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
+ !EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC64() &&
+ !EffectiveTriple.isPPC32())
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< A->getAsString(Args) << TripleStr;
int Offset;
@@ -3669,7 +3688,9 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_reg_EQ)) {
StringRef Value = A->getValue();
- if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64())
+ if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
+ !EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC64() &&
+ !EffectiveTriple.isPPC32())
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< A->getAsString(Args) << TripleStr;
if (EffectiveTriple.isX86() && (Value != "fs" && Value != "gs")) {
@@ -3681,6 +3702,21 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Value;
return;
}
+ if (EffectiveTriple.isRISCV() && Value != "tp") {
+ D.Diag(diag::err_drv_invalid_value_with_suggestion)
+ << A->getOption().getName() << Value << "tp";
+ return;
+ }
+ if (EffectiveTriple.isPPC64() && Value != "r13") {
+ D.Diag(diag::err_drv_invalid_value_with_suggestion)
+ << A->getOption().getName() << Value << "r13";
+ return;
+ }
+ if (EffectiveTriple.isPPC32() && Value != "r2") {
+ D.Diag(diag::err_drv_invalid_value_with_suggestion)
+ << A->getOption().getName() << Value << "r2";
+ return;
+ }
A->render(Args, CmdArgs);
}
diff --git a/clang/test/CodeGen/stack-protector-guard.c b/clang/test/CodeGen/stack-protector-guard.c
index 5839ab06033a15..51af6fb6311be8 100644
--- a/clang/test/CodeGen/stack-protector-guard.c
+++ b/clang/test/CodeGen/stack-protector-guard.c
@@ -9,6 +9,12 @@
// RUN: %clang_cc1 -mstack-protector-guard=sysreg -triple aarch64-linux-gnu \
// RUN: -mstack-protector-guard-offset=1024 -mstack-protector-guard-reg=sp_el0 \
// RUN: -emit-llvm %s -o - | FileCheck %s --check-prefix=AARCH64
+// RUN: %clang_cc1 -mstack-protector-guard=tls -triple riscv64-unknown-elf \
+// RUN: -mstack-protector-guard-offset=44 -mstack-protector-guard-reg=tp \
+// RUN: -emit-llvm %s -o - | FileCheck %s --check-prefix=RISCV
+// RUN: %clang_cc1 -mstack-protector-guard=tls -triple powerpc64-unknown-elf \
+// RUN: -mstack-protector-guard-offset=52 -mstack-protector-guard-reg=r13 \
+// RUN: -emit-llvm %s -o - | FileCheck %s --check-prefix=POWERPC64
void foo(int*);
void bar(int x) {
int baz[x];
@@ -23,3 +29,13 @@ void bar(int x) {
// AARCH64: [[ATTR1]] = !{i32 1, !"stack-protector-guard", !"sysreg"}
// AARCH64: [[ATTR2]] = !{i32 1, !"stack-protector-guard-reg", !"sp_el0"}
// AARCH64: [[ATTR3]] = !{i32 1, !"stack-protector-guard-offset", i32 1024}
+
+// RISCV: !llvm.module.flags = !{{{.*}}[[ATTR1:![0-9]+]], [[ATTR2:![0-9]+]], [[ATTR3:![0-9]+]], [[ATTR4:![0-9]+]]}
+// RISCV: [[ATTR1]] = !{i32 1, !"stack-protector-guard", !"tls"}
+// RISCV: [[ATTR2]] = !{i32 1, !"stack-protector-guard-reg", !"tp"}
+// RISCV: [[ATTR3]] = !{i32 1, !"stack-protector-guard-offset", i32 44}
+
+// POWERPC64: !llvm.module.flags = !{{{.*}}[[ATTR1:![0-9]+]], [[ATTR2:![0-9]+]], [[ATTR3:![0-9]+]], [[ATTR4:![0-9]+]]}
+// POWERPC64: [[ATTR1]] = !{i32 1, !"stack-protector-guard", !"tls"}
+// POWERPC64: [[ATTR2]] = !{i32 1, !"stack-protector-guard-reg", !"r13"}
+// POWERPC64: [[ATTR3]] = !{i32 1, !"stack-protector-guard-offset", i32 52}
diff --git a/clang/test/Driver/stack-protector-guard.c b/clang/test/Driver/stack-protector-guard.c
index af4e11f8eaabce..666c83079e5191 100644
--- a/clang/test/Driver/stack-protector-guard.c
+++ b/clang/test/Driver/stack-protector-guard.c
@@ -17,15 +17,15 @@
// RUN: FileCheck -check-prefix=CHECK-SYM %s
// Invalid arch
-// RUN: not %clang -target powerpc64le-linux-gnu -mstack-protector-guard=tls %s 2>&1 | \
+// RUN: not %clang -target mipsel-linux-gnu -mstack-protector-guard=tls %s 2>&1 | \
// RUN: FileCheck -check-prefix=INVALID-ARCH %s
// INVALID-ARCH: unsupported option '-mstack-protector-guard=tls' for target
-// RUN: not %clang -target powerpc64le-linux-gnu -mstack-protector-guard-reg=fs %s 2>&1 | \
+// RUN: not %clang -target mipsel-linux-gnu -mstack-protector-guard-reg=fs %s 2>&1 | \
// RUN: FileCheck -check-prefix=INVALID-ARCH2 %s
// INVALID-ARCH2: unsupported option '-mstack-protector-guard-reg=fs' for target
-// RUN: not %clang -target powerpc64le-linux-gnu -mstack-protector-guard-offset=10 %s 2>&1 | \
+// RUN: not %clang -target mipsel-linux-gnu -mstack-protector-guard-offset=10 %s 2>&1 | \
// RUN: FileCheck -check-prefix=INVALID-ARCH3 %s
// INVALID-ARCH3: unsupported option '-mstack-protector-guard-offset=10' for target
@@ -85,3 +85,73 @@
// CHECK-AARCH64: "-cc1" {{.*}}"-mstack-protector-guard=sysreg" "-mstack-protector-guard-offset=0" "-mstack-protector-guard-reg=sp_el0"
// INVALID-VALUE-AARCH64: error: invalid value 'tls' in 'mstack-protector-guard=', expected one of: sysreg global
// INVALID-REG-AARCH64: error: invalid value 'foo' in 'mstack-protector-guard-reg='
+
+// RUN: %clang -### -target riscv64-unknown-elf -mstack-protector-guard=tls -mstack-protector-guard-offset=24 -mstack-protector-guard-reg=tp %s 2>&1 | \
+// RUN: FileCheck -v -check-prefix=CHECK-TLS-RISCV %s
+// RUN: %clang -### -target riscv64-unknown-elf -mstack-protector-guard=global %s 2>&1 | \
+// RUN: FileCheck -check-prefix=CHECK-GLOBAL %s
+
+// CHECK-TLS-RISCV: "-cc1" {{.*}}"-mstack-protector-guard=tls" "-mstack-protector-guard-offset=24" "-mstack-protector-guard-reg=tp"
+
+// RUN: not %clang -target riscv64-unknown-elf -mstack-protector-guard=tls %s 2>&1 | \
+// RUN: FileCheck -check-prefix=MISSING-OFFSET %s
+
+// RUN: not %clang -target riscv64-unknown-elf -mstack-protector-guard=sysreg %s 2>&1 | \
+// RUN: FileCheck -check-prefix=INVALID-VALUE2 %s
+
+// RUN: not %clang -target riscv64-unknown-elf -mstack-protector-guard=tls \
+// RUN: -mstack-protector-guard-offset=20 -mstack-protector-guard-reg=sp %s 2>&1 | \
+// RUN: FileCheck -check-prefix=INVALID-REG-RISCV %s
+
+// INVALID-REG-RISCV: error: invalid value 'sp' in 'mstack-protector-guard-reg=', expected one of: tp
+
+// RUN: %clang -### -target powerpc64-unknown-elf -mstack-protector-guard=tls -mstack-protector-guard-offset=24 -mstack-protector-guard-reg=r13 %s 2>&1 | \
+// RUN: FileCheck -v -check-prefix=CHECK-TLS-POWERPC64 %s
+// RUN: %clang -### -target powerpc64-unknown-linux-gnu -mstack-protector-guard=global %s 2>&1 | \
+// RUN: FileCheck -check-prefix=CHECK-GLOBAL %s
+
+// RUN: not %clang -target powerpc64-unknown-linux-gnu -mstack-protector-guard=tls %s 2>&1 | \
+// RUN: FileCheck -check-prefix=MISSING-OFFSET %s
+
+// RUN: not %clang -target powerpc64-unknown-elf -mstack-protector-guard=sysreg %s 2>&1 | \
+// RUN: FileCheck -check-prefix=INVALID-VALUE2 %s
+
+// RUN: not %clang -target powerpc64-unknown-elf -mstack-protector-guard=tls \
+// RUN: -mstack-protector-guard-offset=20 -mstack-protector-guard-reg=r12 %s 2>&1 | \
+// RUN: FileCheck -check-prefix=INVALID-REG-POWERPC64 %s
+
+// CHECK-TLS-POWERPC64: "-cc1" {{.*}}"-mstack-protector-guard=tls" "-mstack-protector-guard-offset=24" "-mstack-protector-guard-reg=r13"
+// INVALID-REG-POWERPC64: error: invalid value 'r12' in 'mstack-protector-guard-reg=', expected one of: r13
+
+// RUN: %clang -### -target powerpc64le-unknown-elf -mstack-protector-guard=tls -mstack-protector-guard-offset=24 -mstack-protector-guard-reg=r13 %s 2>&1 | \
+// RUN: FileCheck -v -check-prefix=CHECK-TLS-POWERPC64 %s
+// RUN: %clang -### -target powerpc64le-unknown-elf -mstack-protector-guard=global %s 2>&1 | \
+// RUN: FileCheck -check-prefix=CHECK-GLOBAL %s
+
+// RUN: not %clang -target powerpc64le-unknown-elf -mstack-protector-guard=tls %s 2>&1 | \
+// RUN: FileCheck -check-prefix=MISSING-OFFSET %s
+
+// RUN: not %clang -target powerpc64le-unknown-elf -mstack-protector-guard=sysreg %s 2>&1 | \
+// RUN: FileCheck -check-prefix=INVALID-VALUE2 %s
+
+// RUN: not %clang -target powerpc64le-unknown-elf -mstack-protector-guard=tls \
+// RUN: -mstack-protector-guard-offset=20 -mstack-protector-guard-reg=r12 %s 2>&1 | \
+// RUN: FileCheck -check-prefix=INVALID-REG-POWERPC64 %s
+
+// RUN: %clang -### -target ppc32-unknown-elf -mstack-protector-guard=tls -mstack-protector-guard-offset=24 -mstack-protector-guard-reg=r2 %s 2>&1 | \
+// RUN: FileCheck -v -check-prefix=CHECK-TLS-POWERPC32 %s
+// RUN: %clang -### -target ppc32-unknown-elf -mstack-protector-guard=global %s 2>&1 | \
+// RUN: FileCheck -check-prefix=CHECK-GLOBAL %s
+
+// RUN: not %clang -target ppc32-unknown-elf -mstack-protector-guard=tls %s 2>&1 | \
+// RUN: FileCheck -check-prefix=MISSING-OFFSET %s
+
+// RUN: not %clang -target ppc32-unknown-elf -mstack-protector-guard=sysreg %s 2>&1 | \
+// RUN: FileCheck -check-prefix=INVALID-VALUE2 %s
+
+// RUN: not %clang -target ppc32-unknown-elf -mstack-protector-guard=tls \
+// RUN: -mstack-protector-guard-offset=20 -mstack-protector-guard-reg=r3 %s 2>&1 | \
+// RUN: FileCheck -check-prefix=INVALID-REG-POWERPC32 %s
+
+// CHECK-TLS-POWERPC32: "-cc1" {{.*}}"-mstack-protector-guard=tls" "-mstack-protector-guard-offset=24" "-mstack-protector-guard-reg=r2"
+// INVALID-REG-POWERPC32: error: invalid value 'r3' in 'mstack-protector-guard-reg=', expected one of: r2
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index d9847a21489e63..455b62aed4c027 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -17913,6 +17913,27 @@ Value *PPCTargetLowering::getSDagStackGuard(const Module &M) const {
return TargetLowering::getSDagStackGuard(M);
}
+static Value *useTpOffset(IRBuilderBase &IRB, unsigned Offset) {
+ Module *M = IRB.GetInsertBlock()->getModule();
+ Function *ThreadPointerFunc =
+ Intrinsic::getDeclaration(M, Intrinsic::thread_pointer);
+ return IRB.CreateConstGEP1_32(IRB.getInt8Ty(),
+ IRB.CreateCall(ThreadPointerFunc), Offset);
+}
+
+Value *PPCTargetLowering::getIRStackGuard(IRBuilderBase &IRB) const {
+ Module *M = IRB.GetInsertBlock()->getModule();
+
+ if (M->getStackProtectorGuard() == "tls") {
+ // Specially, some users may customize the base reg and offset.
+ int Offset = M->getStackProtectorGuardOffset();
+ return useTpOffset(IRB, Offset);
+ }
+
+ return TargetLowering::getIRStackGuard(IRB);
+}
+
+
bool PPCTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
bool ForCodeSize) const {
if (!VT.isSimple() || !Subtarget.hasVSX())
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.h b/llvm/lib/Target/PowerPC/PPCISelLowering.h
index 8907c3c5a81c3c..8d993d467f2b00 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.h
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.h
@@ -1140,6 +1140,7 @@ namespace llvm {
bool useLoadStackGuardNode() const override;
void insertSSPDeclarations(Module &M) const override;
Value *getSDagStackGuard(const Module &M) const override;
+ Value *getIRStackGuard(IRBuilderBase &IRB) const override;
bool isFPImmLegal(const APFloat &Imm, EVT VT,
bool ForCodeSize) const override;
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 4f77bba2968988..a0f885695c2051 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -21304,7 +21304,7 @@ bool RISCVTargetLowering::preferScalarizeSplat(SDNode *N) const {
}
static Value *useTpOffset(IRBuilderBase &IRB, unsigned Offset) {
- Module *M = IRB.GetInsertBlock()->getParent()->getParent();
+ Module *M = IRB.GetInsertBlock()->getModule();
Function *ThreadPointerFunc =
Intrinsic::getDeclaration(M, Intrinsic::thread_pointer);
return IRB.CreateConstGEP1_32(IRB.getInt8Ty(),
@@ -21323,6 +21323,14 @@ Value *RISCVTargetLowering::getIRStackGuard(IRBuilderBase &IRB) const {
if (Subtarget.isTargetAndroid())
return useTpOffset(IRB, -0x18);
+ Module *M = IRB.GetInsertBlock()->getModule();
+
+ if (M->getStackProtectorGuard() == "tls") {
+ // Users must specify the offset explicitly
+ int Offset = M->getStackProtectorGuardOffset();
+ return useTpOffset(IRB, Offset);
+ }
+
return TargetLowering::getIRStackGuard(IRB);
}
diff --git a/llvm/test/CodeGen/PowerPC/stack-guard-global.ll b/llvm/test/CodeGen/PowerPC/stack-guard-global.ll
new file mode 100644
index 00000000000000..022a62a4b0918d
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/stack-guard-global.ll
@@ -0,0 +1,122 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -mtriple=powerpc64 -verify-machineinstrs < %s \
+; RUN: | FileCheck %s --check-prefixes=BE64
+; RUN: llc -mtriple=powerpc64le -verify-machineinstrs < %s \
+; RUN: | FileCheck %s --check-prefixes=LE64
+; RUN: llc -mtriple=ppc32 -verify-machineinstrs < %s \
+; RUN: | FileCheck %s --check-prefixes=LE32
+
+define void @foo(i64 %t) sspstrong nounwind {
+; BE64-LABEL: foo:
+; BE64: # %bb.0:
+; BE64-NEXT: mflr 0
+; BE64-NEXT: std 31, -8(1)
+; BE64-NEXT: stdu 1, -144(1)
+; BE64-NEXT: mr 31, 1
+; BE64-NEXT: std 0, 160(1)
+; BE64-NEXT: std 30, 128(31) # 8-byte Folded Spill
+; BE64-NEXT: addis 30, 2, __stack_chk_guard@toc@ha
+; BE64-NEXT: sldi 3, 3, 2
+; BE64-NEXT: ld 4, __stack_chk_guard@toc@l(30)
+; BE64-NEXT: addi 3, 3, 15
+; BE64-NEXT: rldicr 3, 3, 0, 59
+; BE64-NEXT: neg 3, 3
+; BE64-NEXT: std 4, 120(31)
+; BE64-NEXT: addi 4, 31, 144
+; BE64-NEXT: stdux 4, 1, 3
+; BE64-NEXT: addi 3, 1, 112
+; BE64-NEXT: bl baz
+; BE64-NEXT: nop
+; BE64-NEXT: ld 3, __stack_chk_guard@toc@l(30)
+; BE64-NEXT: ld 4, 120(31)
+; BE64-NEXT: cmpld 3, 4
+; BE64-NEXT: bne 0, .LBB0_2
+; BE64-NEXT: # %bb.1:
+; BE64-NEXT: ld 30, 128(31) # 8-byte Folded Reload
+; BE64-NEXT: ld 1, 0(1)
+; BE64-NEXT: ld 0, 16(1)
+; BE64-NEXT: ld 31, -8(1)
+; BE64-NEXT: mtlr 0
+; BE64-NEXT: blr
+; BE64-NEXT: .LBB0_2:
+; BE64-NEXT: bl __stack_chk_fail
+; BE64-NEXT: nop
+;
+; LE64-LABEL: foo:
+; LE64: # %bb.0:
+; LE64-NEXT: mflr 0
+; LE64-NEXT: std 31, -8(1)
+; LE64-NEXT: stdu 1, -64(1)
+; LE64-NEXT: mr 31, 1
+; LE64-NEXT: sldi 3, 3, 2
+; LE64-NEXT: std 0, 80(1)
+; LE64-NEXT: std 30, 48(31) # 8-byte Folded Spill
+; LE64-NEXT: addis 30, 2, __stack_chk_guard@toc@ha
+; LE64-NEXT: addi 3, 3, 15
+; LE64-NEXT: ld 4, __stack_chk_guard@toc@l(30)
+; LE64-NEXT: rldicr 3, 3, 0, 59
+; LE64-NEXT: neg 3, 3
+; LE64-NEXT: std 4, 40(31)
+; LE64-NEXT: addi 4, 31, 64
+; LE64-NEXT: stdux 4, 1, 3
+; LE64-NEXT: addi 3, 1, 32
+; LE64-NEXT: bl baz
+; LE64-NEXT: nop
+; LE64-NEXT: ld 3, __stack_chk_guard@toc@l(30)
+; LE64-NEXT: ld 4, 40(31)
+; LE64-NEXT: cmpld 3, 4
+; LE64-NEXT: bne 0, .LBB0_2
+; LE64-NEXT: # %bb.1:
+; LE64-NEXT: ld 30, 48(31) # 8-byte Folded Reload
+; LE64-NEXT: ld 1, 0(1)
+; LE64-NEXT: ld 0, 16(1)
+; LE64-NEXT: ld 31, -8(1)
+; LE64-NEXT: mtlr 0
+; LE64-NEXT: blr
+; LE64-NEXT: .LBB0_2:
+; LE64-NEXT: bl __stack_chk_fail
+; LE64-NEXT: nop
+;
+; LE32-LABEL: foo:
+; LE32: # %bb.0:
+; LE32-NEXT: mflr 0
+; LE32-NEXT: stwu 1, -32(1)
+; LE32-NEXT: stw 31, 28(1)
+; LE32-NEXT: mr 31, 1
+; LE32-NEXT: stw 0, 36(1)
+; LE32-NEXT: slwi 4, 4, 2
+; LE32-NEXT: stw 30, 24(31) # 4-byte Folded Spill
+; LE32-NEXT: lis 30, __stack_chk_guard@ha
+; LE32-NEXT: lwz 3, __stack_chk_guard@l(30)
+; LE32-NEXT: addi 4, 4, 15
+; LE32-NEXT: rlwinm 4, 4, 0, 0, 27
+; LE32-NEXT: neg 4, 4
+; LE32-NEXT: stw 3, 20(31)
+; LE32-NEXT: addi 3, 31, 32
+; LE32-NEXT: stwux 3, 1, 4
+; LE32-NEXT: addi 3, 1, 16
+; LE32-NEXT: bl baz
+; LE32-NEXT: lwz 3, __stack_chk_guard@l(30)
+; LE32-NEXT: lwz 4, 20(31)
+; LE32-NEXT: cmplw 3, 4
+; LE32-NEXT: bne 0, .LBB0_2
+; LE32-NEXT: # %bb.1:
+; LE32-NEXT: lwz 30, 24(31) # 4-byte Folded Reload
+; LE32-NEXT: lwz 31, 0(1)
+; LE32-NEXT: lwz 0, -4(31)
+; LE32-NEXT: mr 1, 31
+; LE32-NEXT: mr 31, 0
+; LE32-NEXT: lwz 0, 4(1)
+; LE32-NEXT: mtlr 0
+; LE32-NEXT: blr
+; LE32-NEXT: .LBB0_2:
+; LE32-NEXT: bl __stack_chk_fail
+ %vla = alloca i32, i64 %t, align 4
+ call void @baz(ptr %vla)
+ ret void
+}
+
+declare void @baz(ptr)
+
+!llvm.module.flags = !{!1}
+!1 = !{i32 2, !"stack-protector-guard", !"global"}
diff --git a/llvm/test/CodeGen/PowerPC/stack-guard-tls.ll b/llvm/test/CodeGen/PowerPC/stack-guard-tls.ll
new file mode 100644
index 00000000000000..fa50db0607f9aa
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/stack-guard-tls.ll
@@ -0,0 +1,114 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -mtriple=powerpc64 -verify-machineinstrs < %s \
+; RUN: | FileCheck %s --check-prefixes=BE64
+; RUN: llc -mtriple=powerpc64le -verify-machineinstrs < %s \
+; RUN: | FileCheck %s --check-prefixes=LE64
+; RUN: llc -mtriple=ppc32 -verify-machineinstrs < %s \
+; RUN: | FileCheck %s --check-prefixes=LE32
+
+define void @foo(i64 %t) sspstrong nounwind {
+; BE64-LABEL: foo:
+; BE64: # %bb.0:
+; BE64-NEXT: mflr 0
+; BE64-NEXT: std 31, -8(1)
+; BE64-NEXT: stdu 1, -144(1)
+; BE64-NEXT: std 0, 160(1)
+; BE64-NEXT: sldi 3, 3, 2
+; BE64-NEXT: mr 31, 1
+; BE64-NEXT: ld 4, 500(13)
+; BE64-NEXT: addi 3, 3, 15
+; BE64-NEXT: rldicr 3, 3, 0, 59
+; BE64-NEXT: neg 3, 3
+; BE64-NEXT: std 4, 128(31)
+; BE64-NEXT: addi 4, 31, 144
+; BE64-NEXT: stdux 4, 1, 3
+; BE64-NEXT: addi 3, 1, 112
+; BE64-NEXT: bl baz
+; BE64-NEXT: nop
+; BE64-NEXT: ld 3, 500(13)
+; BE64-NEXT: ld 4, 128(31)
+; BE64-NEXT: cmpld 3, 4
+; BE64-NEXT: bne- 0, .LBB0_2
+; BE64-NEXT: # %bb.1: # %SP_return
+; BE64-NEXT: ld 1, 0(1)
+; BE64-NEXT: ld 0, 16(1)
+; BE64-NEXT: ld 31, -8(1)
+; BE64-NEXT: mtlr 0
+; BE64-NEXT: blr
+; BE64-NEXT: .LBB0_2: # %CallStackCheckFailBlk
+; BE64-NEXT: bl __stack_chk_fail
+; BE64-NEXT: nop
+;
+; LE64-LABEL: foo:
+; LE64: # %bb.0:
+; LE64-NEXT: mflr 0
+; LE64-NEXT: std 31, -8(1)
+; LE64-NEXT: stdu 1, -64(1)
...
[truncated]
|
!EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC64() && | ||
!EffectiveTriple.isPPC32()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason not to use EffectiveTriple.isPPC()
instead of both EffectiveTriple.isPPC32()
and EffectiveTriple.isPPC64()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
None at all -- I started adding just PPC64 support and realized that it would be easy to just do both 32 and 64 in the same series, but didn't go back and re-factor. Thanks for catching this. I've rebased on top of main so that the RISC-V changes aren't mixed into this PR.
7dcfa3c
to
e81fc45
Compare
✅ With the latest revision this PR passed the C/C++ code formatter. |
Add support for using a thread-local variable with a specified offset for holding the stack guard canary value. Signed-off-by: Keith Packard <[email protected]>
Add tests ensuring that the driver correctly handles stack protector guard options. Signed-off-by: Keith Packard <[email protected]>
Make sure the code generated for a TLS-relative stack guard canary references the right location before and after intervening function code. Signed-off-by: Keith Packard <[email protected]>
Make sure the code generated for a global stack guard canary references __stack_chk_guard before and after intervening function code. Signed-off-by: Keith Packard <[email protected]>
e81fc45
to
c4ce586
Compare
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.