[clang] 4321300 - [PowerPC] Support -fpatchable-function-entry (#92997)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Jul 21 17:51:55 PDT 2024
Author: Chen Zheng
Date: 2024-07-22T08:51:51+08:00
New Revision: 43213002b99e32d618f2afbbaaeb2ff8dfc84e33
URL: https://github.com/llvm/llvm-project/commit/43213002b99e32d618f2afbbaaeb2ff8dfc84e33
DIFF: https://github.com/llvm/llvm-project/commit/43213002b99e32d618f2afbbaaeb2ff8dfc84e33.diff
LOG: [PowerPC] Support -fpatchable-function-entry (#92997)
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
Added:
llvm/test/CodeGen/PowerPC/patchable-function-entry.ll
Modified:
clang/include/clang/Basic/Attr.td
clang/include/clang/Basic/AttrDocs.td
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Driver/ToolChains/Clang.cpp
clang/lib/Sema/SemaDeclAttr.cpp
clang/test/Driver/fpatchable-function-entry.c
clang/test/Sema/patchable-function-entry-attr.cpp
llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 1293d0ddbc117..4825979a974d2 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -902,7 +902,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 09cf4f80bd999..99738812c8157 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -5800,7 +5800,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 d60f32674ca3a..dd9dc912ef4ca 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3492,7 +3492,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 364e55a628c34..601f7a355297d 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -6666,7 +6666,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 50e7be9ea6020..5fd8622c90dd8 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -5247,6 +5247,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 (!S.checkUInt32Argument(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 ab04fd39ffa1c..5f07ca99a69de 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.cpp b/clang/test/Sema/patchable-function-entry-attr.cpp
index 9134c851da588..bd4d57a7e3093 100644
--- a/clang/test/Sema/patchable-function-entry-attr.cpp
+++ b/clang/test/Sema/patchable-function-entry-attr.cpp
@@ -6,9 +6,14 @@
// 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
+// 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
// silence-no-diagnostics
+// AIX-error at +2 {{'patchable_function_entry' attribute is not yet supported on AIX}}
// expected-warning at +1 {{unknown attribute 'patchable_function_entry' ignored}}
[[gnu::patchable_function_entry(0)]] void f();
diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
index d74143b487880..753f0d586a0d9 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -909,6 +909,23 @@ 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 = MF->getFunction();
+ unsigned Num = 0;
+ (void)F.getFnAttribute("patchable-function-entry")
+ .getValueAsString()
+ .getAsInteger(10, Num);
+ if (!Num)
+ return;
+ emitNops(Num);
+ return;
+ }
case TargetOpcode::DBG_VALUE:
llvm_unreachable("Should be handled target independently");
case TargetOpcode::STACKMAP:
@@ -1780,7 +1797,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]
@@ -1793,6 +1810,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);
@@ -1909,6 +1929,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..0c2d2829a6d4b
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/patchable-function-entry.ll
@@ -0,0 +1,58 @@
+; RUN: llc -mtriple=powerpc %s -o - | FileCheck %s --check-prefixes=CHECK,PPC32
+; RUN: llc -mtriple=powerpc64 %s -o - | FileCheck %s --check-prefixes=CHECK,PPC64
+
+ at a = global i32 0, align 4
+
+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 i32 @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
+; PPC32: lis 3, a at ha
+; PPC32-NEXT: lwz 3, a at l(3)
+; PPC64: addis 3, 2, .LC0 at toc@ha
+; PPC64-NEXT: ld 3, .LC0 at toc@l(3)
+; PPC64-NEXT: lwz 3, 0(3)
+; CHECK: blr
+; CHECK: .section __patchable_function_entries
+; PPC32: .p2align 2, 0x0
+; PPC64: .p2align 3, 0x0
+; PPC32-NEXT: .long .Ltmp0
+; PPC64-NEXT: .quad .Ltmp0
+entry:
+ %0 = load i32, ptr @a, align 4
+ ret i32 %0
+}
More information about the cfe-commits
mailing list