https://github.com/maryammo created 
https://github.com/llvm/llvm-project/pull/151569

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

>From 6a380fa9789412e561a1b5ae976f7b312090571f Mon Sep 17 00:00:00 2001
From: Maryam Moghadas <marya...@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 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

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to