-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[PowerPC] Support -fpatchable-function-entry #92997
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
Conversation
@llvm/pr-subscribers-clang @llvm/pr-subscribers-backend-powerpc Author: Chen Zheng (chenzheng1030) ChangesFor now only PPC big endian Linux 32 and 64 bit are supported. PPC little endian Linux has XRAY support for 64-bit. Fixes #63220 Full diff: https://github.com/llvm/llvm-project/pull/92997.diff 10 Files Affected:
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 7008bea483c87..e98d0edb6fca0 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -892,7 +892,7 @@ def PatchableFunctionEntry
: InheritableAttr,
TargetSpecificAttr<TargetArch<
["aarch64", "aarch64_be", "loongarch32", "loongarch64", "riscv32",
- "riscv64", "x86", "x86_64"]>> {
+ "riscv64", "x86", "x86_64", "ppc", "ppc64"]>> {
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 54197d588eb45..fe566cc25bd0d 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -5799,7 +5799,8 @@ takes precedence over the command line option ``-fpatchable-function-entry=N,M``
``M`` defaults to 0 if omitted.
This attribute is only supported on
-aarch64/aarch64-be/loongarch32/loongarch64/riscv32/riscv64/i386/x86-64 targets.
+aarch64/aarch64-be/loongarch32/loongarch64/riscv32/riscv64/i386/x86-64/ppc/ppc64 targets.
+For ppc/ppc64 targets, AIX is still not supported.
}];
}
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 5a32463763aa6..b807eda3862b2 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3470,7 +3470,7 @@ def err_attr_tlsmodel_arg : Error<"tls_model must be \"global-dynamic\", "
def err_attr_codemodel_arg : Error<"code model '%0' is not supported on this target">;
-def err_aix_attr_unsupported_tls_model : Error<"TLS model '%0' is not yet supported on AIX">;
+def err_aix_attr_unsupported : Error<"%0 attribute is not yet supported on AIX">;
def err_tls_var_aligned_over_maximum : Error<
"alignment (%0) of thread-local variable %1 is greater than the maximum supported "
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 6d2015b2cd156..c7fa6d9a0ffe8 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -6681,7 +6681,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
StringRef S0 = A->getValue(), S = S0;
unsigned Size, Offset = 0;
if (!Triple.isAArch64() && !Triple.isLoongArch() && !Triple.isRISCV() &&
- !Triple.isX86())
+ !Triple.isX86() &&
+ !(!Triple.isOSAIX() && (Triple.getArch() == llvm::Triple::ppc ||
+ Triple.getArch() == llvm::Triple::ppc64)))
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< A->getAsString(Args) << TripleStr;
else if (S.consumeInteger(10, Size) ||
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index ca5938083917f..17c17032ef96b 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -5922,6 +5922,10 @@ static void handleXRayLogArgsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
static void handlePatchableFunctionEntryAttr(Sema &S, Decl *D,
const ParsedAttr &AL) {
+ if (S.Context.getTargetInfo().getTriple().isOSAIX()) {
+ S.Diag(AL.getLoc(), diag::err_aix_attr_unsupported) << AL;
+ return;
+ }
uint32_t Count = 0, Offset = 0;
if (!checkUInt32Argument(S, AL, AL.getArgAsExpr(0), Count, 0, true))
return;
diff --git a/clang/test/Driver/fpatchable-function-entry.c b/clang/test/Driver/fpatchable-function-entry.c
index 4d0d609584c8d..8df3311f33b0e 100644
--- a/clang/test/Driver/fpatchable-function-entry.c
+++ b/clang/test/Driver/fpatchable-function-entry.c
@@ -6,6 +6,8 @@
// RUN: %clang -target loongarch64 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s
// RUN: %clang -target riscv32 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s
// 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
// 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
@@ -13,8 +15,11 @@
// RUN: %clang -target aarch64 -fsyntax-only %s -fpatchable-function-entry=2,1 -c -### 2>&1 | FileCheck --check-prefix=21 %s
// 21: "-fpatchable-function-entry=2" "-fpatchable-function-entry-offset=1"
-// RUN: not %clang -target ppc64 -fsyntax-only %s -fpatchable-function-entry=1 2>&1 | FileCheck --check-prefix=TARGET %s
-// TARGET: error: unsupported option '-fpatchable-function-entry=1' for target 'ppc64'
+// RUN: not %clang -target powerpc64-ibm-aix-xcoff -fsyntax-only %s -fpatchable-function-entry=1 2>&1 | FileCheck --check-prefix=AIX64 %s
+// AIX64: error: unsupported option '-fpatchable-function-entry=1' for target 'powerpc64-ibm-aix-xcoff'
+
+// RUN: not %clang -target powerpc-ibm-aix-xcoff -fsyntax-only %s -fpatchable-function-entry=1 2>&1 | FileCheck --check-prefix=AIX32 %s
+// AIX32: error: unsupported option '-fpatchable-function-entry=1' for target 'powerpc-ibm-aix-xcoff'
// RUN: not %clang -target x86_64 -fsyntax-only %s -fpatchable-function-entry=1,0, 2>&1 | FileCheck --check-prefix=EXCESS %s
// EXCESS: error: invalid argument '1,0,' to -fpatchable-function-entry=
diff --git a/clang/test/Sema/patchable-function-entry-attr-aix.cpp b/clang/test/Sema/patchable-function-entry-attr-aix.cpp
new file mode 100644
index 0000000000000..648ad739b1df7
--- /dev/null
+++ b/clang/test/Sema/patchable-function-entry-attr-aix.cpp
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -fsyntax-only -verify %s
+
+// expected-error@+1 {{'patchable_function_entry' attribute is not yet supported on AIX}}
+__attribute__((patchable_function_entry(0))) void f();
diff --git a/clang/test/Sema/patchable-function-entry-attr.cpp b/clang/test/Sema/patchable-function-entry-attr.cpp
index 9134c851da588..c08293dfe6672 100644
--- a/clang/test/Sema/patchable-function-entry-attr.cpp
+++ b/clang/test/Sema/patchable-function-entry-attr.cpp
@@ -6,6 +6,8 @@
// RUN: %clang_cc1 -triple loongarch64 -fsyntax-only -verify=silence %s
// RUN: %clang_cc1 -triple riscv32 -fsyntax-only -verify=silence %s
// 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
// silence-no-diagnostics
diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
index 72e8215fffaf7..76e3fc10877cd 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -909,6 +909,24 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
// Lower multi-instruction pseudo operations.
switch (MI->getOpcode()) {
default: break;
+ 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 = MI->getParent()->getParent()->getFunction();
+ if (F.hasFnAttribute("patchable-function-entry")) {
+ unsigned Num = 0;
+ if (F.getFnAttribute("patchable-function-entry")
+ .getValueAsString()
+ .getAsInteger(10, Num))
+ return;
+ emitNops(Num);
+ return;
+ }
+ }
case TargetOpcode::DBG_VALUE:
llvm_unreachable("Should be handled target independently");
case TargetOpcode::STACKMAP:
@@ -1781,7 +1799,7 @@ void PPCLinuxAsmPrinter::emitInstruction(const MachineInstr *MI) {
switch (MI->getOpcode()) {
default:
- return PPCAsmPrinter::emitInstruction(MI);
+ break;
case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
// .begin:
// b .end # lis 0, FuncId[16..32]
@@ -1794,6 +1812,9 @@ 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())
+ break;
MCSymbol *BeginOfSled = OutContext.createTempSymbol();
MCSymbol *EndOfSled = OutContext.createTempSymbol();
OutStreamer->emitLabel(BeginOfSled);
@@ -1910,6 +1931,7 @@ void PPCLinuxAsmPrinter::emitInstruction(const MachineInstr *MI) {
llvm_unreachable("Tail call is handled in the normal case. See comments "
"around this assert.");
}
+ return PPCAsmPrinter::emitInstruction(MI);
}
void PPCLinuxAsmPrinter::emitStartOfAsmFile(Module &M) {
diff --git a/llvm/test/CodeGen/PowerPC/patchable-function-entry.ll b/llvm/test/CodeGen/PowerPC/patchable-function-entry.ll
new file mode 100644
index 0000000000000..088b616eb77fc
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/patchable-function-entry.ll
@@ -0,0 +1,49 @@
+; RUN: llc -mtriple=powerpc-unknown-linux-gnu %s -o - | FileCheck %s --check-prefixes=CHECK,PPC32
+; RUN: llc -mtriple=powerpc64-unknown-linux-gnu %s -o - | FileCheck %s --check-prefixes=CHECK,PPC64
+
+define void @f0() {
+; CHECK-LABEL: f0:
+; CHECK-NOT: nop
+; CHECK: # %bb.0:
+; CHECK-NEXT: blr
+; CHECK-NOT: .section __patchable_function_entries
+ ret void
+}
+
+define void @f1() "patchable-function-entry"="0" {
+; CHECK-LABEL: f1:
+; CHECK-NOT: nop
+; CHECK: # %bb.0:
+; CHECK-NEXT: blr
+; CHECK-NOT: .section __patchable_function_entries
+ ret void
+}
+
+define void @f2() "patchable-function-entry"="1" {
+; CHECK-LABEL: f2:
+; CHECK-LABEL-NEXT: .Lfunc_begin2:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nop
+; CHECK-NEXT: blr
+; CHECK: .section __patchable_function_entries
+; PPC32: .p2align 2, 0x0
+; PPC64: .p2align 3, 0x0
+; PPC32-NEXT: .long .Lfunc_begin2
+; PPC64-NEXT: .quad .Lfunc_begin2
+ ret void
+}
+
+define void @f3() "patchable-function-entry"="1" "patchable-function-prefix"="2" {
+; CHECK-LABEL: .Ltmp0:
+; CHECK-COUNT-2: nop
+; CHECK-LABEL: f3:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nop
+; CHECK-NEXT: blr
+; CHECK: .section __patchable_function_entries
+; PPC32: .p2align 2, 0x0
+; PPC64: .p2align 3, 0x0
+; PPC32-NEXT: .long .Ltmp0
+; PPC64-NEXT: .quad .Ltmp0
+ ret void
+}
|
@llvm/pr-subscribers-clang-driver Author: Chen Zheng (chenzheng1030) ChangesFor now only PPC big endian Linux 32 and 64 bit are supported. PPC little endian Linux has XRAY support for 64-bit. Fixes #63220 Full diff: https://github.com/llvm/llvm-project/pull/92997.diff 10 Files Affected:
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 7008bea483c87..e98d0edb6fca0 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -892,7 +892,7 @@ def PatchableFunctionEntry
: InheritableAttr,
TargetSpecificAttr<TargetArch<
["aarch64", "aarch64_be", "loongarch32", "loongarch64", "riscv32",
- "riscv64", "x86", "x86_64"]>> {
+ "riscv64", "x86", "x86_64", "ppc", "ppc64"]>> {
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 54197d588eb45..fe566cc25bd0d 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -5799,7 +5799,8 @@ takes precedence over the command line option ``-fpatchable-function-entry=N,M``
``M`` defaults to 0 if omitted.
This attribute is only supported on
-aarch64/aarch64-be/loongarch32/loongarch64/riscv32/riscv64/i386/x86-64 targets.
+aarch64/aarch64-be/loongarch32/loongarch64/riscv32/riscv64/i386/x86-64/ppc/ppc64 targets.
+For ppc/ppc64 targets, AIX is still not supported.
}];
}
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 5a32463763aa6..b807eda3862b2 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3470,7 +3470,7 @@ def err_attr_tlsmodel_arg : Error<"tls_model must be \"global-dynamic\", "
def err_attr_codemodel_arg : Error<"code model '%0' is not supported on this target">;
-def err_aix_attr_unsupported_tls_model : Error<"TLS model '%0' is not yet supported on AIX">;
+def err_aix_attr_unsupported : Error<"%0 attribute is not yet supported on AIX">;
def err_tls_var_aligned_over_maximum : Error<
"alignment (%0) of thread-local variable %1 is greater than the maximum supported "
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 6d2015b2cd156..c7fa6d9a0ffe8 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -6681,7 +6681,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
StringRef S0 = A->getValue(), S = S0;
unsigned Size, Offset = 0;
if (!Triple.isAArch64() && !Triple.isLoongArch() && !Triple.isRISCV() &&
- !Triple.isX86())
+ !Triple.isX86() &&
+ !(!Triple.isOSAIX() && (Triple.getArch() == llvm::Triple::ppc ||
+ Triple.getArch() == llvm::Triple::ppc64)))
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< A->getAsString(Args) << TripleStr;
else if (S.consumeInteger(10, Size) ||
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index ca5938083917f..17c17032ef96b 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -5922,6 +5922,10 @@ static void handleXRayLogArgsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
static void handlePatchableFunctionEntryAttr(Sema &S, Decl *D,
const ParsedAttr &AL) {
+ if (S.Context.getTargetInfo().getTriple().isOSAIX()) {
+ S.Diag(AL.getLoc(), diag::err_aix_attr_unsupported) << AL;
+ return;
+ }
uint32_t Count = 0, Offset = 0;
if (!checkUInt32Argument(S, AL, AL.getArgAsExpr(0), Count, 0, true))
return;
diff --git a/clang/test/Driver/fpatchable-function-entry.c b/clang/test/Driver/fpatchable-function-entry.c
index 4d0d609584c8d..8df3311f33b0e 100644
--- a/clang/test/Driver/fpatchable-function-entry.c
+++ b/clang/test/Driver/fpatchable-function-entry.c
@@ -6,6 +6,8 @@
// RUN: %clang -target loongarch64 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s
// RUN: %clang -target riscv32 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s
// 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
// 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
@@ -13,8 +15,11 @@
// RUN: %clang -target aarch64 -fsyntax-only %s -fpatchable-function-entry=2,1 -c -### 2>&1 | FileCheck --check-prefix=21 %s
// 21: "-fpatchable-function-entry=2" "-fpatchable-function-entry-offset=1"
-// RUN: not %clang -target ppc64 -fsyntax-only %s -fpatchable-function-entry=1 2>&1 | FileCheck --check-prefix=TARGET %s
-// TARGET: error: unsupported option '-fpatchable-function-entry=1' for target 'ppc64'
+// RUN: not %clang -target powerpc64-ibm-aix-xcoff -fsyntax-only %s -fpatchable-function-entry=1 2>&1 | FileCheck --check-prefix=AIX64 %s
+// AIX64: error: unsupported option '-fpatchable-function-entry=1' for target 'powerpc64-ibm-aix-xcoff'
+
+// RUN: not %clang -target powerpc-ibm-aix-xcoff -fsyntax-only %s -fpatchable-function-entry=1 2>&1 | FileCheck --check-prefix=AIX32 %s
+// AIX32: error: unsupported option '-fpatchable-function-entry=1' for target 'powerpc-ibm-aix-xcoff'
// RUN: not %clang -target x86_64 -fsyntax-only %s -fpatchable-function-entry=1,0, 2>&1 | FileCheck --check-prefix=EXCESS %s
// EXCESS: error: invalid argument '1,0,' to -fpatchable-function-entry=
diff --git a/clang/test/Sema/patchable-function-entry-attr-aix.cpp b/clang/test/Sema/patchable-function-entry-attr-aix.cpp
new file mode 100644
index 0000000000000..648ad739b1df7
--- /dev/null
+++ b/clang/test/Sema/patchable-function-entry-attr-aix.cpp
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -fsyntax-only -verify %s
+
+// expected-error@+1 {{'patchable_function_entry' attribute is not yet supported on AIX}}
+__attribute__((patchable_function_entry(0))) void f();
diff --git a/clang/test/Sema/patchable-function-entry-attr.cpp b/clang/test/Sema/patchable-function-entry-attr.cpp
index 9134c851da588..c08293dfe6672 100644
--- a/clang/test/Sema/patchable-function-entry-attr.cpp
+++ b/clang/test/Sema/patchable-function-entry-attr.cpp
@@ -6,6 +6,8 @@
// RUN: %clang_cc1 -triple loongarch64 -fsyntax-only -verify=silence %s
// RUN: %clang_cc1 -triple riscv32 -fsyntax-only -verify=silence %s
// 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
// silence-no-diagnostics
diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
index 72e8215fffaf7..76e3fc10877cd 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -909,6 +909,24 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
// Lower multi-instruction pseudo operations.
switch (MI->getOpcode()) {
default: break;
+ 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 = MI->getParent()->getParent()->getFunction();
+ if (F.hasFnAttribute("patchable-function-entry")) {
+ unsigned Num = 0;
+ if (F.getFnAttribute("patchable-function-entry")
+ .getValueAsString()
+ .getAsInteger(10, Num))
+ return;
+ emitNops(Num);
+ return;
+ }
+ }
case TargetOpcode::DBG_VALUE:
llvm_unreachable("Should be handled target independently");
case TargetOpcode::STACKMAP:
@@ -1781,7 +1799,7 @@ void PPCLinuxAsmPrinter::emitInstruction(const MachineInstr *MI) {
switch (MI->getOpcode()) {
default:
- return PPCAsmPrinter::emitInstruction(MI);
+ break;
case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
// .begin:
// b .end # lis 0, FuncId[16..32]
@@ -1794,6 +1812,9 @@ 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())
+ break;
MCSymbol *BeginOfSled = OutContext.createTempSymbol();
MCSymbol *EndOfSled = OutContext.createTempSymbol();
OutStreamer->emitLabel(BeginOfSled);
@@ -1910,6 +1931,7 @@ void PPCLinuxAsmPrinter::emitInstruction(const MachineInstr *MI) {
llvm_unreachable("Tail call is handled in the normal case. See comments "
"around this assert.");
}
+ return PPCAsmPrinter::emitInstruction(MI);
}
void PPCLinuxAsmPrinter::emitStartOfAsmFile(Module &M) {
diff --git a/llvm/test/CodeGen/PowerPC/patchable-function-entry.ll b/llvm/test/CodeGen/PowerPC/patchable-function-entry.ll
new file mode 100644
index 0000000000000..088b616eb77fc
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/patchable-function-entry.ll
@@ -0,0 +1,49 @@
+; RUN: llc -mtriple=powerpc-unknown-linux-gnu %s -o - | FileCheck %s --check-prefixes=CHECK,PPC32
+; RUN: llc -mtriple=powerpc64-unknown-linux-gnu %s -o - | FileCheck %s --check-prefixes=CHECK,PPC64
+
+define void @f0() {
+; CHECK-LABEL: f0:
+; CHECK-NOT: nop
+; CHECK: # %bb.0:
+; CHECK-NEXT: blr
+; CHECK-NOT: .section __patchable_function_entries
+ ret void
+}
+
+define void @f1() "patchable-function-entry"="0" {
+; CHECK-LABEL: f1:
+; CHECK-NOT: nop
+; CHECK: # %bb.0:
+; CHECK-NEXT: blr
+; CHECK-NOT: .section __patchable_function_entries
+ ret void
+}
+
+define void @f2() "patchable-function-entry"="1" {
+; CHECK-LABEL: f2:
+; CHECK-LABEL-NEXT: .Lfunc_begin2:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nop
+; CHECK-NEXT: blr
+; CHECK: .section __patchable_function_entries
+; PPC32: .p2align 2, 0x0
+; PPC64: .p2align 3, 0x0
+; PPC32-NEXT: .long .Lfunc_begin2
+; PPC64-NEXT: .quad .Lfunc_begin2
+ ret void
+}
+
+define void @f3() "patchable-function-entry"="1" "patchable-function-prefix"="2" {
+; CHECK-LABEL: .Ltmp0:
+; CHECK-COUNT-2: nop
+; CHECK-LABEL: f3:
+; CHECK: # %bb.0:
+; CHECK-NEXT: nop
+; CHECK-NEXT: blr
+; CHECK: .section __patchable_function_entries
+; PPC32: .p2align 2, 0x0
+; PPC64: .p2align 3, 0x0
+; PPC32-NEXT: .long .Ltmp0
+; PPC64-NEXT: .quad .Ltmp0
+ ret void
+}
|
7bbd096
to
76db92c
Compare
In
So PPC64 can use ELFv2 for |
@@ -6681,7 +6681,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, | |||
StringRef S0 = A->getValue(), S = S0; | |||
unsigned Size, Offset = 0; | |||
if (!Triple.isAArch64() && !Triple.isLoongArch() && !Triple.isRISCV() && | |||
!Triple.isX86()) | |||
!Triple.isX86() && | |||
!(!Triple.isOSAIX() && (Triple.getArch() == llvm::Triple::ppc || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
little-endian variants (ppcle ppc64le) are omitted here.
Use isPPC
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Linux little endian targets are this patch's scope. This patch tries to support -fpatchable-function-entry for big endian targets but not AIX.
If we are going to support little endian, we first need to check the possibility about removal of XRAY. (XRAY also uses backend node PATCHABLE_FUNCTION_ENTER
)
@@ -6,15 +6,20 @@ | |||
// RUN: %clang -target loongarch64 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s | |||
// RUN: %clang -target riscv32 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s | |||
// 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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use --target=
for new tests. -target
has been deprecated for a long time
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you. Updated.
@@ -0,0 +1,49 @@ | |||
; RUN: llc -mtriple=powerpc-unknown-linux-gnu %s -o - | FileCheck %s --check-prefixes=CHECK,PPC32 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-mtriple=powerpc
. Prefer a generic ELF triple to a Linux specific one.
Suggest 2 RUN lines, powerpc
and powerpc64le
, to catch both 32-bit/64-bit and LE/BE.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, changed the triple. Little endian is not going to be supported in this patch.
define void @f3() "patchable-function-entry"="1" "patchable-function-prefix"="2" { | ||
; CHECK-LABEL: .Ltmp0: | ||
; CHECK-COUNT-2: nop | ||
; CHECK-LABEL: f3: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Test addis/addi, instructions at the global entry point.
Per https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99888#c5 #c8
and #15
, GCC will change the current strategy to match us :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated.
This patch matches the intended end result: NOPs before the global entry and after the local entry. The current way GCC handles |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So PPC64 can use ELFv2 for Triple::OpenBSD. We probably want to diagnose this OS for PPC64, since with ELFv2 we might emit separate local and global entry points which means only certain values can be passed to -fpatchable-function-entry option.
For targets with ABI elfv2 which means there are dual entries, this patch can generate expected patchable entry:
For -mtriple=powerpc64-unknown-freebsd-unknown
.Ltmp0:
nop
nop
f3: # @f3
.Lfunc_begin0:
.cfi_startproc
.Lfunc_gep0:
addis 2, 12, .TOC.-.Lfunc_gep0@ha
addi 2, 2, .TOC.-.Lfunc_gep0@l
.Lfunc_lep0:
.localentry f3, .Lfunc_lep0-.Lfunc_gep0
# %bb.0: # %entry
nop
@@ -6681,7 +6681,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, | |||
StringRef S0 = A->getValue(), S = S0; | |||
unsigned Size, Offset = 0; | |||
if (!Triple.isAArch64() && !Triple.isLoongArch() && !Triple.isRISCV() && | |||
!Triple.isX86()) | |||
!Triple.isX86() && | |||
!(!Triple.isOSAIX() && (Triple.getArch() == llvm::Triple::ppc || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Linux little endian targets are this patch's scope. This patch tries to support -fpatchable-function-entry for big endian targets but not AIX.
If we are going to support little endian, we first need to check the possibility about removal of XRAY. (XRAY also uses backend node PATCHABLE_FUNCTION_ENTER
)
@@ -6,15 +6,20 @@ | |||
// RUN: %clang -target loongarch64 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s | |||
// RUN: %clang -target riscv32 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s | |||
// 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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you. Updated.
@@ -0,0 +1,49 @@ | |||
; RUN: llc -mtriple=powerpc-unknown-linux-gnu %s -o - | FileCheck %s --check-prefixes=CHECK,PPC32 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, changed the triple. Little endian is not going to be supported in this patch.
define void @f3() "patchable-function-entry"="1" "patchable-function-prefix"="2" { | ||
; CHECK-LABEL: .Ltmp0: | ||
; CHECK-COUNT-2: nop | ||
; CHECK-LABEL: f3: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated.
For now only PPC big endian Linux is supported. PPC little endian Linux has XRAY support for 64-bit. PPC AIX has different patchable function entry implementations. Fixes llvm#63220 Fixes llvm#57031
b3abeed
to
0552f85
Compare
I see, thanks. |
Ok, so there is no NOPs between lep and gep. Thanks for verifying. |
For now only PPC big endian Linux 32 and 64 bit are supported.
PPC little endian Linux has XRAY support for 64-bit.
PPC AIX has different patchable function entry implementations.
Fixes #63220
Fixes #57031