[clang] 7c53fc4 - [clang] Emit target_clones resolver functions as COMDAT.

Tom Honermann via cfe-commits cfe-commits at lists.llvm.org
Tue Apr 5 12:34:59 PDT 2022


Author: Tom Honermann
Date: 2022-04-05T15:34:35-04:00
New Revision: 7c53fc4fe1308f5b2a7527d14ea41fabb18109b8

URL: https://github.com/llvm/llvm-project/commit/7c53fc4fe1308f5b2a7527d14ea41fabb18109b8
DIFF: https://github.com/llvm/llvm-project/commit/7c53fc4fe1308f5b2a7527d14ea41fabb18109b8.diff

LOG: [clang] Emit target_clones resolver functions as COMDAT.

Previously, resolver functions synthesized for target_clones multiversion
functions were not emitted as COMDAT. Now fixed.

Added: 
    

Modified: 
    clang/lib/CodeGen/CodeGenModule.cpp
    clang/test/CodeGen/attr-target-clones.c

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 4d24c33f51d02..ddcf564e688fe 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -3454,6 +3454,10 @@ void CodeGenModule::EmitTargetClonesResolver(GlobalDecl GD) {
     Options.emplace_back(cast<llvm::Function>(Func), Architecture, Feature);
   }
 
+  if (supportsCOMDAT())
+    ResolverFunc->setComdat(
+        getModule().getOrInsertComdat(ResolverFunc->getName()));
+
   const TargetInfo &TI = getTarget();
   std::stable_sort(
       Options.begin(), Options.end(),

diff  --git a/clang/test/CodeGen/attr-target-clones.c b/clang/test/CodeGen/attr-target-clones.c
index 2ba3fb0158044..ecb36a41bab88 100644
--- a/clang/test/CodeGen/attr-target-clones.c
+++ b/clang/test/CodeGen/attr-target-clones.c
@@ -1,6 +1,18 @@
 // RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefixes=LINUX,CHECK
 // RUN: %clang_cc1 -triple x86_64-windows-pc -emit-llvm %s -o - | FileCheck %s --check-prefixes=WINDOWS,CHECK
 
+// LINUX: $foo.resolver = comdat any
+// LINUX: $foo_dupes.resolver = comdat any
+// LINUX: $unused.resolver = comdat any
+// LINUX: $foo_inline.resolver = comdat any
+// LINUX: $foo_inline2.resolver = comdat any
+
+// WINDOWS: $foo = comdat any
+// WINDOWS: $foo_dupes = comdat any
+// WINDOWS: $unused = comdat any
+// WINDOWS: $foo_inline = comdat any
+// WINDOWS: $foo_inline2 = comdat any
+
 // LINUX: @foo.ifunc = weak_odr ifunc i32 (), i32 ()* ()* @foo.resolver
 // LINUX: @foo_dupes.ifunc = weak_odr ifunc void (), void ()* ()* @foo_dupes.resolver
 // LINUX: @unused.ifunc = weak_odr ifunc void (), void ()* ()* @unused.resolver
@@ -10,26 +22,26 @@
 int __attribute__((target_clones("sse4.2, default"))) foo(void) { return 0; }
 // LINUX: define {{.*}}i32 @foo.sse4.2.0()
 // LINUX: define {{.*}}i32 @foo.default.1()
-// LINUX: define i32 ()* @foo.resolver()
+// LINUX: define i32 ()* @foo.resolver() comdat
 // LINUX: ret i32 ()* @foo.sse4.2.0
 // LINUX: ret i32 ()* @foo.default.1
 
 // WINDOWS: define dso_local i32 @foo.sse4.2.0()
 // WINDOWS: define dso_local i32 @foo.default.1()
-// WINDOWS: define dso_local i32 @foo()
+// WINDOWS: define dso_local i32 @foo() comdat
 // WINDOWS: musttail call i32 @foo.sse4.2.0
 // WINDOWS: musttail call i32 @foo.default.1
 
 __attribute__((target_clones("default,default ,sse4.2"))) void foo_dupes(void) {}
 // LINUX: define {{.*}}void @foo_dupes.default.1()
 // LINUX: define {{.*}}void @foo_dupes.sse4.2.0()
-// LINUX: define void ()* @foo_dupes.resolver()
+// LINUX: define void ()* @foo_dupes.resolver() comdat
 // LINUX: ret void ()* @foo_dupes.sse4.2.0
 // LINUX: ret void ()* @foo_dupes.default.1
 
 // WINDOWS: define dso_local void @foo_dupes.default.1()
 // WINDOWS: define dso_local void @foo_dupes.sse4.2.0()
-// WINDOWS: define dso_local void @foo_dupes()
+// WINDOWS: define dso_local void @foo_dupes() comdat
 // WINDOWS: musttail call void @foo_dupes.sse4.2.0
 // WINDOWS: musttail call void @foo_dupes.default.1
 
@@ -52,13 +64,13 @@ int bar(void) {
 void __attribute__((target_clones("default, arch=ivybridge"))) unused(void) {}
 // LINUX: define {{.*}}void @unused.default.1()
 // LINUX: define {{.*}}void @unused.arch_ivybridge.0()
-// LINUX: define void ()* @unused.resolver()
+// LINUX: define void ()* @unused.resolver() comdat
 // LINUX: ret void ()* @unused.arch_ivybridge.0
 // LINUX: ret void ()* @unused.default.1
 
 // WINDOWS: define dso_local void @unused.default.1()
 // WINDOWS: define dso_local void @unused.arch_ivybridge.0()
-// WINDOWS: define dso_local void @unused()
+// WINDOWS: define dso_local void @unused() comdat
 // WINDOWS: musttail call void @unused.arch_ivybridge.0
 // WINDOWS: musttail call void @unused.default.1
 
@@ -79,12 +91,12 @@ int bar3(void) {
 }
 
 // Deferred emission of foo_inline, which got delayed because it is inline.
-// LINUX: define i32 ()* @foo_inline.resolver()
+// LINUX: define i32 ()* @foo_inline.resolver() comdat
 // LINUX: ret i32 ()* @foo_inline.arch_sandybridge.0
 // LINUX: ret i32 ()* @foo_inline.sse4.2.1
 // LINUX: ret i32 ()* @foo_inline.default.2
 
-// WINDOWS: define dso_local i32 @foo_inline()
+// WINDOWS: define dso_local i32 @foo_inline() comdat
 // WINDOWS: musttail call i32 @foo_inline.arch_sandybridge.0
 // WINDOWS: musttail call i32 @foo_inline.sse4.2.1
 // WINDOWS: musttail call i32 @foo_inline.default.2
@@ -92,13 +104,13 @@ int bar3(void) {
 inline int __attribute__((target_clones("arch=sandybridge,default,sse4.2")))
 foo_inline2(void){ return 0; }
 // LINUX: define linkonce i32 @foo_inline2.arch_sandybridge.0() #[[SB:[0-9]+]]
-// LINUX: define i32 ()* @foo_inline2.resolver()
+// LINUX: define i32 ()* @foo_inline2.resolver() comdat
 // LINUX: ret i32 ()* @foo_inline2.arch_sandybridge.0
 // LINUX: ret i32 ()* @foo_inline2.sse4.2.1
 // LINUX: ret i32 ()* @foo_inline2.default.2
 
 // WINDOWS: define linkonce_odr dso_local i32 @foo_inline2.arch_sandybridge.0() #[[SB:[0-9]+]]
-// WINDOWS: define dso_local i32 @foo_inline2()
+// WINDOWS: define dso_local i32 @foo_inline2() comdat
 // WINDOWS: musttail call i32 @foo_inline2.arch_sandybridge.0
 // WINDOWS: musttail call i32 @foo_inline2.sse4.2.1
 // WINDOWS: musttail call i32 @foo_inline2.default.2


        


More information about the cfe-commits mailing list