Skip to content

[PowerPC] Support -fpatchable-function-entry on PPC64LE #151569

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

maryammo
Copy link
Contributor

This patch enables -fpatchable-function-entry on PPC64 little-endian Linux. It is mutually exclusive with existing XRay instrumentation on this target.

@maryammo maryammo self-assigned this Jul 31, 2025
@maryammo maryammo requested a review from RolandF77 July 31, 2025 17:59
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Jul 31, 2025
@maryammo maryammo requested a review from w2yehia July 31, 2025 17:59
@llvmbot
Copy link
Member

llvmbot commented Jul 31, 2025

@llvm/pr-subscribers-clang

@llvm/pr-subscribers-backend-powerpc

Author: Maryam Moghadas (maryammo)

Changes

This patch enables -fpatchable-function-entry on PPC64 little-endian Linux. It is mutually exclusive with existing XRay instrumentation on this target.


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

7 Files Affected:

  • (modified) clang/include/clang/Basic/Attr.td (+1-1)
  • (modified) clang/include/clang/Basic/AttrDocs.td (+1-1)
  • (modified) clang/lib/Driver/ToolChains/Clang.cpp (+2-1)
  • (modified) clang/test/Driver/fpatchable-function-entry.c (+1)
  • (modified) clang/test/Sema/patchable-function-entry-attr.cpp (+1-1)
  • (modified) llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp (+7-5)
  • (modified) llvm/test/CodeGen/PowerPC/patchable-function-entry.ll (+49)
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 fefdaba7f8bf5..b61f65fd6466d 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 456bfe885f354..e89d97ad9e622 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -6771,7 +6771,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 a091b21f4a791..2f903251244a2 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@toc@ha
+; PC64LE-NEXT:     ld 3, .LC0@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

@maryammo maryammo requested a review from diggerlin July 31, 2025 17:59
This patch enables `-fpatchable-function-entry` on PPC64 little-endian Linux.
It is mutually exclusive with existing XRay instrumentation on this target.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:PowerPC clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants