[clang] [llvm] [PowerPC] Support `-fpatchable-function-entry` on PPC64LE (PR #151569)
Maryam Moghadas via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 31 13:48:09 PDT 2025
https://github.com/maryammo updated https://github.com/llvm/llvm-project/pull/151569
>From 30bbcebb5a3be58b55229f8eda80423813bcd623 Mon Sep 17 00:00:00 2001
From: Maryam Moghadas <maryammo at ca.ibm.com>
Date: Thu, 31 Jul 2025 17:54:42 +0000
Subject: [PATCH] [PowerPC] Support `-fpatchable-function-entry` on PPC64LE
This patch enables `-fpatchable-function-entry` on PPC64 little-endian Linux.
It is mutually exclusive with existing XRay instrumentation on this target.
---
clang/include/clang/Basic/Attr.td | 2 +-
clang/include/clang/Basic/AttrDocs.td | 2 +-
clang/lib/Driver/ToolChains/Clang.cpp | 3 +-
clang/test/Driver/fpatchable-function-entry.c | 1 +
.../Sema/patchable-function-entry-attr.cpp | 2 +-
llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp | 12 +++--
.../PowerPC/patchable-function-entry.ll | 49 +++++++++++++++++++
7 files changed, 62 insertions(+), 9 deletions(-)
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 224cb6a32af28..f495706030a0e 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -954,7 +954,7 @@ def PatchableFunctionEntry
: InheritableAttr,
TargetSpecificAttr<TargetArch<
["aarch64", "aarch64_be", "loongarch32", "loongarch64", "riscv32",
- "riscv64", "x86", "x86_64", "ppc", "ppc64"]>> {
+ "riscv64", "x86", "x86_64", "ppc", "ppc64", "ppc64le"]>> {
let Spellings = [GCC<"patchable_function_entry">];
let Subjects = SubjectList<[Function, ObjCMethod]>;
let Args = [UnsignedArgument<"Count">, DefaultIntArgument<"Offset", 0>,
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index 76747d2b11811..b1f664c99c2dd 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -6567,7 +6567,7 @@ if omitted.``Section`` defaults to the ``-fpatchable-function-entry`` section n
set, or to ``__patchable_function_entries`` otherwise.
This attribute is only supported on
-aarch64/aarch64-be/loongarch32/loongarch64/riscv32/riscv64/i386/x86-64/ppc/ppc64 targets.
+aarch64/aarch64-be/loongarch32/loongarch64/riscv32/riscv64/i386/x86-64/ppc/ppc64/ppc64le targets.
For ppc/ppc64 targets, AIX is still not supported.
}];
}
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 4e1b1d9e33621..b008a0cc4a916 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -6744,7 +6744,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (!Triple.isAArch64() && !Triple.isLoongArch() && !Triple.isRISCV() &&
!Triple.isX86() &&
!(!Triple.isOSAIX() && (Triple.getArch() == llvm::Triple::ppc ||
- Triple.getArch() == llvm::Triple::ppc64)))
+ Triple.getArch() == llvm::Triple::ppc64 ||
+ Triple.getArch() == llvm::Triple::ppc64le)))
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< A->getAsString(Args) << TripleStr;
else if (S.consumeInteger(10, Size) ||
diff --git a/clang/test/Driver/fpatchable-function-entry.c b/clang/test/Driver/fpatchable-function-entry.c
index 43be6c5a47e47..5248a7c008812 100644
--- a/clang/test/Driver/fpatchable-function-entry.c
+++ b/clang/test/Driver/fpatchable-function-entry.c
@@ -8,6 +8,7 @@
// RUN: %clang --target=riscv64 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s
// RUN: %clang --target=powerpc-unknown-linux-gnu %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s
// RUN: %clang --target=powerpc64-unknown-linux-gnu %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s
+// RUN: %clang --target=powerpc64le-unknown-linux-gnu %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s
// CHECK: "-fpatchable-function-entry=1"
// RUN: %clang --target=aarch64 -fsyntax-only %s -fpatchable-function-entry=1,1 -c -### 2>&1 | FileCheck --check-prefix=11 %s
diff --git a/clang/test/Sema/patchable-function-entry-attr.cpp b/clang/test/Sema/patchable-function-entry-attr.cpp
index 7498e67de302d..97b9c26af1edb 100644
--- a/clang/test/Sema/patchable-function-entry-attr.cpp
+++ b/clang/test/Sema/patchable-function-entry-attr.cpp
@@ -8,7 +8,7 @@
// RUN: %clang_cc1 -triple riscv64 -fsyntax-only -verify=silence %s
// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -fsyntax-only -verify=silence %s
// RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu -fsyntax-only -verify=silence %s
-// RUN: %clang_cc1 -triple ppc64le -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple ppc64le -fsyntax-only -verify=silence %s
// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -fsyntax-only -verify=AIX %s
// RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -fsyntax-only -verify=AIX %s
diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
index ce1d51a0de091..357d2bd6c17f0 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -920,10 +920,6 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
assert(!Subtarget->isAIXABI() &&
"AIX does not support patchable function entry!");
- // PATCHABLE_FUNCTION_ENTER on little endian is for XRAY support which is
- // handled in PPCLinuxAsmPrinter.
- if (MAI->isLittleEndian())
- return;
const Function &F = MF->getFunction();
unsigned Num = 0;
(void)F.getFnAttribute("patchable-function-entry")
@@ -1789,7 +1785,13 @@ void PPCLinuxAsmPrinter::emitInstruction(const MachineInstr *MI) {
// Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
// of instructions change.
// XRAY is only supported on PPC Linux little endian.
- if (!MAI->isLittleEndian())
+ const Function &F = MF->getFunction();
+ unsigned Num = 0;
+ (void)F.getFnAttribute("patchable-function-entry")
+ .getValueAsString()
+ .getAsInteger(10, Num);
+
+ if (!MAI->isLittleEndian() || Num)
break;
MCSymbol *BeginOfSled = OutContext.createTempSymbol();
MCSymbol *EndOfSled = OutContext.createTempSymbol();
diff --git a/llvm/test/CodeGen/PowerPC/patchable-function-entry.ll b/llvm/test/CodeGen/PowerPC/patchable-function-entry.ll
index 0c2d2829a6d4b..f5977543784f9 100644
--- a/llvm/test/CodeGen/PowerPC/patchable-function-entry.ll
+++ b/llvm/test/CodeGen/PowerPC/patchable-function-entry.ll
@@ -1,5 +1,6 @@
; RUN: llc -mtriple=powerpc %s -o - | FileCheck %s --check-prefixes=CHECK,PPC32
; RUN: llc -mtriple=powerpc64 %s -o - | FileCheck %s --check-prefixes=CHECK,PPC64
+; RUN: llc -mtriple=powerpc64le %s -o - | FileCheck %s --check-prefix=PPC64LE
@a = global i32 0, align 4
@@ -9,6 +10,12 @@ define void @f0() {
; CHECK: # %bb.0:
; CHECK-NEXT: blr
; CHECK-NOT: .section __patchable_function_entries
+;
+; PPC64LE-LABEL: f0:
+; PPC64LE-NOT: nop
+; PPC64LE: # %bb.0:
+; PPC64LE-NEXT: blr
+; PPC64LE-NOT: .section __patchable_function_entries
ret void
}
@@ -18,6 +25,22 @@ define void @f1() "patchable-function-entry"="0" {
; CHECK: # %bb.0:
; CHECK-NEXT: blr
; CHECK-NOT: .section __patchable_function_entries
+;
+; PPC64LE-LABEL: f1:
+; PPC64LE: # %bb.0:
+; PPC64LE-NEXT: .Ltmp0:
+; PPC64LE-NEXT: b .Ltmp1
+; PPC64LE-NEXT: nop
+; PPC64LE-NEXT: std 0, -8(1)
+; PPC64LE-NEXT: mflr 0
+; PPC64LE-NEXT: bl __xray_FunctionEntry
+; PPC64LE-NEXT: nop
+; PPC64LE-NEXT: mtlr 0
+; PPC64LE-NEXT: .Ltmp1:
+; PPC64LE-NEXT: blr
+; PPC64LE-NOT: .section __patchable_function_entries
+; PPC64LE: .section xray_instr_map
+; PPC64LE: .section xray_fn_idx
ret void
}
@@ -32,6 +55,17 @@ define void @f2() "patchable-function-entry"="1" {
; PPC64: .p2align 3, 0x0
; PPC32-NEXT: .long .Lfunc_begin2
; PPC64-NEXT: .quad .Lfunc_begin2
+;
+; PPC64LE-LABEL: f2:
+; PPC64LE-LABEL-NEXT: .Lfunc_begin2:
+; PPC64LE: # %bb.0:
+; PPC64LE-NEXT: nop
+; PPC64LE-NEXT: blr
+; PPC64LE: .section __patchable_function_entries
+; PPC64LE: .p2align 3, 0x0
+; PPC64LE-NEXT: .quad .Lfunc_begin2
+; PPC64LE-NOT: .section xray_instr_map
+; PPC64LE-NOT: .section xray_fn_idx
ret void
}
@@ -52,6 +86,21 @@ define i32 @f3() "patchable-function-entry"="1" "patchable-function-prefix"="2"
; PPC64: .p2align 3, 0x0
; PPC32-NEXT: .long .Ltmp0
; PPC64-NEXT: .quad .Ltmp0
+;
+; PC64LE-LABEL: .Ltmp3:
+; PC64LE-COUNT-2: nop
+; PC64LE-LABEL: f3:
+; PC64LE: # %bb.0:
+; PC64LE-NEXT: nop
+; PC64LE: addis 3, 2, .LC0 at toc@ha
+; PC64LE-NEXT: ld 3, .LC0 at toc@l(3)
+; PC64LE-NEXT: lwz 3, 0(3)
+; PC64LE: blr
+; PC64LE: .section __patchable_function_entries
+; PPC64LE: .p2align 3, 0x0
+; PPC64LE-NEXT: .quad .Ltmp3
+; PC64LE-NOT: .section xray_instr_map
+; PC64LE-NOT: .section xray_fn_idx
entry:
%0 = load i32, ptr @a, align 4
ret i32 %0
More information about the llvm-commits
mailing list