llvm::Function *ResolverFunc = cast<llvm::Function>(
GetGlobalValue((getMangledName(GD) + ".resolver").str()));
+ if (supportsCOMDAT())
+ ResolverFunc->setComdat(
+ getModule().getOrInsertComdat(ResolverFunc->getName()));
std::stable_sort(
Options.begin(), Options.end(),
std::greater<CodeGenFunction::MultiVersionResolverOption>());
// CHECK: define i32 @bar()
// CHECK: call i32 (i32, ...) @foo.ifunc(i32 1, i32 97, double
// CHECK: call i32 (i32, ...) @foo.ifunc(i32 2, double 2.2{{[0-9Ee+]+}}, i8* getelementptr inbounds
-// CHECK: define i32 (i32, ...)* @foo.resolver()
+// CHECK: define i32 (i32, ...)* @foo.resolver() comdat
// CHECK: ret i32 (i32, ...)* @foo.arch_sandybridge
// CHECK: ret i32 (i32, ...)* @foo.arch_ivybridge
// CHECK: ret i32 (i32, ...)* @foo.sse4.2
// CHECK: define i32 @bar()
// CHECK: call i32 @foo.ifunc()
-// CHECK: define i32 ()* @foo.resolver()
+// CHECK: define i32 ()* @foo.resolver() comdat
// CHECK: call void @__cpu_indicator_init()
// CHECK: ret i32 ()* @foo.arch_sandybridge
// CHECK: ret i32 ()* @foo.arch_ivybridge
// CHECK: define i32 @bar2()
// CHECK: call i32 @foo_inline.ifunc()
-// CHECK: define i32 ()* @foo_inline.resolver()
+// CHECK: define i32 ()* @foo_inline.resolver() comdat
// CHECK: call void @__cpu_indicator_init()
// CHECK: ret i32 ()* @foo_inline.arch_sandybridge
// CHECK: ret i32 ()* @foo_inline.arch_ivybridge
// CHECK: define void @bar3()
// CHECK: call void @foo_decls.ifunc()
-// CHECK: define void ()* @foo_decls.resolver()
+// CHECK: define void ()* @foo_decls.resolver() comdat
// CHECK: ret void ()* @foo_decls.sse4.2
// CHECK: ret void ()* @foo_decls
// CHECK: call i32 @_Z3fooi.ifunc(i32 1)
// CHECK: call i32 @_ZN2ns3fooEi.ifunc(i32 2)
-// CHECK: define i32 (i32)* @_Z3fooi.resolver()
+// CHECK: define i32 (i32)* @_Z3fooi.resolver() comdat
// CHECK: ret i32 (i32)* @_Z3fooi.arch_sandybridge
// CHECK: ret i32 (i32)* @_Z3fooi.arch_ivybridge
// CHECK: ret i32 (i32)* @_Z3fooi.sse4.2
// CHECK: ret i32 (i32)* @_Z3fooi
//
-// CHECK: define i32 (i32)* @_ZN2ns3fooEi.resolver()
+// CHECK: define i32 (i32)* @_ZN2ns3fooEi.resolver() comdat
// CHECK: ret i32 (i32)* @_ZN2ns3fooEi.arch_sandybridge
// CHECK: ret i32 (i32)* @_ZN2ns3fooEi.arch_ivybridge
// CHECK: ret i32 (i32)* @_ZN2ns3fooEi.sse4.2
// CHECK: call dereferenceable(1) %struct.S* @_ZN1SaSERKS_.ifunc(%struct.S* %s2
// CHECK: call i32 @_ZN1S3fooEi.ifunc(%struct.S* %s, i32 0)
-// CHECK: define %struct.S* (%struct.S*, %struct.S*)* @_ZN1SaSERKS_.resolver()
+// CHECK: define %struct.S* (%struct.S*, %struct.S*)* @_ZN1SaSERKS_.resolver() comdat
// CHECK: ret %struct.S* (%struct.S*, %struct.S*)* @_ZN1SaSERKS_.arch_ivybridge
// CHECK: ret %struct.S* (%struct.S*, %struct.S*)* @_ZN1SaSERKS_
-// CHECK: define void (%struct.ConvertTo*)* @_ZNK9ConvertTocv1SEv.resolver()
+// CHECK: define void (%struct.ConvertTo*)* @_ZNK9ConvertTocv1SEv.resolver() comdat
// CHECK: ret void (%struct.ConvertTo*)* @_ZNK9ConvertTocv1SEv.arch_ivybridge
// CHECK: ret void (%struct.ConvertTo*)* @_ZNK9ConvertTocv1SEv
-// CHECK: define i32 (%struct.S*, i32)* @_ZN1S3fooEi.resolver()
+// CHECK: define i32 (%struct.S*, i32)* @_ZN1S3fooEi.resolver() comdat
// CHECK: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi.arch_sandybridge
// CHECK: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi.arch_ivybridge
// CHECK: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi.sse4.2
// CHECK: define i32 @_Z4bar2v()
// CHECK:call i32 @_ZN2S23fooEi.ifunc
-// define i32 (%struct.S2*, i32)* @_ZN2S23fooEi.resolver()
+// define i32 (%struct.S2*, i32)* @_ZN2S23fooEi.resolver() comdat
// CHECK: ret i32 (%struct.S2*, i32)* @_ZN2S23fooEi.arch_sandybridge
// CHECK: ret i32 (%struct.S2*, i32)* @_ZN2S23fooEi.arch_ivybridge
// CHECK: ret i32 (%struct.S2*, i32)* @_ZN2S23fooEi.sse4.2
// CHECK: call i32 @_ZN5templIdE3fooEi.ifunc
-// CHECK: define i32 (%struct.templ*, i32)* @_ZN5templIiE3fooEi.resolver()
+// CHECK: define i32 (%struct.templ*, i32)* @_ZN5templIiE3fooEi.resolver() comdat
// CHECK: ret i32 (%struct.templ*, i32)* @_ZN5templIiE3fooEi.arch_sandybridge
// CHECK: ret i32 (%struct.templ*, i32)* @_ZN5templIiE3fooEi.arch_ivybridge
// CHECK: ret i32 (%struct.templ*, i32)* @_ZN5templIiE3fooEi.sse4.2
// CHECK: ret i32 (%struct.templ*, i32)* @_ZN5templIiE3fooEi
//
-// CHECK: define i32 (%struct.templ.0*, i32)* @_ZN5templIdE3fooEi.resolver()
+// CHECK: define i32 (%struct.templ.0*, i32)* @_ZN5templIdE3fooEi.resolver() comdat
// CHECK: ret i32 (%struct.templ.0*, i32)* @_ZN5templIdE3fooEi.arch_sandybridge
// CHECK: ret i32 (%struct.templ.0*, i32)* @_ZN5templIdE3fooEi.arch_ivybridge
// CHECK: ret i32 (%struct.templ.0*, i32)* @_ZN5templIdE3fooEi.sse4.2
// CHECK: %s = alloca %struct.S, align 1
// CHECK: %call = call i32 @_ZN1S3fooEi.ifunc(%struct.S* %s, i32 0)
-// CHECK: define i32 (%struct.S*, i32)* @_ZN1S3fooEi.resolver()
+// CHECK: define i32 (%struct.S*, i32)* @_ZN1S3fooEi.resolver() comdat
// CHECK: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi.arch_sandybridge
// CHECK: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi.arch_ivybridge
// CHECK: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi.sse4.2
// CHECK: call i32 @_Z12foo_overloadv.ifunc()
// CHECK: call i32 @_Z12foo_overloadi.ifunc(i32 1)
-// CHECK: define i32 ()* @_Z12foo_overloadv.resolver()
+// CHECK: define i32 ()* @_Z12foo_overloadv.resolver() comdat
// CHECK: ret i32 ()* @_Z12foo_overloadv.arch_sandybridge
// CHECK: ret i32 ()* @_Z12foo_overloadv.arch_ivybridge
// CHECK: ret i32 ()* @_Z12foo_overloadv.sse4.2
// CHECK: ret i32 ()* @_Z12foo_overloadv
-// CHECK: define i32 (i32)* @_Z12foo_overloadi.resolver()
+// CHECK: define i32 (i32)* @_Z12foo_overloadi.resolver() comdat
// CHECK: ret i32 (i32)* @_Z12foo_overloadi.arch_sandybridge
// CHECK: ret i32 (i32)* @_Z12foo_overloadi.arch_ivybridge
// CHECK: ret i32 (i32)* @_Z12foo_overloadi.sse4.2