Skip to content

Conversation

@cuviper
Copy link
Member

@cuviper cuviper commented Aug 21, 2025

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.

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.
@llvmbot
Copy link
Member

llvmbot commented Aug 21, 2025

@llvm/pr-subscribers-backend-powerpc

Author: Josh Stone (cuviper)

Changes

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.


Full diff: https://github.com/llvm/llvm-project/pull/154654.diff

2 Files Affected:

  • (modified) llvm/lib/Target/PowerPC/PPCInstrInfo.td (+2-1)
  • (added) llvm/test/CodeGen/PowerPC/tls-picgot.ll (+31)
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
index c2f91ce8e6b96..80b187eaf6062 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
@@ -3235,7 +3235,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}

Copy link
Contributor

@amy-kwan amy-kwan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@tstellar tstellar merged commit e6ae4e6 into llvm:main Aug 25, 2025
11 checks passed
@nikic nikic added this to the LLVM 21.x Release milestone Aug 26, 2025
@github-project-automation github-project-automation bot moved this to Needs Triage in LLVM Release Status Aug 26, 2025
@nikic
Copy link
Contributor

nikic commented Aug 26, 2025

/cherry-pick e6ae4e6

@llvmbot
Copy link
Member

llvmbot commented Aug 26, 2025

/pull-request #155361

@llvmbot llvmbot moved this from Needs Triage to Done in LLVM Release Status Aug 26, 2025
tru pushed a commit to llvmbot/llvm-project that referenced this pull request Aug 26, 2025
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 e6ae4e6)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Development

Successfully merging this pull request may close these issues.

5 participants