================ @@ -4114,8 +4114,26 @@ void CodeGenModule::emitMultiVersionFunctions() { } llvm::Constant *ResolverConstant = GetOrCreateMultiVersionResolver(GD); - if (auto *IFunc = dyn_cast<llvm::GlobalIFunc>(ResolverConstant)) + if (auto *IFunc = dyn_cast<llvm::GlobalIFunc>(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? ---------------- jroelofs wrote:
I have been meaning to file an issue about this. Not using a different mangling means you always get the default version when referencing a multi-versioned function outside of the TU. Consider e.g: ``` PublicHeader.h: int versioned(void); void *inside_TU(); void *outside_TU(); --- TUA.c: #include "PublicHeader.h" __attribute__((target_version("simd"))) int versioned(void) { return 1; } __attribute__((target_version("default"))) int versioned(void) { return 2; } void *inside_TU(void) { return versioned; } --- TUB.c: #include "PublicHeader.h" void *outside_TU(void) { return versioned; } --- Check.c: #include "PublicHeader.h" int main() { return inside_TU() == outside_TU(); } ``` @rsandifo-arm brought up a similar case on x86: ``` __attribute__((target("avx2"))) int versioned(void) { return 1; } __attribute__((target("default"))) int versioned(void) { return 2; } int (*inside_TU(void))(void) { return versioned; } ``` If we fix this, we should definitely make sure both the ACLE folks, and GCC are on board, and that the fix makes sense in the context of other targets. https://github.com/llvm/llvm-project/pull/71706 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits