1 // RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=LINUX 2 // RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-pc -emit-llvm %s -o - | FileCheck %s --check-prefix=WINDOWS 3 4 // Overloaded ifuncs 5 // LINUX: @_Z10overloadedi.ifunc = weak_odr ifunc i32 (i32), i32 (i32)* ()* @_Z10overloadedi.resolver 6 // LINUX: @_Z10overloadedPKc.ifunc = weak_odr ifunc i32 (i8*), i32 (i8*)* ()* @_Z10overloadedPKc.resolver 7 // struct 'C' ifuncs, note the 'float, U' one doesn't get one. 8 // LINUX: @_ZN1CIssE3fooEv.ifunc = weak_odr ifunc i32 (%struct.C*), i32 (%struct.C*)* ()* @_ZN1CIssE3fooEv.resolver 9 // LINUX: @_ZN1CIisE3fooEv.ifunc = weak_odr ifunc i32 (%struct.C.0*), i32 (%struct.C.0*)* ()* @_ZN1CIisE3fooEv.resolver 10 // LINUX: @_ZN1CIdfE3fooEv.ifunc = weak_odr ifunc i32 (%struct.C.2*), i32 (%struct.C.2*)* ()* @_ZN1CIdfE3fooEv.resolver 11 12 int __attribute__((target_clones("sse4.2", "default"))) overloaded(int) { return 1; } 13 // LINUX: define {{.*}}i32 @_Z10overloadedi.sse4.2.0(i32{{.+}}) 14 // LINUX: define {{.*}}i32 @_Z10overloadedi.default.1(i32{{.+}}) 15 // LINUX: define i32 (i32)* @_Z10overloadedi.resolver 16 // LINUX: ret i32 (i32)* @_Z10overloadedi.sse4.2.0 17 // LINUX: ret i32 (i32)* @_Z10overloadedi.default.1 18 19 // WINDOWS: define dso_local noundef i32 @"?overloaded@@[email protected]"(i32{{.+}}) 20 // WINDOWS: define dso_local noundef i32 @"?overloaded@@[email protected]"(i32{{.+}}) 21 // WINDOWS: define dso_local i32 @"?overloaded@@YAHH@Z"(i32{{.+}}) 22 // WINDOWS: call i32 @"?overloaded@@[email protected]" 23 // WINDOWS: call i32 @"?overloaded@@[email protected]" 24 25 int __attribute__((target_clones("arch=ivybridge", "default"))) overloaded(const char *) { return 2; } 26 // LINUX: define {{.*}}i32 @_Z10overloadedPKc.arch_ivybridge.0(i8*{{.+}}) 27 // LINUX: define {{.*}}i32 @_Z10overloadedPKc.default.1(i8*{{.+}}) 28 // LINUX: define i32 (i8*)* @_Z10overloadedPKc.resolver 29 // LINUX: ret i32 (i8*)* @_Z10overloadedPKc.arch_ivybridge.0 30 // LINUX: ret i32 (i8*)* @_Z10overloadedPKc.default.1 31 32 // WINDOWS: define dso_local noundef i32 @"?overloaded@@[email protected]_ivybridge.0"(i8*{{.+}}) 33 // WINDOWS: define dso_local noundef i32 @"?overloaded@@[email protected]"(i8*{{.+}}) 34 // WINDOWS: define dso_local i32 @"?overloaded@@YAHPEBD@Z"(i8*{{.+}}) 35 // WINDOWS: call i32 @"?overloaded@@[email protected]_ivybridge.0" 36 // WINDOWS: call i32 @"?overloaded@@[email protected]" 37 // 38 void use_overloaded() { 39 overloaded(1); 40 // LINUX: call noundef i32 @_Z10overloadedi.ifunc 41 // WINDOWS: call noundef i32 @"?overloaded@@YAHH@Z" 42 overloaded(nullptr); 43 // LINUX: call noundef i32 @_Z10overloadedPKc.ifunc 44 // WINDOWS: call noundef i32 @"?overloaded@@YAHPEBD@Z" 45 } 46 47 template<typename T, typename U> 48 struct C { 49 int __attribute__((target_clones("sse4.2", "default"))) foo(){ return 1;} 50 }; 51 template<typename U> 52 struct C<int, U> { 53 int __attribute__((target_clones("sse4.2", "default"))) foo(){ return 2;} 54 }; 55 template<typename U> 56 struct C<float, U> { 57 int foo(){ return 2;} 58 }; 59 template<> 60 struct C<double, float> { 61 int __attribute__((target_clones("sse4.2", "default"))) foo(){ return 3;} 62 }; 63 64 void uses_specialized() { 65 C<short, short> c; 66 c.foo(); 67 // LINUX: call noundef i32 @_ZN1CIssE3fooEv.ifunc(%struct.C 68 // WINDOWS: call noundef i32 @"?foo@?$C@FF@@QEAAHXZ"(%struct.C 69 C<int, short> c2; 70 c2.foo(); 71 // LINUX: call noundef i32 @_ZN1CIisE3fooEv.ifunc(%struct.C 72 // WINDOWS: call noundef i32 @"?foo@?$C@HF@@QEAAHXZ"(%struct.C 73 C<float, short> c3; 74 c3.foo(); 75 // Note this is not an ifunc/mv 76 // LINUX: call noundef i32 @_ZN1CIfsE3fooEv(%struct.C 77 // WINDOWS: call noundef i32 @"?foo@?$C@MF@@QEAAHXZ"(%struct.C 78 C<double, float> c4; 79 c4.foo(); 80 // LINUX: call noundef i32 @_ZN1CIdfE3fooEv.ifunc(%struct.C 81 // WINDOWS: call noundef i32 @"?foo@?$C@NM@@QEAAHXZ"(%struct.C 82 } 83 84 // LINUX: define {{.*}}i32 @_ZN1CIssE3fooEv.sse4.2.0(%struct.C{{.+}}) 85 // WINDOWS: define {{.*}}i32 @"?foo@?$C@FF@@QEAAHXZ.sse4.2.0"(%struct.C{{.+}}) 86 // LINUX: define i32 (%struct.C*)* @_ZN1CIssE3fooEv.resolver 87 // LINUX: ret i32 (%struct.C*)* @_ZN1CIssE3fooEv.sse4.2.0 88 // LINUX: ret i32 (%struct.C*)* @_ZN1CIssE3fooEv.default.1 89 // WINDOWS: define {{.*}}i32 @"?foo@?$C@FF@@QEAAHXZ"(%struct.C{{.+}}) 90 // WINDOWS: call i32 @"?foo@?$C@FF@@QEAAHXZ.sse4.2.0" 91 // WINDOWS: call i32 @"?foo@?$C@FF@@QEAAHXZ.default.1" 92 93 // LINUX: define {{.*}}i32 @_ZN1CIisE3fooEv.sse4.2.0(%struct.C{{.+}}) 94 // WINDOWS: define {{.*}}i32 @"?foo@?$C@HF@@QEAAHXZ.sse4.2.0"(%struct.C{{.+}}) 95 // LINUX: define i32 (%struct.C{{.+}})* @_ZN1CIisE3fooEv.resolver 96 // LINUX: ret i32 (%struct.C{{.+}})* @_ZN1CIisE3fooEv.sse4.2.0 97 // LINUX: ret i32 (%struct.C{{.+}})* @_ZN1CIisE3fooEv.default.1 98 // WINDOWS: define {{.*}}i32 @"?foo@?$C@HF@@QEAAHXZ"(%struct.C{{.+}}) 99 // WINDOWS: call i32 @"?foo@?$C@HF@@QEAAHXZ.sse4.2.0" 100 // WINDOWS: call i32 @"?foo@?$C@HF@@QEAAHXZ.default.1" 101 102 // LINUX: define i32 (%struct.C{{.+}})* @_ZN1CIdfE3fooEv.resolver 103 // LINUX: ret i32 (%struct.C{{.+}})* @_ZN1CIdfE3fooEv.sse4.2.0 104 // LINUX: ret i32 (%struct.C{{.+}})* @_ZN1CIdfE3fooEv.default.1 105 // WINDOWS: define {{.*}}i32 @"?foo@?$C@NM@@QEAAHXZ"(%struct.C{{.+}}) 106 // WINDOWS: call i32 @"?foo@?$C@NM@@QEAAHXZ.sse4.2.0" 107 // WINDOWS: call i32 @"?foo@?$C@NM@@QEAAHXZ.default.1" 108 109 // LINUX: define {{.*}}i32 @_ZN1CIdfE3fooEv.sse4.2.0(%struct.C{{.+}}) 110 // WINDOWS: define {{.*}}i32 @"?foo@?$C@NM@@QEAAHXZ.sse4.2.0"(%struct.C{{.+}}) 111 // LINUX: define {{.*}}i32 @_ZN1CIdfE3fooEv.default.1(%struct.C{{.+}}) 112 // WINDOWS: define {{.*}}i32 @"?foo@?$C@NM@@QEAAHXZ.default.1"(%struct.C{{.+}}) 113 // LINUX: define {{.*}}i32 @_ZN1CIssE3fooEv.default.1(%struct.C{{.+}}) 114 // WINDOWS: define {{.*}}i32 @"?foo@?$C@FF@@QEAAHXZ.default.1"(%struct.C{{.+}}) 115 // LINUX: define {{.*}}i32 @_ZN1CIisE3fooEv.default.1(%struct.C{{.+}}) 116 // WINDOWS: define {{.*}}i32 @"?foo@?$C@HF@@QEAAHXZ.default.1"(%struct.C{{.+}}) 117