File: powerpc-fix-SIGILL.diff

package info (click to toggle)
llvm-toolchain-19 1%3A19.1.7-9
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 1,999,196 kB
  • sloc: cpp: 6,951,711; ansic: 1,486,157; asm: 913,598; python: 232,024; f90: 80,126; objc: 75,281; lisp: 37,276; pascal: 16,990; sh: 10,033; ml: 5,058; perl: 4,724; awk: 3,523; makefile: 3,248; javascript: 2,504; xml: 892; fortran: 664; cs: 573
file content (70 lines) | stat: -rw-r--r-- 2,571 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
From 9b15701c8add66db542f66fe20a5a0e9caef7e4d Mon Sep 17 00:00:00 2001
From: Josh Stone <jistone@redhat.com>
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.
---
 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 69f8ddc0ea70..151df8800aa9 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
@@ -3224,7 +3224,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 000000000000..6562d864d1ba
--- /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}
-- 
2.51.0