https://github.com/keith-packard updated https://github.com/llvm/llvm-project/pull/110928
>From 05c0a80977564496094a55ca0ca0b54b8048a30b Mon Sep 17 00:00:00 2001 From: Keith Packard <kei...@keithp.com> Date: Mon, 16 Sep 2024 15:41:38 +0200 Subject: [PATCH 1/5] [PowerPC][ISelLowering] Support -mstack-protector-guard=tls Add support for using a thread-local variable with a specified offset for holding the stack guard canary value. To keep Linux targets from also getting another load due to LOAD_STACK_GUARD, kill that instruction when using "tls" mode. We can't use LOAD_STACK_GUARD for this new case as that is gated by useLoadStackGuardNode() and that function doesn't have a reference to the Module where we could test for "tls" mode. Signed-off-by: Keith Packard <kei...@keithp.com> --- clang/lib/Driver/ToolChains/Clang.cpp | 18 ++++++++++++++---- llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 20 ++++++++++++++++++++ llvm/lib/Target/PowerPC/PPCISelLowering.h | 1 + llvm/lib/Target/PowerPC/PPCInstrInfo.cpp | 6 ++++++ 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index c9baca00ec6f3b..2b465915054a0c 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -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() || @@ -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"; @@ -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; @@ -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")) { @@ -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); } diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index d9847a21489e63..089c866af11b5e 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -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()) 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/PowerPC/PPCInstrInfo.cpp b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp index 48833e8f88066c..73d7d9ac35f029 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp @@ -35,6 +35,7 @@ #include "llvm/CodeGen/ScheduleDAG.h" #include "llvm/CodeGen/SlotIndexes.h" #include "llvm/CodeGen/StackMaps.h" +#include "llvm/IR/Module.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/TargetRegistry.h" @@ -3107,6 +3108,11 @@ bool PPCInstrInfo::expandPostRAPseudo(MachineInstr &MI) const { return true; } case TargetOpcode::LOAD_STACK_GUARD: { + const Module *M = MI.getParent()->getBasicBlock()->getModule(); + if (M->getStackProtectorGuard() == "tls") { + MI.setDesc(get(PPC::UNENCODED_NOP)); + return true; + } assert(Subtarget.isTargetLinux() && "Only Linux target is expected to contain LOAD_STACK_GUARD"); const int64_t Offset = Subtarget.isPPC64() ? -0x7010 : -0x7008; >From af3f73112c47abd3d5500edf891b93c45a111030 Mon Sep 17 00:00:00 2001 From: Keith Packard <kei...@keithp.com> Date: Mon, 16 Sep 2024 11:27:19 -0700 Subject: [PATCH 2/5] [clang][PowerPC] Add stack protector tests Add tests ensuring that the driver correctly handles stack protector guard options. Signed-off-by: Keith Packard <kei...@keithp.com> --- clang/test/CodeGen/stack-protector-guard.c | 16 ++++++ clang/test/Driver/stack-protector-guard.c | 57 ++++++++++++++++++++-- 2 files changed, 70 insertions(+), 3 deletions(-) diff --git a/clang/test/CodeGen/stack-protector-guard.c b/clang/test/CodeGen/stack-protector-guard.c index 4777367c94e733..82616ae800c426 100644 --- a/clang/test/CodeGen/stack-protector-guard.c +++ b/clang/test/CodeGen/stack-protector-guard.c @@ -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]; @@ -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} diff --git a/clang/test/Driver/stack-protector-guard.c b/clang/test/Driver/stack-protector-guard.c index d8475a70e3709f..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 @@ -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 >From d3eb1db1f831c0562465699f4c3609183d980630 Mon Sep 17 00:00:00 2001 From: Keith Packard <kei...@keithp.com> Date: Mon, 16 Sep 2024 12:36:06 -0700 Subject: [PATCH 3/5] [CodeGen][PowerPC] Add codegen test for TLS stack canary 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 <kei...@keithp.com> --- llvm/test/CodeGen/PowerPC/stack-guard-tls.ll | 114 +++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 llvm/test/CodeGen/PowerPC/stack-guard-tls.ll 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) +; LE64-NEXT: sldi 3, 3, 2 +; LE64-NEXT: std 0, 80(1) +; LE64-NEXT: mr 31, 1 +; LE64-NEXT: addi 3, 3, 15 +; LE64-NEXT: ld 4, 500(13) +; LE64-NEXT: rldicr 3, 3, 0, 59 +; LE64-NEXT: std 4, 48(31) +; LE64-NEXT: addi 4, 31, 64 +; LE64-NEXT: neg 3, 3 +; LE64-NEXT: stdux 4, 1, 3 +; LE64-NEXT: addi 3, 1, 32 +; LE64-NEXT: bl baz +; LE64-NEXT: nop +; LE64-NEXT: ld 3, 500(13) +; LE64-NEXT: ld 4, 48(31) +; LE64-NEXT: cmpld 3, 4 +; LE64-NEXT: bne- 0, .LBB0_2 +; LE64-NEXT: # %bb.1: # %SP_return +; 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: # %CallStackCheckFailBlk +; 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: slwi 4, 4, 2 +; LE32-NEXT: stw 0, 36(1) +; LE32-NEXT: addi 4, 4, 15 +; LE32-NEXT: lwz 3, 500(2) +; LE32-NEXT: mr 31, 1 +; LE32-NEXT: rlwinm 4, 4, 0, 0, 27 +; LE32-NEXT: neg 4, 4 +; LE32-NEXT: stw 3, 24(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, 500(2) +; LE32-NEXT: lwz 4, 24(31) +; LE32-NEXT: cmplw 3, 4 +; LE32-NEXT: bne- 0, .LBB0_2 +; LE32-NEXT: # %bb.1: # %SP_return +; 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: # %CallStackCheckFailBlk +; 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, !2} +!1 = !{i32 2, !"stack-protector-guard", !"tls"} +!2 = !{i32 2, !"stack-protector-guard-offset", i32 500} >From 98fed04135e9ca347d634e25a12fffe63b37b312 Mon Sep 17 00:00:00 2001 From: Keith Packard <kei...@keithp.com> Date: Mon, 23 Sep 2024 11:34:21 -0700 Subject: [PATCH 4/5] [CodeGen][PowerPC] Add codegen test for global stack canary 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 <kei...@keithp.com> --- .../CodeGen/PowerPC/stack-guard-global.ll | 122 ++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 llvm/test/CodeGen/PowerPC/stack-guard-global.ll 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"} >From deecdc5ee92ea3173fef4acf52b107619b0237d8 Mon Sep 17 00:00:00 2001 From: Keith Packard <kei...@keithp.com> Date: Sun, 6 Oct 2024 23:19:30 -0700 Subject: [PATCH 5/5] [PowerPC] Provide Module to useLoadStackGuardNode Use of LOAD_STACK_GUARD may depend upon compilation parameters; the Module has access to all of the stack guard parameter methods. Allow targets to only implement the old interface by providing a wrapper. Mark the old interface protected to catch callers who fail to pass the Module. Signed-off-by: Keith Packard <kei...@keithp.com> --- llvm/include/llvm/CodeGen/TargetLowering.h | 11 +++++++++-- llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 4 ++-- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 7 ++++--- llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 4 ++-- llvm/lib/Target/PowerPC/PPCISelLowering.h | 2 +- 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h index 3842af56e6b3d7..9f0ddf8ec6a7e6 100644 --- a/llvm/include/llvm/CodeGen/TargetLowering.h +++ b/llvm/include/llvm/CodeGen/TargetLowering.h @@ -5586,8 +5586,8 @@ class TargetLowering : public TargetLoweringBase { /// If this function returns true, SelectionDAGBuilder emits a /// LOAD_STACK_GUARD node when it is lowering Intrinsic::stackprotector. - virtual bool useLoadStackGuardNode() const { - return false; + virtual bool useLoadStackGuardNode(const Module &M) const { + return useLoadStackGuardNode(); } virtual SDValue emitStackGuardXorFP(SelectionDAG &DAG, SDValue Val, @@ -5616,7 +5616,14 @@ class TargetLowering : public TargetLoweringBase { return true; } +protected: + // Simple interface for targets without a Module dependency + virtual bool useLoadStackGuardNode() const { + return false; + } + private: + SDValue foldSetCCWithAnd(EVT VT, SDValue N0, SDValue N1, ISD::CondCode Cond, const SDLoc &DL, DAGCombinerInfo &DCI) const; SDValue foldSetCCWithBinOp(EVT VT, SDValue N0, SDValue N1, ISD::CondCode Cond, diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index 40360b0b0f1d86..7b57db1222249a 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -2377,7 +2377,7 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID, case Intrinsic::stackprotector: { LLT PtrTy = getLLTForType(*CI.getArgOperand(0)->getType(), *DL); Register GuardVal; - if (TLI->useLoadStackGuardNode()) { + if (TLI->useLoadStackGuardNode(*CI.getModule())) { GuardVal = MRI->createGenericVirtualRegister(PtrTy); getStackGuard(GuardVal, MIRBuilder); } else @@ -3868,7 +3868,7 @@ bool IRTranslator::emitSPDescriptorParent(StackProtectorDescriptor &SPD, // If useLoadStackGuardNode returns true, generate LOAD_STACK_GUARD. // Otherwise, emit a volatile load to retrieve the stack guard value. - if (TLI->useLoadStackGuardNode()) { + if (TLI->useLoadStackGuardNode(*ParentBB->getBasicBlock()->getModule())) { Guard = MRI->createGenericVirtualRegister(LLT::scalar(PtrTy.getSizeInBits())); getStackGuard(Guard, *CurBuilder); diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 25213f587116d5..138058ce192470 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -3138,7 +3138,7 @@ void SelectionDAGBuilder::visitSPDescriptorParent(StackProtectorDescriptor &SPD, // If useLoadStackGuardNode returns true, generate LOAD_STACK_GUARD. // Otherwise, emit a volatile load to retrieve the stack guard value. SDValue Chain = DAG.getEntryNode(); - if (TLI.useLoadStackGuardNode()) { + if (TLI.useLoadStackGuardNode(M)) { Guard = getLoadStackGuard(DAG, dl, Chain); } else { const Value *IRGuard = TLI.getSDagStackGuard(M); @@ -7331,7 +7331,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, const Module &M = *MF.getFunction().getParent(); EVT PtrTy = TLI.getValueType(DAG.getDataLayout(), I.getType()); SDValue Chain = getRoot(); - if (TLI.useLoadStackGuardNode()) { + if (TLI.useLoadStackGuardNode(M)) { Res = getLoadStackGuard(DAG, sdl, Chain); Res = DAG.getPtrExtOrTrunc(Res, sdl, PtrTy); } else { @@ -7351,9 +7351,10 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, // Emit code into the DAG to store the stack guard onto the stack. MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo &MFI = MF.getFrameInfo(); + const Module &M = *MF.getFunction().getParent(); SDValue Src, Chain = getRoot(); - if (TLI.useLoadStackGuardNode()) + if (TLI.useLoadStackGuardNode(M)) Src = getLoadStackGuard(DAG, sdl, Chain); else Src = getValue(I.getArgOperand(0)); // The guard's value. diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index 089c866af11b5e..f72fb2009068f5 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -17889,8 +17889,8 @@ SDValue PPCTargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG, } // Override to enable LOAD_STACK_GUARD lowering on Linux. -bool PPCTargetLowering::useLoadStackGuardNode() const { - if (!Subtarget.isTargetLinux()) +bool PPCTargetLowering::useLoadStackGuardNode(const Module &M) const { + if (M.getStackProtectorGuard() == "tls" || !Subtarget.isTargetLinux()) return TargetLowering::useLoadStackGuardNode(); return true; } diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.h b/llvm/lib/Target/PowerPC/PPCISelLowering.h index 8d993d467f2b00..1a26633ea427e8 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.h +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.h @@ -1137,7 +1137,7 @@ namespace llvm { getExceptionSelectorRegister(const Constant *PersonalityFn) const override; /// Override to support customized stack guard loading. - bool useLoadStackGuardNode() const override; + bool useLoadStackGuardNode(const Module &M) const override; void insertSSPDeclarations(Module &M) const override; Value *getSDagStackGuard(const Module &M) const override; Value *getIRStackGuard(IRBuilderBase &IRB) const override; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits