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