Skip to content

Commit 7bbd096

Browse files
author
Chen Zheng
committed
[PowerPC] Support -fpatchable-function-entry
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 #63220 Fixes #57031
1 parent 203232f commit 7bbd096

File tree

10 files changed

+96
-7
lines changed

10 files changed

+96
-7
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -892,7 +892,7 @@ def PatchableFunctionEntry
892892
: InheritableAttr,
893893
TargetSpecificAttr<TargetArch<
894894
["aarch64", "aarch64_be", "loongarch32", "loongarch64", "riscv32",
895-
"riscv64", "x86", "x86_64"]>> {
895+
"riscv64", "x86", "x86_64", "ppc", "ppc64"]>> {
896896
let Spellings = [GCC<"patchable_function_entry">];
897897
let Subjects = SubjectList<[Function, ObjCMethod]>;
898898
let Args = [UnsignedArgument<"Count">, DefaultIntArgument<"Offset", 0>];

clang/include/clang/Basic/AttrDocs.td

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5799,7 +5799,8 @@ takes precedence over the command line option ``-fpatchable-function-entry=N,M``
57995799
``M`` defaults to 0 if omitted.
58005800

58015801
This attribute is only supported on
5802-
aarch64/aarch64-be/loongarch32/loongarch64/riscv32/riscv64/i386/x86-64 targets.
5802+
aarch64/aarch64-be/loongarch32/loongarch64/riscv32/riscv64/i386/x86-64/ppc/ppc64 targets.
5803+
For ppc/ppc64 targets, AIX is still not supported.
58035804
}];
58045805
}
58055806

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3470,7 +3470,7 @@ def err_attr_tlsmodel_arg : Error<"tls_model must be \"global-dynamic\", "
34703470

34713471
def err_attr_codemodel_arg : Error<"code model '%0' is not supported on this target">;
34723472

3473-
def err_aix_attr_unsupported_tls_model : Error<"TLS model '%0' is not yet supported on AIX">;
3473+
def err_aix_attr_unsupported : Error<"%0 attribute is not yet supported on AIX">;
34743474

34753475
def err_tls_var_aligned_over_maximum : Error<
34763476
"alignment (%0) of thread-local variable %1 is greater than the maximum supported "

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6681,7 +6681,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
66816681
StringRef S0 = A->getValue(), S = S0;
66826682
unsigned Size, Offset = 0;
66836683
if (!Triple.isAArch64() && !Triple.isLoongArch() && !Triple.isRISCV() &&
6684-
!Triple.isX86())
6684+
!Triple.isX86() &&
6685+
!(!Triple.isOSAIX() && (Triple.getArch() == llvm::Triple::ppc ||
6686+
Triple.getArch() == llvm::Triple::ppc64)))
66856687
D.Diag(diag::err_drv_unsupported_opt_for_target)
66866688
<< A->getAsString(Args) << TripleStr;
66876689
else if (S.consumeInteger(10, Size) ||

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5922,6 +5922,10 @@ static void handleXRayLogArgsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
59225922

59235923
static void handlePatchableFunctionEntryAttr(Sema &S, Decl *D,
59245924
const ParsedAttr &AL) {
5925+
if (S.Context.getTargetInfo().getTriple().isOSAIX()) {
5926+
S.Diag(AL.getLoc(), diag::err_aix_attr_unsupported) << AL;
5927+
return;
5928+
}
59255929
uint32_t Count = 0, Offset = 0;
59265930
if (!checkUInt32Argument(S, AL, AL.getArgAsExpr(0), Count, 0, true))
59275931
return;

clang/test/Driver/fpatchable-function-entry.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,20 @@
66
// RUN: %clang -target loongarch64 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s
77
// RUN: %clang -target riscv32 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s
88
// RUN: %clang -target riscv64 %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s
9+
// RUN: %clang -target powerpc-unknown-linux-gnu %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s
10+
// RUN: %clang -target powerpc64-unknown-linux-gnu %s -fpatchable-function-entry=1,0 -c -### 2>&1 | FileCheck %s
911
// CHECK: "-fpatchable-function-entry=1"
1012

1113
// RUN: %clang -target aarch64 -fsyntax-only %s -fpatchable-function-entry=1,1 -c -### 2>&1 | FileCheck --check-prefix=11 %s
1214
// 11: "-fpatchable-function-entry=1" "-fpatchable-function-entry-offset=1"
1315
// RUN: %clang -target aarch64 -fsyntax-only %s -fpatchable-function-entry=2,1 -c -### 2>&1 | FileCheck --check-prefix=21 %s
1416
// 21: "-fpatchable-function-entry=2" "-fpatchable-function-entry-offset=1"
1517

16-
// RUN: not %clang -target ppc64 -fsyntax-only %s -fpatchable-function-entry=1 2>&1 | FileCheck --check-prefix=TARGET %s
17-
// TARGET: error: unsupported option '-fpatchable-function-entry=1' for target 'ppc64'
18+
// RUN: not %clang -target powerpc64-ibm-aix-xcoff -fsyntax-only %s -fpatchable-function-entry=1 2>&1 | FileCheck --check-prefix=AIX64 %s
19+
// AIX64: error: unsupported option '-fpatchable-function-entry=1' for target 'powerpc64-ibm-aix-xcoff'
20+
21+
// RUN: not %clang -target powerpc-ibm-aix-xcoff -fsyntax-only %s -fpatchable-function-entry=1 2>&1 | FileCheck --check-prefix=AIX32 %s
22+
// AIX32: error: unsupported option '-fpatchable-function-entry=1' for target 'powerpc-ibm-aix-xcoff'
1823

1924
// RUN: not %clang -target x86_64 -fsyntax-only %s -fpatchable-function-entry=1,0, 2>&1 | FileCheck --check-prefix=EXCESS %s
2025
// EXCESS: error: invalid argument '1,0,' to -fpatchable-function-entry=
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -fsyntax-only -verify %s
2+
3+
// expected-error@+1 {{'patchable_function_entry' attribute is not yet supported on AIX}}
4+
__attribute__((patchable_function_entry(0))) void f();

clang/test/Sema/patchable-function-entry-attr.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
// RUN: %clang_cc1 -triple loongarch64 -fsyntax-only -verify=silence %s
77
// RUN: %clang_cc1 -triple riscv32 -fsyntax-only -verify=silence %s
88
// RUN: %clang_cc1 -triple riscv64 -fsyntax-only -verify=silence %s
9+
// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -fsyntax-only -verify=silence %s
10+
// RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu -fsyntax-only -verify=silence %s
911
// RUN: %clang_cc1 -triple ppc64le -fsyntax-only -verify %s
1012

1113
// silence-no-diagnostics

llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,24 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
909909
// Lower multi-instruction pseudo operations.
910910
switch (MI->getOpcode()) {
911911
default: break;
912+
case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
913+
assert(!Subtarget->isAIXABI() &&
914+
"AIX does not support patchable function entry!");
915+
// PATCHABLE_FUNCTION_ENTER on little endian is for XRAY support which is
916+
// handled in PPCLinuxAsmPrinter.
917+
if (MAI->isLittleEndian())
918+
return;
919+
const Function &F = MI->getParent()->getParent()->getFunction();
920+
if (F.hasFnAttribute("patchable-function-entry")) {
921+
unsigned Num = 0;
922+
if (F.getFnAttribute("patchable-function-entry")
923+
.getValueAsString()
924+
.getAsInteger(10, Num))
925+
return;
926+
emitNops(Num);
927+
return;
928+
}
929+
}
912930
case TargetOpcode::DBG_VALUE:
913931
llvm_unreachable("Should be handled target independently");
914932
case TargetOpcode::STACKMAP:
@@ -1781,7 +1799,7 @@ void PPCLinuxAsmPrinter::emitInstruction(const MachineInstr *MI) {
17811799

17821800
switch (MI->getOpcode()) {
17831801
default:
1784-
return PPCAsmPrinter::emitInstruction(MI);
1802+
break;
17851803
case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
17861804
// .begin:
17871805
// b .end # lis 0, FuncId[16..32]
@@ -1794,6 +1812,9 @@ void PPCLinuxAsmPrinter::emitInstruction(const MachineInstr *MI) {
17941812
//
17951813
// Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
17961814
// of instructions change.
1815+
// XRAY is only supported on PPC Linux little endian.
1816+
if (!MAI->isLittleEndian())
1817+
break;
17971818
MCSymbol *BeginOfSled = OutContext.createTempSymbol();
17981819
MCSymbol *EndOfSled = OutContext.createTempSymbol();
17991820
OutStreamer->emitLabel(BeginOfSled);
@@ -1910,6 +1931,7 @@ void PPCLinuxAsmPrinter::emitInstruction(const MachineInstr *MI) {
19101931
llvm_unreachable("Tail call is handled in the normal case. See comments "
19111932
"around this assert.");
19121933
}
1934+
return PPCAsmPrinter::emitInstruction(MI);
19131935
}
19141936

19151937
void PPCLinuxAsmPrinter::emitStartOfAsmFile(Module &M) {
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
; RUN: llc -mtriple=powerpc-unknown-linux-gnu %s -o - | FileCheck %s --check-prefixes=CHECK,PPC32
2+
; RUN: llc -mtriple=powerpc64-unknown-linux-gnu %s -o - | FileCheck %s --check-prefixes=CHECK,PPC64
3+
4+
define void @f0() {
5+
; CHECK-LABEL: f0:
6+
; CHECK-NOT: nop
7+
; CHECK: # %bb.0:
8+
; CHECK-NEXT: blr
9+
; CHECK-NOT: .section __patchable_function_entries
10+
ret void
11+
}
12+
13+
define void @f1() "patchable-function-entry"="0" {
14+
; CHECK-LABEL: f1:
15+
; CHECK-NOT: nop
16+
; CHECK: # %bb.0:
17+
; CHECK-NEXT: blr
18+
; CHECK-NOT: .section __patchable_function_entries
19+
ret void
20+
}
21+
22+
define void @f2() "patchable-function-entry"="1" {
23+
; CHECK-LABEL: f2:
24+
; CHECK-LABEL-NEXT: .Lfunc_begin2:
25+
; CHECK: # %bb.0:
26+
; CHECK-NEXT: nop
27+
; CHECK-NEXT: blr
28+
; CHECK: .section __patchable_function_entries
29+
; PPC32: .p2align 2, 0x0
30+
; PPC64: .p2align 3, 0x0
31+
; PPC32-NEXT: .long .Lfunc_begin2
32+
; PPC64-NEXT: .quad .Lfunc_begin2
33+
ret void
34+
}
35+
36+
define void @f3() "patchable-function-entry"="1" "patchable-function-prefix"="2" {
37+
; CHECK-LABEL: .Ltmp0:
38+
; CHECK-COUNT-2: nop
39+
; CHECK-LABEL: f3:
40+
; CHECK: # %bb.0:
41+
; CHECK-NEXT: nop
42+
; CHECK-NEXT: blr
43+
; CHECK: .section __patchable_function_entries
44+
; PPC32: .p2align 2, 0x0
45+
; PPC64: .p2align 3, 0x0
46+
; PPC32-NEXT: .long .Ltmp0
47+
; PPC64-NEXT: .quad .Ltmp0
48+
ret void
49+
}

0 commit comments

Comments
 (0)