https://github.com/llvmbot created https://github.com/llvm/llvm-project/pull/155361
Backport e6ae4e689cd6511987aecd1d0678cad317ea3f33 Requested by: @nikic >From dd491e74c62a7db1052bf43d26459e259249c1e5 Mon Sep 17 00:00:00 2001 From: Josh Stone <[email protected]> Date: Mon, 25 Aug 2025 15:31:27 -0700 Subject: [PATCH] [PowerPC] Indicate that PPC32PICGOT clobbers LR (#154654) This pseudo-instruction emits a local `bl` writing LR, so that must be saved and restored for the function to return to the right place. If not, we'll return to the inline `.long` that the `bl` stepped over. This fixes the `SIGILL` seen in rayon-rs/rayon#1268. (cherry picked from commit e6ae4e689cd6511987aecd1d0678cad317ea3f33) --- llvm/lib/Target/PowerPC/PPCInstrInfo.td | 3 ++- llvm/test/CodeGen/PowerPC/tls-picgot.ll | 31 +++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 llvm/test/CodeGen/PowerPC/tls-picgot.ll diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td index 99ef89a7fdc0c..dbbf06f471533 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td @@ -3252,7 +3252,8 @@ def PPC32GOT: PPCEmitTimePseudo<(outs gprc:$rD), (ins), "#PPC32GOT", // Get the _GLOBAL_OFFSET_TABLE_ in PIC mode. // This uses two output registers, the first as the real output, the second as a -// temporary register, used internally in code generation. +// temporary register, used internally in code generation. A "bl" also clobbers LR. +let Defs = [LR] in def PPC32PICGOT: PPCEmitTimePseudo<(outs gprc:$rD, gprc:$rT), (ins), "#PPC32PICGOT", []>, NoEncode<"$rT">; diff --git a/llvm/test/CodeGen/PowerPC/tls-picgot.ll b/llvm/test/CodeGen/PowerPC/tls-picgot.ll new file mode 100644 index 0000000000000..6562d864d1ba7 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/tls-picgot.ll @@ -0,0 +1,31 @@ +; RUN: llc -verify-machineinstrs -relocation-model=pic < %s | FileCheck %s + +target triple = "powerpc-unknown-linux-gnu" + +; Test that LR is preserved when PPC32PICGOT clobbers it with a local "bl". + +@TLS = external thread_local global i8 + +; CHECK-LABEL: tls_addr: +; CHECK: mflr [[SAVED_REG:[0-9]+]] + +; CHECK: bl [[JUMP:\.L[[:alnum:]_]+]] +; CHECK-NEXT: [[OFFSET:\.L[[:alnum:]_]+]]: +; CHECK-NEXT: .long _GLOBAL_OFFSET_TABLE_-[[OFFSET]] +; CHECK-NEXT: [[JUMP]] +; CHECK-NEXT: mflr {{[0-9]+}} + +; CHECK: mtlr [[SAVED_REG]] +; CHECK-NEXT: blr + +define ptr @tls_addr() unnamed_addr { + %1 = call ptr @llvm.threadlocal.address.p0(ptr @TLS) + ret ptr %1 +} + +declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull) + +!llvm.module.flags = !{!0, !1} + +!0 = !{i32 8, !"PIC Level", i32 2} +!1 = !{i32 7, !"PIE Level", i32 2} _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
