https://github.com/chenzheng1030 updated https://github.com/llvm/llvm-project/pull/92997
>From 7c1e44455a343cef3c5ab0da22c997188ffff8cf Mon Sep 17 00:00:00 2001 From: Chen Zheng <czhen...@cn.ibm.com> Date: Wed, 22 May 2024 02:37:04 -0400 Subject: [PATCH 1/3] [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 --- clang/include/clang/Basic/Attr.td | 2 +- clang/include/clang/Basic/AttrDocs.td | 3 +- .../clang/Basic/DiagnosticSemaKinds.td | 2 +- clang/lib/Driver/ToolChains/Clang.cpp | 4 +- clang/lib/Sema/SemaDeclAttr.cpp | 4 ++ clang/test/Driver/fpatchable-function-entry.c | 9 +++- .../patchable-function-entry-attr-aix.cpp | 4 ++ .../Sema/patchable-function-entry-attr.cpp | 2 + llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp | 24 ++++++++- .../PowerPC/patchable-function-entry.ll | 49 +++++++++++++++++++ 10 files changed, 96 insertions(+), 7 deletions(-) create mode 100644 clang/test/Sema/patchable-function-entry-attr-aix.cpp create mode 100644 llvm/test/CodeGen/PowerPC/patchable-function-entry.ll diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index e59cccccdd369..c85a6690d6ad9 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 a313e811c9d21..b7858a5ce0247 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -5796,7 +5796,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 270b0a1e01307..31c3a6007a1a1 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 18de8781e894a..e1023477653b9 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 5041fd65286fa..5c7cb08060061 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 ab04fd39ffa1c..26ec4669ccb77 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 f4e84ade3b5ac..81019357561ab 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 +} >From 94a0b343a4674bb3beaeadb257094e6e03fb70d0 Mon Sep 17 00:00:00 2001 From: Chen Zheng <czhen...@cn.ibm.com> Date: Wed, 22 May 2024 22:44:23 -0400 Subject: [PATCH 2/3] address comments --- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp index 81019357561ab..30981e2e70a49 100644 --- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -916,16 +916,15 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) { // 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); + 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"); >From 0552f8506f628dc7c7f2e8e2ef0c136b28882a0e Mon Sep 17 00:00:00 2001 From: Chen Zheng <czhen...@cn.ibm.com> Date: Fri, 24 May 2024 05:39:11 -0400 Subject: [PATCH 3/3] address comments --- clang/test/Driver/fpatchable-function-entry.c | 4 ++-- .../patchable-function-entry-attr-aix.cpp | 4 ---- .../Sema/patchable-function-entry-attr.cpp | 3 +++ .../PowerPC/patchable-function-entry.ll | 19 ++++++++++++++----- 4 files changed, 19 insertions(+), 11 deletions(-) delete mode 100644 clang/test/Sema/patchable-function-entry-attr-aix.cpp diff --git a/clang/test/Driver/fpatchable-function-entry.c b/clang/test/Driver/fpatchable-function-entry.c index 26ec4669ccb77..5f07ca99a69de 100644 --- a/clang/test/Driver/fpatchable-function-entry.c +++ b/clang/test/Driver/fpatchable-function-entry.c @@ -15,10 +15,10 @@ // 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 powerpc64-ibm-aix-xcoff -fsyntax-only %s -fpatchable-function-entry=1 2>&1 | FileCheck --check-prefix=AIX64 %s +// 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 +// 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 diff --git a/clang/test/Sema/patchable-function-entry-attr-aix.cpp b/clang/test/Sema/patchable-function-entry-attr-aix.cpp deleted file mode 100644 index 648ad739b1df7..0000000000000 --- a/clang/test/Sema/patchable-function-entry-attr-aix.cpp +++ /dev/null @@ -1,4 +0,0 @@ -// 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 c08293dfe6672..bd4d57a7e3093 100644 --- a/clang/test/Sema/patchable-function-entry-attr.cpp +++ b/clang/test/Sema/patchable-function-entry-attr.cpp @@ -9,8 +9,11 @@ // 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@+2 {{'patchable_function_entry' attribute is not yet supported on AIX}} // expected-warning@+1 {{unknown attribute 'patchable_function_entry' ignored}} [[gnu::patchable_function_entry(0)]] void f(); diff --git a/llvm/test/CodeGen/PowerPC/patchable-function-entry.ll b/llvm/test/CodeGen/PowerPC/patchable-function-entry.ll index 088b616eb77fc..0c2d2829a6d4b 100644 --- a/llvm/test/CodeGen/PowerPC/patchable-function-entry.ll +++ b/llvm/test/CodeGen/PowerPC/patchable-function-entry.ll @@ -1,5 +1,7 @@ -; 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 +; RUN: llc -mtriple=powerpc %s -o - | FileCheck %s --check-prefixes=CHECK,PPC32 +; RUN: llc -mtriple=powerpc64 %s -o - | FileCheck %s --check-prefixes=CHECK,PPC64 + +@a = global i32 0, align 4 define void @f0() { ; CHECK-LABEL: f0: @@ -33,17 +35,24 @@ define void @f2() "patchable-function-entry"="1" { ret void } -define void @f3() "patchable-function-entry"="1" "patchable-function-prefix"="2" { +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 -; CHECK-NEXT: blr +; PPC32: lis 3, a@ha +; PPC32-NEXT: lwz 3, a@l(3) +; PPC64: addis 3, 2, .LC0@toc@ha +; PPC64-NEXT: ld 3, .LC0@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 - ret void +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