From 1be0d9d7d88a9bdabe6ef4d81720ddf4cf6f71c1 Mon Sep 17 00:00:00 2001 From: Dani Date: Mon, 22 Jan 2024 19:55:16 +0100 Subject: [AArch64][Clang] Fix linker error for function multiversioning (#74358) AArch64 part of https://github.com/llvm/llvm-project/pull/71706. Default version is now mangled with .default. Resolver for the TargetVersion need to be emitted from the CodeGenModule::EmitMultiVersionFunctionDefinition. --- clang/lib/CodeGen/CodeGenModule.cpp | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) (limited to 'clang/lib/CodeGen/CodeGenModule.cpp') diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 77c931842dd2..78b2f2ba29fd 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1716,8 +1716,10 @@ static void AppendCPUSpecificCPUDispatchMangling(const CodeGenModule &CGM, static void AppendTargetVersionMangling(const CodeGenModule &CGM, const TargetVersionAttr *Attr, raw_ostream &Out) { - if (Attr->isDefaultVersion()) + if (Attr->isDefaultVersion()) { + Out << ".default"; return; + } Out << "._"; const TargetInfo &TI = CGM.getTarget(); llvm::SmallVector Feats; @@ -1780,8 +1782,10 @@ static void AppendTargetClonesMangling(const CodeGenModule &CGM, const TargetInfo &TI = CGM.getTarget(); if (TI.getTriple().isAArch64()) { StringRef FeatureStr = Attr->getFeatureStr(VersionIndex); - if (FeatureStr == "default") + if (FeatureStr == "default") { + Out << ".default"; return; + } Out << "._"; SmallVector Features; FeatureStr.split(Features, "+"); @@ -4029,6 +4033,8 @@ void CodeGenModule::EmitMultiVersionFunctionDefinition(GlobalDecl GD, EmitGlobalFunctionDefinition(GD.getWithMultiVersionIndex(I), nullptr); // Ensure that the resolver function is also emitted. GetOrCreateMultiVersionResolver(GD); + } else if (FD->hasAttr()) { + GetOrCreateMultiVersionResolver(GD); } else EmitGlobalFunctionDefinition(GD, GV); } @@ -4210,14 +4216,7 @@ void CodeGenModule::emitMultiVersionFunctions() { llvm::Constant *ResolverConstant = GetOrCreateMultiVersionResolver(GD); if (auto *IFunc = dyn_cast(ResolverConstant)) { ResolverConstant = IFunc->getResolver(); - // In Aarch64, default versions of multiversioned functions are mangled to - // their 'normal' assembly name. This deviates from other targets which - // append a '.default' string. As a result we need to continue appending - // .ifunc in Aarch64. - // FIXME: Should Aarch64 mangling for 'default' multiversion function and - // in turn ifunc function match that of other targets? - if (FD->isTargetClonesMultiVersion() && - !getTarget().getTriple().isAArch64()) { + if (FD->isTargetClonesMultiVersion()) { const CGFunctionInfo &FI = getTypes().arrangeGlobalDeclaration(GD); llvm::FunctionType *DeclTy = getTypes().GetFunctionType(FI); std::string MangledName = getMangledNameImpl( @@ -4398,14 +4397,7 @@ llvm::Constant *CodeGenModule::GetOrCreateMultiVersionResolver(GlobalDecl GD) { // a separate resolver). std::string ResolverName = MangledName; if (getTarget().supportsIFunc()) { - // In Aarch64, default versions of multiversioned functions are mangled to - // their 'normal' assembly name. This deviates from other targets which - // append a '.default' string. As a result we need to continue appending - // .ifunc in Aarch64. - // FIXME: Should Aarch64 mangling for 'default' multiversion function and - // in turn ifunc function match that of other targets? - if (!FD->isTargetClonesMultiVersion() || - getTarget().getTriple().isAArch64()) + if (!FD->isTargetClonesMultiVersion()) ResolverName += ".ifunc"; } else if (FD->isTargetMultiVersion()) { ResolverName += ".resolver"; -- cgit v1.2.3