diff options
author | Fangrui Song <maskray@google.com> | 2019-09-11 01:54:48 +0000 |
---|---|---|
committer | Fangrui Song <maskray@google.com> | 2019-09-11 01:54:48 +0000 |
commit | 9ca1b94a6d3f491f26ccbeacf910342e6861fc7f (patch) | |
tree | f8197545a4a7e4829b20cbee9edb46e7c5969703 /clang/test/CodeGen/attr-cpuspecific.c | |
parent | 56a34f4541cb6ca70f41f6229911894db18ff113 (diff) | |
download | bcm5719-llvm-9ca1b94a6d3f491f26ccbeacf910342e6861fc7f.tar.gz bcm5719-llvm-9ca1b94a6d3f491f26ccbeacf910342e6861fc7f.zip |
[CodeGen] Add alias for cpu_dispatch function with IFunc & Fix resolver linkage type
Multi-versioned functions defined by cpu_dispatch and implemented with IFunc
can not be called outside the translation units where they are defined due to
lack of symbols. This patch add function aliases for these functions and thus
make them visible outside.
Differential Revision: https://reviews.llvm.org/D67058
Patch by Senran Zhang
llvm-svn: 371586
Diffstat (limited to 'clang/test/CodeGen/attr-cpuspecific.c')
-rw-r--r-- | clang/test/CodeGen/attr-cpuspecific.c | 62 |
1 files changed, 39 insertions, 23 deletions
diff --git a/clang/test/CodeGen/attr-cpuspecific.c b/clang/test/CodeGen/attr-cpuspecific.c index 744af1454a9..e249c87dfb4 100644 --- a/clang/test/CodeGen/attr-cpuspecific.c +++ b/clang/test/CodeGen/attr-cpuspecific.c @@ -7,11 +7,27 @@ #define ATTR(X) __attribute__((X)) #endif // _MSC_VER -// Each called version should have an IFunc. -// LINUX: @SingleVersion.ifunc = ifunc void (), void ()* ()* @SingleVersion.resolver -// LINUX: @TwoVersions.ifunc = ifunc void (), void ()* ()* @TwoVersions.resolver -// LINUX: @TwoVersionsSameAttr.ifunc = ifunc void (), void ()* ()* @TwoVersionsSameAttr.resolver -// LINUX: @ThreeVersionsSameAttr.ifunc = ifunc void (), void ()* ()* @ThreeVersionsSameAttr.resolver +// Each version should have an IFunc and an alias. +// LINUX: @TwoVersions = weak_odr alias void (), void ()* @TwoVersions.ifunc +// LINUX: @TwoVersionsSameAttr = weak_odr alias void (), void ()* @TwoVersionsSameAttr.ifunc +// LINUX: @ThreeVersionsSameAttr = weak_odr alias void (), void ()* @ThreeVersionsSameAttr.ifunc +// LINUX: @NoSpecifics = weak_odr alias void (), void ()* @NoSpecifics.ifunc +// LINUX: @HasGeneric = weak_odr alias void (), void ()* @HasGeneric.ifunc +// LINUX: @HasParams = weak_odr alias void (i32, double), void (i32, double)* @HasParams.ifunc +// LINUX: @HasParamsAndReturn = weak_odr alias i32 (i32, double), i32 (i32, double)* @HasParamsAndReturn.ifunc +// LINUX: @GenericAndPentium = weak_odr alias i32 (i32, double), i32 (i32, double)* @GenericAndPentium.ifunc +// LINUX: @DispatchFirst = weak_odr alias i32 (), i32 ()* @DispatchFirst.ifunc + +// LINUX: @TwoVersions.ifunc = weak_odr ifunc void (), void ()* ()* @TwoVersions.resolver +// LINUX: @SingleVersion.ifunc = weak_odr ifunc void (), void ()* ()* @SingleVersion.resolver +// LINUX: @TwoVersionsSameAttr.ifunc = weak_odr ifunc void (), void ()* ()* @TwoVersionsSameAttr.resolver +// LINUX: @ThreeVersionsSameAttr.ifunc = weak_odr ifunc void (), void ()* ()* @ThreeVersionsSameAttr.resolver +// LINUX: @NoSpecifics.ifunc = weak_odr ifunc void (), void ()* ()* @NoSpecifics.resolver +// LINUX: @HasGeneric.ifunc = weak_odr ifunc void (), void ()* ()* @HasGeneric.resolver +// LINUX: @HasParams.ifunc = weak_odr ifunc void (i32, double), void (i32, double)* ()* @HasParams.resolver +// LINUX: @HasParamsAndReturn.ifunc = weak_odr ifunc i32 (i32, double), i32 (i32, double)* ()* @HasParamsAndReturn.resolver +// LINUX: @GenericAndPentium.ifunc = weak_odr ifunc i32 (i32, double), i32 (i32, double)* ()* @GenericAndPentium.resolver +// LINUX: @DispatchFirst.ifunc = weak_odr ifunc i32 (), i32 ()* ()* @DispatchFirst.resolver ATTR(cpu_specific(ivybridge)) void SingleVersion(void){} @@ -29,14 +45,14 @@ void TwoVersions(void); ATTR(cpu_dispatch(ivybridge, knl)) void TwoVersions(void); -// LINUX: define void ()* @TwoVersions.resolver() +// LINUX: define weak_odr void ()* @TwoVersions.resolver() // LINUX: call void @__cpu_indicator_init // LINUX: ret void ()* @TwoVersions.Z // LINUX: ret void ()* @TwoVersions.S // LINUX: call void @llvm.trap // LINUX: unreachable -// WINDOWS: define dso_local void @TwoVersions() +// WINDOWS: define weak_odr dso_local void @TwoVersions() comdat // WINDOWS: call void @__cpu_indicator_init() // WINDOWS: call void @TwoVersions.Z() // WINDOWS-NEXT: ret void @@ -82,14 +98,14 @@ void usages() { // has an extra config to emit! ATTR(cpu_dispatch(ivybridge, knl, atom)) void TwoVersionsSameAttr(void); -// LINUX: define void ()* @TwoVersionsSameAttr.resolver() +// LINUX: define weak_odr void ()* @TwoVersionsSameAttr.resolver() // LINUX: ret void ()* @TwoVersionsSameAttr.Z // LINUX: ret void ()* @TwoVersionsSameAttr.S // LINUX: ret void ()* @TwoVersionsSameAttr.O // LINUX: call void @llvm.trap // LINUX: unreachable -// WINDOWS: define dso_local void @TwoVersionsSameAttr() +// WINDOWS: define weak_odr dso_local void @TwoVersionsSameAttr() comdat // WINDOWS: call void @TwoVersionsSameAttr.Z // WINDOWS-NEXT: ret void // WINDOWS: call void @TwoVersionsSameAttr.S @@ -101,7 +117,7 @@ void TwoVersionsSameAttr(void); ATTR(cpu_dispatch(atom, ivybridge, knl)) void ThreeVersionsSameAttr(void){} -// LINUX: define void ()* @ThreeVersionsSameAttr.resolver() +// LINUX: define weak_odr void ()* @ThreeVersionsSameAttr.resolver() // LINUX: call void @__cpu_indicator_init // LINUX: ret void ()* @ThreeVersionsSameAttr.Z // LINUX: ret void ()* @ThreeVersionsSameAttr.S @@ -109,7 +125,7 @@ void ThreeVersionsSameAttr(void){} // LINUX: call void @llvm.trap // LINUX: unreachable -// WINDOWS: define dso_local void @ThreeVersionsSameAttr() +// WINDOWS: define weak_odr dso_local void @ThreeVersionsSameAttr() comdat // WINDOWS: call void @__cpu_indicator_init // WINDOWS: call void @ThreeVersionsSameAttr.Z // WINDOWS-NEXT: ret void @@ -123,7 +139,7 @@ void ThreeVersionsSameAttr(void){} // No Cpu Specific options. ATTR(cpu_dispatch(atom, ivybridge, knl)) void NoSpecifics(void); -// LINUX: define void ()* @NoSpecifics.resolver() +// LINUX: define weak_odr void ()* @NoSpecifics.resolver() // LINUX: call void @__cpu_indicator_init // LINUX: ret void ()* @NoSpecifics.Z // LINUX: ret void ()* @NoSpecifics.S @@ -131,7 +147,7 @@ void NoSpecifics(void); // LINUX: call void @llvm.trap // LINUX: unreachable -// WINDOWS: define dso_local void @NoSpecifics() +// WINDOWS: define weak_odr dso_local void @NoSpecifics() comdat // WINDOWS: call void @__cpu_indicator_init // WINDOWS: call void @NoSpecifics.Z // WINDOWS-NEXT: ret void @@ -144,7 +160,7 @@ void NoSpecifics(void); ATTR(cpu_dispatch(atom, generic, ivybridge, knl)) void HasGeneric(void); -// LINUX: define void ()* @HasGeneric.resolver() +// LINUX: define weak_odr void ()* @HasGeneric.resolver() // LINUX: call void @__cpu_indicator_init // LINUX: ret void ()* @HasGeneric.Z // LINUX: ret void ()* @HasGeneric.S @@ -152,7 +168,7 @@ void HasGeneric(void); // LINUX: ret void ()* @HasGeneric.A // LINUX-NOT: call void @llvm.trap -// WINDOWS: define dso_local void @HasGeneric() +// WINDOWS: define weak_odr dso_local void @HasGeneric() comdat // WINDOWS: call void @__cpu_indicator_init // WINDOWS: call void @HasGeneric.Z // WINDOWS-NEXT: ret void @@ -166,7 +182,7 @@ void HasGeneric(void); ATTR(cpu_dispatch(atom, generic, ivybridge, knl)) void HasParams(int i, double d); -// LINUX: define void (i32, double)* @HasParams.resolver() +// LINUX: define weak_odr void (i32, double)* @HasParams.resolver() // LINUX: call void @__cpu_indicator_init // LINUX: ret void (i32, double)* @HasParams.Z // LINUX: ret void (i32, double)* @HasParams.S @@ -174,7 +190,7 @@ void HasParams(int i, double d); // LINUX: ret void (i32, double)* @HasParams.A // LINUX-NOT: call void @llvm.trap -// WINDOWS: define dso_local void @HasParams(i32 %0, double %1) +// WINDOWS: define weak_odr dso_local void @HasParams(i32 %0, double %1) comdat // WINDOWS: call void @__cpu_indicator_init // WINDOWS: call void @HasParams.Z(i32 %0, double %1) // WINDOWS-NEXT: ret void @@ -188,7 +204,7 @@ void HasParams(int i, double d); ATTR(cpu_dispatch(atom, generic, ivybridge, knl)) int HasParamsAndReturn(int i, double d); -// LINUX: define i32 (i32, double)* @HasParamsAndReturn.resolver() +// LINUX: define weak_odr i32 (i32, double)* @HasParamsAndReturn.resolver() // LINUX: call void @__cpu_indicator_init // LINUX: ret i32 (i32, double)* @HasParamsAndReturn.Z // LINUX: ret i32 (i32, double)* @HasParamsAndReturn.S @@ -196,7 +212,7 @@ int HasParamsAndReturn(int i, double d); // LINUX: ret i32 (i32, double)* @HasParamsAndReturn.A // LINUX-NOT: call void @llvm.trap -// WINDOWS: define dso_local i32 @HasParamsAndReturn(i32 %0, double %1) +// WINDOWS: define weak_odr dso_local i32 @HasParamsAndReturn(i32 %0, double %1) comdat // WINDOWS: call void @__cpu_indicator_init // WINDOWS: %[[RET:.+]] = musttail call i32 @HasParamsAndReturn.Z(i32 %0, double %1) // WINDOWS-NEXT: ret i32 %[[RET]] @@ -210,14 +226,14 @@ int HasParamsAndReturn(int i, double d); ATTR(cpu_dispatch(atom, generic, pentium)) int GenericAndPentium(int i, double d); -// LINUX: define i32 (i32, double)* @GenericAndPentium.resolver() +// LINUX: define weak_odr i32 (i32, double)* @GenericAndPentium.resolver() // LINUX: call void @__cpu_indicator_init // LINUX: ret i32 (i32, double)* @GenericAndPentium.O // LINUX: ret i32 (i32, double)* @GenericAndPentium.B // LINUX-NOT: ret i32 (i32, double)* @GenericAndPentium.A // LINUX-NOT: call void @llvm.trap -// WINDOWS: define dso_local i32 @GenericAndPentium(i32 %0, double %1) +// WINDOWS: define weak_odr dso_local i32 @GenericAndPentium(i32 %0, double %1) comdat // WINDOWS: call void @__cpu_indicator_init // WINDOWS: %[[RET:.+]] = musttail call i32 @GenericAndPentium.O(i32 %0, double %1) // WINDOWS-NEXT: ret i32 %[[RET]] @@ -228,11 +244,11 @@ int GenericAndPentium(int i, double d); ATTR(cpu_dispatch(atom, pentium)) int DispatchFirst(void); -// LINUX: define i32 ()* @DispatchFirst.resolver +// LINUX: define weak_odr i32 ()* @DispatchFirst.resolver // LINUX: ret i32 ()* @DispatchFirst.O // LINUX: ret i32 ()* @DispatchFirst.B -// WINDOWS: define dso_local i32 @DispatchFirst() +// WINDOWS: define weak_odr dso_local i32 @DispatchFirst() comdat // WINDOWS: %[[RET:.+]] = musttail call i32 @DispatchFirst.O() // WINDOWS-NEXT: ret i32 %[[RET]] // WINDOWS: %[[RET:.+]] = musttail call i32 @DispatchFirst.B() |