]> granicus.if.org Git - clang/commitdiff
Multiversioning- Ensure all MV functions are emitted.
authorErich Keane <erich.keane@intel.com>
Thu, 1 Nov 2018 15:11:43 +0000 (15:11 +0000)
committerErich Keane <erich.keane@intel.com>
Thu, 1 Nov 2018 15:11:43 +0000 (15:11 +0000)
Multiverson function versions are always used (by the resolver), so ensure that
they are always emitted.

Change-Id: I5d2e0841fddf0d18918b3fb92ae76814add7ee96

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@345839 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/ASTContext.cpp
test/CodeGen/attr-target-mv.c
test/CodeGenCXX/attr-cpuspecific.cpp
test/CodeGenCXX/attr-target-mv-member-funcs.cpp

index 211d6c9d4d32d73f85366d98878561cf02fed01a..d6fac05829d7da7b3a8cc0d5851f79c4a84316ca 100644 (file)
@@ -9773,6 +9773,10 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
     return true;
 
   if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
+    // Multiversioned functions always have to be emitted, because they are used
+    // by the resolver.
+    if (FD->isMultiVersion())
+      return true;
     // Forward declarations aren't required.
     if (!FD->doesThisDeclarationHaveABody())
       return FD->doesDeclarationForceExternallyVisibleDefinition();
index a28f330f58203303a355a69c063015ced78123b3..f9fbbbd5f0bac0bb180d86448bb7d4a805b3e4d5 100644 (file)
@@ -72,6 +72,16 @@ void bar4() {
 // WINDOWS: call i32 @foo.sse4.2
 // WINDOWS: call i32 @foo
 
+// LINUX: define linkonce i32 @foo_inline.arch_ivybridge()
+// LINUX: ret i32 1
+// LINUX: define linkonce i32 @foo_inline()
+// LINUX: ret i32 2
+
+// WINDOWS: define linkonce_odr dso_local i32 @foo_inline.arch_ivybridge()
+// WINDOWS: ret i32 1
+// WINDOWS: define linkonce_odr dso_local i32 @foo_inline()
+// WINDOWS: ret i32 2
+
 // LINUX: define i32 @bar2()
 // LINUX: call i32 @foo_inline.ifunc()
 
@@ -106,6 +116,22 @@ void bar4() {
 // WINDOWS: call void @foo_decls.sse4.2
 // Windows: call void @foo_decls
 
+// LINUX: define linkonce void @foo_decls()
+// LINUX: define linkonce void @foo_decls.sse4.2()
+
+// 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 %{{[^\)]+}})
+
 // LINUX: define void @bar4()
 // LINUX: call void @foo_multi.ifunc(i32 1, double 5.{{[0+e]*}})
 
@@ -156,26 +182,3 @@ void bar4() {
 
 // WINDOWS: declare dso_local i32 @foo_inline.arch_sandybridge()
 
-// LINUX: define linkonce i32 @foo_inline.arch_ivybridge()
-// LINUX: ret i32 1
-// LINUX: define linkonce i32 @foo_inline()
-// LINUX: ret i32 2
-
-// WINDOWS: define linkonce_odr dso_local i32 @foo_inline.arch_ivybridge()
-// WINDOWS: ret i32 1
-// WINDOWS: define linkonce_odr dso_local i32 @foo_inline()
-// WINDOWS: ret i32 2
-
-// LINUX: define linkonce void @foo_decls()
-// LINUX: define linkonce void @foo_decls.sse4.2()
-
-// 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.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.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 %{{[^\)]+}})
index 57b45e1da2e71d9e4e327d2f138012285c76804b..7a4427d6ffa42ac6433f196be661df782719cc8d 100644 (file)
@@ -13,11 +13,13 @@ void foo() {
   s.Func();
 }
 
+
+// LINUX: define linkonce_odr void @_ZN1S4FuncEv.O
 // LINUX: define void (%struct.S*)* @_ZN1S4FuncEv.resolver
 // LINUX: ret void (%struct.S*)* @_ZN1S4FuncEv.S
 // LINUX: ret void (%struct.S*)* @_ZN1S4FuncEv.O
 
+// WINDOWS: define linkonce_odr dso_local void @"?Func@S@@QEAAXXZ.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)
-
index a63737ed0330261722d677864bc9dbebe427d135..f448463556e131f36d42a87e79b4dd722552c93f 100644 (file)
@@ -73,6 +73,25 @@ int templ_use() {
 // LINUX: @_ZN5templIiE3fooEi.ifunc = ifunc i32 (%struct.templ*, i32), i32 (%struct.templ*, i32)* ()* @_ZN5templIiE3fooEi.resolver
 // LINUX: @_ZN5templIdE3fooEi.ifunc = ifunc i32 (%struct.templ.0*, i32), i32 (%struct.templ.0*, i32)* ()* @_ZN5templIdE3fooEi.resolver
 
+
+// LINUX: define linkonce_odr i32 @_ZN1S3fooEi.sse4.2(%struct.S* %this, i32)
+// LINUX: ret i32 0
+
+// WINDOWS: define linkonce_odr dso_local i32 @"?foo@S@@QEAAHH@Z.sse4.2"(%struct.S* %this, i32)
+// WINDOWS: ret i32 0
+
+// LINUX: define linkonce_odr i32 @_ZN1S3fooEi.arch_ivybridge(%struct.S* %this, i32)
+// LINUX: ret i32 1
+
+// WINDOWS: define linkonce_odr dso_local i32 @"?foo@S@@QEAAHH@Z.arch_ivybridge"(%struct.S* %this, i32)
+// WINDOWS: ret i32 1
+
+// LINUX: define linkonce_odr i32 @_ZN1S3fooEi(%struct.S* %this, i32)
+// LINUX: ret i32 2
+
+// WINDOWS: define linkonce_odr dso_local i32 @"?foo@S@@QEAAHH@Z"(%struct.S* %this, i32)
+// WINDOWS: ret i32 2
+
 // LINUX: define i32 @_Z3barv()
 // LINUX: %s = alloca %struct.S, align 1
 // LINUX: %s2 = alloca %struct.S, align 1
@@ -177,44 +196,26 @@ int templ_use() {
 // WINDOWS: call i32 @"?foo@?$templ@N@@QEAAHH@Z.sse4.2"
 // WINDOWS: call i32 @"?foo@?$templ@N@@QEAAHH@Z"
 
-// LINUX: define linkonce_odr i32 @_ZN1S3fooEi.sse4.2(%struct.S* %this, i32)
-// LINUX: ret i32 0
-
-// WINDOWS: define linkonce_odr dso_local i32 @"?foo@S@@QEAAHH@Z.sse4.2"(%struct.S* %this, i32)
-// WINDOWS: ret i32 0
-
-// LINUX: declare i32 @_ZN1S3fooEi.arch_sandybridge(%struct.S*, i32)
-
-// WINDOWS: declare dso_local i32 @"?foo@S@@QEAAHH@Z.arch_sandybridge"(%struct.S*, i32)
-
-// LINUX: define linkonce_odr i32 @_ZN1S3fooEi.arch_ivybridge(%struct.S* %this, i32)
-// LINUX: ret i32 1
-
-// WINDOWS: define linkonce_odr dso_local i32 @"?foo@S@@QEAAHH@Z.arch_ivybridge"(%struct.S* %this, i32)
-// WINDOWS: ret i32 1
-
-// LINUX: define linkonce_odr i32 @_ZN1S3fooEi(%struct.S* %this, i32)
-// LINUX: ret i32 2
-
-// WINDOWS: define linkonce_odr dso_local i32 @"?foo@S@@QEAAHH@Z"(%struct.S* %this, i32)
-// WINDOWS: ret i32 2
-
 // LINUX: define linkonce_odr i32 @_ZN5templIiE3fooEi.sse4.2
-// LINUX: declare i32 @_ZN5templIiE3fooEi.arch_sandybridge
 // LINUX: define linkonce_odr i32 @_ZN5templIiE3fooEi.arch_ivybridge
 // LINUX: define linkonce_odr i32 @_ZN5templIiE3fooEi
 
 // WINDOWS: define linkonce_odr dso_local i32 @"?foo@?$templ@H@@QEAAHH@Z.sse4.2"
-// WINDOWS: declare dso_local i32 @"?foo@?$templ@H@@QEAAHH@Z.arch_sandybridge"
 // WINDOWS: define linkonce_odr dso_local i32 @"?foo@?$templ@H@@QEAAHH@Z.arch_ivybridge"
 // WINDOWS: define linkonce_odr dso_local i32 @"?foo@?$templ@H@@QEAAHH@Z"
 
 // LINUX: define linkonce_odr i32 @_ZN5templIdE3fooEi.sse4.2
-// LINUX: declare i32 @_ZN5templIdE3fooEi.arch_sandybridge
 // LINUX: define linkonce_odr i32 @_ZN5templIdE3fooEi.arch_ivybridge
 // LINUX: define linkonce_odr i32 @_ZN5templIdE3fooEi
 
 // WINDOWS: define linkonce_odr dso_local i32 @"?foo@?$templ@N@@QEAAHH@Z.sse4.2"
-// WINDOWS: declare dso_local i32 @"?foo@?$templ@N@@QEAAHH@Z.arch_sandybridge"
 // WINDOWS: define linkonce_odr dso_local i32 @"?foo@?$templ@N@@QEAAHH@Z.arch_ivybridge"
 // WINDOWS: define linkonce_odr dso_local i32 @"?foo@?$templ@N@@QEAAHH@Z"
+
+// LINUX: declare i32 @_ZN1S3fooEi.arch_sandybridge(%struct.S*, i32)
+// LINUX: declare i32 @_ZN5templIiE3fooEi.arch_sandybridge
+// LINUX: declare i32 @_ZN5templIdE3fooEi.arch_sandybridge
+
+// WINDOWS: declare dso_local i32 @"?foo@S@@QEAAHH@Z.arch_sandybridge"(%struct.S*, i32)
+// WINDOWS: declare dso_local i32 @"?foo@?$templ@H@@QEAAHH@Z.arch_sandybridge"
+// WINDOWS: declare dso_local i32 @"?foo@?$templ@N@@QEAAHH@Z.arch_sandybridge"