Skip to content
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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
18 changes: 14 additions & 4 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3605,7 +3605,7 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
StringRef Value = A->getValue();
if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
!EffectiveTriple.isRISCV())
!EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC())
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< A->getAsString(Args) << TripleStr;
if ((EffectiveTriple.isX86() || EffectiveTriple.isARM() ||
Expand Down Expand Up @@ -3645,7 +3645,7 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
<< A->getOption().getName() << Value << "sysreg global";
return;
}
if (EffectiveTriple.isRISCV()) {
if (EffectiveTriple.isRISCV() || EffectiveTriple.isPPC()) {
if (Value != "tls" && Value != "global") {
D.Diag(diag::err_drv_invalid_value_with_suggestion)
<< A->getOption().getName() << Value << "tls global";
Expand All @@ -3666,7 +3666,7 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
StringRef Value = A->getValue();
if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
!EffectiveTriple.isRISCV())
!EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC())
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< A->getAsString(Args) << TripleStr;
int Offset;
Expand All @@ -3686,7 +3686,7 @@ 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() &&
!EffectiveTriple.isRISCV())
!EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC())
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< A->getAsString(Args) << TripleStr;
if (EffectiveTriple.isX86() && (Value != "fs" && Value != "gs")) {
Expand All @@ -3703,6 +3703,16 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
<< 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);
}

Expand Down
16 changes: 16 additions & 0 deletions clang/test/CodeGen/stack-protector-guard.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@
// 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
// RUN: %clang_cc1 -mstack-protector-guard=tls -triple ppc32-unknown-elf \
// RUN: -mstack-protector-guard-offset=16 -mstack-protector-guard-reg=r2 \
// RUN: -emit-llvm %s -o - | FileCheck %s --check-prefix=POWERPC32
void foo(int*);
void bar(int x) {
int baz[x];
Expand All @@ -31,3 +37,13 @@ void bar(int x) {
// 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: [[ATTR2]] = !{i32 1, !"stack-protector-guard", !"tls"}
// POWERPC64: [[ATTR3]] = !{i32 1, !"stack-protector-guard-reg", !"r13"}
// POWERPC64: [[ATTR4]] = !{i32 1, !"stack-protector-guard-offset", i32 52}

// POWERPC32: !llvm.module.flags = !{{{.*}}[[ATTR1:![0-9]+]], [[ATTR2:![0-9]+]], [[ATTR3:![0-9]+]], [[ATTR4:![0-9]+]]}
// POWERPC32: [[ATTR2]] = !{i32 1, !"stack-protector-guard", !"tls"}
// POWERPC32: [[ATTR3]] = !{i32 1, !"stack-protector-guard-reg", !"r2"}
// POWERPC32: [[ATTR4]] = !{i32 1, !"stack-protector-guard-offset", i32 16}
57 changes: 54 additions & 3 deletions clang/test/Driver/stack-protector-guard.c
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -104,3 +104,54 @@
// 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
20 changes: 20 additions & 0 deletions llvm/lib/Target/PowerPC/PPCISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17913,6 +17913,26 @@ 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())
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/PowerPC/PPCISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
122 changes: 122 additions & 0 deletions llvm/test/CodeGen/PowerPC/stack-guard-global.ll
Original file line number Diff line number Diff line change
@@ -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"}
Loading
Loading