summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp15
-rw-r--r--clang/test/CodeGen/attr-target-mv.c2
-rw-r--r--clang/test/CodeGenCXX/attr-cpuspecific.cpp5
3 files changed, 19 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 81304493a3a..b80a43b7eb2 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2585,11 +2585,22 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) {
llvm::Constant *Func = GetGlobalValue(MangledName);
- if (!Func)
+ if (!Func) {
+ GlobalDecl ExistingDecl = Manglings.lookup(MangledName);
+ if (ExistingDecl.getDecl() &&
+ ExistingDecl.getDecl()->getAsFunction()->isDefined()) {
+ EmitGlobalFunctionDefinition(ExistingDecl, nullptr);
+ Func = GetGlobalValue(MangledName);
+ } else {
+ if (!ExistingDecl.getDecl())
+ ExistingDecl = GD.getWithMultiVersionIndex(Index);
+
Func = GetOrCreateLLVMFunction(
- MangledName, DeclTy, GD.getWithMultiVersionIndex(Index),
+ MangledName, DeclTy, ExistingDecl,
/*ForVTable=*/false, /*DontDefer=*/true,
/*IsThunk=*/false, llvm::AttributeList(), ForDefinition);
+ }
+ }
llvm::SmallVector<StringRef, 32> Features;
Target.getCPUSpecificCPUDispatchFeatures(II->getName(), Features);
diff --git a/clang/test/CodeGen/attr-target-mv.c b/clang/test/CodeGen/attr-target-mv.c
index 372b14053fc..363dea6a2fc 100644
--- a/clang/test/CodeGen/attr-target-mv.c
+++ b/clang/test/CodeGen/attr-target-mv.c
@@ -223,10 +223,12 @@ void bar5() {
// WINDOWS: define linkonce_odr dso_local void @foo_decls()
// WINDOWS: define linkonce_odr dso_local void @foo_decls.sse4.2()
+// LINUX: define linkonce void @foo_multi(i32 %{{[^,]+}}, double %{{[^\)]+}})
// LINUX: define linkonce void @foo_multi.avx_sse4.2(i32 %{{[^,]+}}, double %{{[^\)]+}})
// LINUX: define linkonce void @foo_multi.fma4_sse4.2(i32 %{{[^,]+}}, double %{{[^\)]+}})
// LINUX: define linkonce void @foo_multi.arch_ivybridge_fma4_sse4.2(i32 %{{[^,]+}}, double %{{[^\)]+}})
+// WINDOWS: define linkonce_odr dso_local void @foo_multi(i32 %{{[^,]+}}, double %{{[^\)]+}})
// WINDOWS: define linkonce_odr dso_local void @foo_multi.avx_sse4.2(i32 %{{[^,]+}}, double %{{[^\)]+}})
// WINDOWS: define linkonce_odr dso_local void @foo_multi.fma4_sse4.2(i32 %{{[^,]+}}, double %{{[^\)]+}})
// WINDOWS: define linkonce_odr dso_local void @foo_multi.arch_ivybridge_fma4_sse4.2(i32 %{{[^,]+}}, double %{{[^\)]+}})
diff --git a/clang/test/CodeGenCXX/attr-cpuspecific.cpp b/clang/test/CodeGenCXX/attr-cpuspecific.cpp
index 57b45e1da2e..bfee49ca34b 100644
--- a/clang/test/CodeGenCXX/attr-cpuspecific.cpp
+++ b/clang/test/CodeGenCXX/attr-cpuspecific.cpp
@@ -16,8 +16,11 @@ void foo() {
// LINUX: define void (%struct.S*)* @_ZN1S4FuncEv.resolver
// LINUX: ret void (%struct.S*)* @_ZN1S4FuncEv.S
// LINUX: ret void (%struct.S*)* @_ZN1S4FuncEv.O
+// LINUX: declare void @_ZN1S4FuncEv.S
+// LINUX: define linkonce_odr void @_ZN1S4FuncEv.O
// WINDOWS: define dso_local void @"?Func@S@@QEAAXXZ"(%struct.S*)
// WINDOWS: musttail call void @"?Func@S@@QEAAXXZ.S"(%struct.S* %0)
// WINDOWS: musttail call void @"?Func@S@@QEAAXXZ.O"(%struct.S* %0)
-
+// WINDOWS: declare dso_local void @"?Func@S@@QEAAXXZ.S"
+// WINDOWS: define linkonce_odr dso_local void @"?Func@S@@QEAAXXZ.O"
OpenPOWER on IntegriCloud