Fix Target Multiversioning renaming.

The initial implementation only did 'first declaration renaming' when
a default version came after. This is insufficient in cases where a
default does not exist, so this patch makes sure that we do the renaming
in all cases.

This renaming is necessary because we emit the first declaration before
knowing that it IS a target multiversion function, which would change
its name. The second declaration (the one that caused the
multiversioning) then needs to make sure that the first one has its name
changed to be consistent with the resolver usage.
This commit is contained in:
Erich Keane 2020-03-09 08:06:58 -07:00
parent 2fed3ca3b5
commit 7b66160828
2 changed files with 10 additions and 2 deletions

View File

@ -3141,8 +3141,7 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(
(void)OpenMPRuntime->emitDeclareVariant(GD, /*IsForDefinition=*/true);
if (FD->isMultiVersion()) {
const auto *TA = FD->getAttr<TargetAttr>();
if (TA && TA->isDefaultVersion())
if (FD->hasAttr<TargetAttr>())
UpdateMultiVersionNames(GD, FD);
if (!IsForDefinition)
return GetOrCreateMultiVersionResolver(GD, Ty, FD);

View File

@ -47,6 +47,9 @@ void bar5() {
fwd_decl_avx();
}
int __attribute__((target("avx"))) changed_to_mv(void) { return 0;}
int __attribute__((target("fma4"))) changed_to_mv(void) { return 1;}
// LINUX: @foo.ifunc = weak_odr ifunc i32 (), i32 ()* ()* @foo.resolver
// LINUX: @foo_inline.ifunc = weak_odr ifunc i32 (), i32 ()* ()* @foo_inline.resolver
// LINUX: @foo_decls.ifunc = weak_odr ifunc void (), void ()* ()* @foo_decls.resolver
@ -194,6 +197,12 @@ void bar5() {
// WINDOWS: call i32 @fwd_decl_avx.avx
// WINDOWS: call i32 @fwd_decl_avx
// LINUX: define i32 @changed_to_mv.avx()
// LINUX: define i32 @changed_to_mv.fma4()
// WINDOWS: define dso_local i32 @changed_to_mv.avx()
// WINDOWS: define dso_local i32 @changed_to_mv.fma4()
// LINUX: declare i32 @foo.arch_sandybridge()
// WINDOWS: declare dso_local i32 @foo.arch_sandybridge()