llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-codegen Author: Chen Zheng (chenzheng1030) <details> <summary>Changes</summary> musttail does not often possible to be generated on PPC targets as when calling to a function defined in another module, PPC needs to restore the TOC pointer. To restore the TOC pointer, compiler needs to emit a nop after the call to let linker generate codes to restore TOC pointer. Tail call cannot generate expected call sequence for this case. To avoid the crash inside the compiler backend, a diagnosis is added in the frontend and in the backend, PPC will change the musttail to tail. AIX for now does not support tailcall, so on AIX musttail call attribute leads to an error instead of warning. Fixes #<!-- -->63214 --- Full diff: https://github.com/llvm/llvm-project/pull/93267.diff 5 Files Affected: - (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+5) - (modified) clang/lib/CodeGen/CGCall.cpp (+9-1) - (added) clang/test/SemaCXX/attr-musttail-ppc.cpp (+12) - (modified) llvm/lib/Target/PowerPC/PPCISelLowering.cpp (+12-3) - (added) llvm/test/CodeGen/PowerPC/musttail-call.ll (+32) ``````````diff diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index cc402182687f3..97f0cc4d9e004 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3833,6 +3833,11 @@ def note_cannot_use_trivial_abi_reason : Note< "it is polymorphic|" "it has a base of a non-trivial class type|it has a virtual base|" "it has a __weak field|it has a field of a non-trivial class type}1">; +def warn_ppc_musttail_maybe_ignored: Warning< + "'musttail' attribute may be ignored on ppc targets">, + InGroup<IgnoredAttributes>; +def err_aix_musttail_unsupported: Error< + "'musttail' attribute is not supported on AIX">; // Availability attribute def warn_availability_unknown_platform : Warning< diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 97449a5e51e73..0b6eda004a590 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -26,6 +26,7 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" #include "clang/Basic/CodeGenOptions.h" +#include "clang/Basic/DiagnosticSema.h" #include "clang/Basic/TargetInfo.h" #include "clang/CodeGen/CGFunctionInfo.h" #include "clang/CodeGen/SwiftCallingConv.h" @@ -5747,8 +5748,15 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, if (llvm::CallInst *Call = dyn_cast<llvm::CallInst>(CI)) { if (TargetDecl && TargetDecl->hasAttr<NotTailCalledAttr>()) Call->setTailCallKind(llvm::CallInst::TCK_NoTail); - else if (IsMustTail) + else if (IsMustTail) { + if (getTarget().getTriple().isPPC()) { + if (getTarget().getTriple().isOSAIX()) + CGM.getDiags().Report(Loc, diag::err_aix_musttail_unsupported); + else + CGM.getDiags().Report(Loc, diag::warn_ppc_musttail_maybe_ignored); + } Call->setTailCallKind(llvm::CallInst::TCK_MustTail); + } } // Add metadata for calls to MSAllocator functions diff --git a/clang/test/SemaCXX/attr-musttail-ppc.cpp b/clang/test/SemaCXX/attr-musttail-ppc.cpp new file mode 100644 index 0000000000000..72b61adf7560b --- /dev/null +++ b/clang/test/SemaCXX/attr-musttail-ppc.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 %s -triple powerpc64-ibm-aix-xcoff -o /dev/null -emit-llvm -verify=aix +// RUN: %clang_cc1 %s -triple powerpc-ibm-aix-xcoff -o /dev/null -emit-llvm -verify=aix +// RUN: %clang_cc1 %s -triple powerpc64-unknown-linux-gnu -o /dev/null -emit-llvm -verify=linux +// RUN: %clang_cc1 %s -triple powerpc-unknown-linux-gnu -o /dev/null -emit-llvm -verify=linux +// RUN: %clang_cc1 %s -triple powerpc64le-unknown-linux-gnu -o /dev/null -emit-llvm -verify=linux + +int Func(); +int Func1() { + // linux-warning@+2 {{'musttail' attribute may be ignored on ppc targets}} + // aix-error@+1 {{'musttail' attribute is not supported on AIX}} + [[clang::musttail]] return Func(); +} diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index 8450ce9e0e3b3..59e4109e8e075 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -146,6 +146,10 @@ static cl::opt<unsigned> PPCAIXTLSModelOptUseIEForLDLimit( cl::desc("Set inclusive limit count of TLS local-dynamic access(es) in a " "function to use initial-exec")); +static cl::opt<bool> AbortOnImpossibleMusttailCall( + "ppc-abort-on-impossible-musttailcall", cl::init(false), cl::Hidden, + cl::desc("Abort if any call marked as musttail is impossible.")); + STATISTIC(NumTailCalls, "Number of tail calls"); STATISTIC(NumSiblingCalls, "Number of sibling calls"); STATISTIC(ShufflesHandledWithVPERM, @@ -5945,9 +5949,14 @@ PPCTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, } } - if (!isTailCall && CB && CB->isMustTailCall()) - report_fatal_error("failed to perform tail call elimination on a call " - "site marked musttail"); + if (!isTailCall && CB && CB->isMustTailCall()) { + if (AbortOnImpossibleMusttailCall) + report_fatal_error("failed to perform tail call elimination on a call " + "site marked musttail"); + else + cast<CallInst>(const_cast<CallBase *>(CB)) + ->setTailCallKind(llvm::CallInst::TCK_Tail); + } // When long calls (i.e. indirect calls) are always used, calls are always // made via function pointer. If we have a function name, first translate it diff --git a/llvm/test/CodeGen/PowerPC/musttail-call.ll b/llvm/test/CodeGen/PowerPC/musttail-call.ll new file mode 100644 index 0000000000000..c4c283f5e1f94 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/musttail-call.ll @@ -0,0 +1,32 @@ +; RUN: not --crash llc -mtriple=powerpc64-ibm-aix-xcoff %s -o - 2>&1 -ppc-abort-on-impossible-musttailcall=true | \ +; RUN: FileCheck %s --check-prefix=CRASH +; RUN: not --crash llc -mtriple=powerpc-ibm-aix-xcoff %s -o - 2>&1 -ppc-abort-on-impossible-musttailcall=true | \ +; RUN: FileCheck %s --check-prefix=CRASH +; RUN: not --crash llc -mtriple=powerpc64-unknown-linux-gnu %s -o - 2>&1 -ppc-abort-on-impossible-musttailcall=true | \ +; RUN: FileCheck %s --check-prefix=CRASH +; RUN: not --crash llc -mtriple=powerpc-unknown-linux-gnu %s -o - 2>&1 -ppc-abort-on-impossible-musttailcall=true | \ +; RUN: FileCheck %s --check-prefix=CRASH +; RUN: not --crash llc -mtriple=powerpc64le-unknown-linux-gnu %s -o - 2>&1 -ppc-abort-on-impossible-musttailcall=true | \ +; RUN: FileCheck %s --check-prefix=CRASH +; RUN: llc -mtriple=powerpc64-ibm-aix-xcoff %s -o - 2>&1 -ppc-abort-on-impossible-musttailcall=false | \ +; RUN: FileCheck %s --check-prefix=NOCRASH +; RUN: llc -mtriple=powerpc-ibm-aix-xcoff %s -o - 2>&1 -ppc-abort-on-impossible-musttailcall=false | \ +; RUN: FileCheck %s --check-prefix=NOCRASH +; RUN: llc -mtriple=powerpc64-unknown-linux-gnu %s -o - 2>&1 -ppc-abort-on-impossible-musttailcall=false | \ +; RUN: FileCheck %s --check-prefix=NOCRASH +; RUN: llc -mtriple=powerpc-unknown-linux-gnu %s -o - 2>&1 -ppc-abort-on-impossible-musttailcall=false | \ +; RUN: FileCheck %s --check-prefix=NOCRASH +; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu %s -o - 2>&1 -ppc-abort-on-impossible-musttailcall=false | \ +; RUN: FileCheck %s --check-prefix=NOCRASH + +; CRASH: LLVM ERROR: failed to perform tail call elimination on a call site marked musttail +; NOCRASH-NOT: LLVM ERROR: failed to perform tail call elimination on a call site marked musttail +; NOCRASH-LABEL: caller +; NOCRASH: bl {{callee|.callee}} + + +declare i32 @callee() +define i32 @caller() { + %res = musttail call i32 @callee() + ret i32 %res +} `````````` </details> https://github.com/llvm/llvm-project/pull/93267 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits