1 // RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefixes=ITANIUM,LINUX
2 // RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-macos -emit-llvm %s -o - | FileCheck %s --check-prefixes=ITANIUM,DARWIN
3 // RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-pc -emit-llvm %s -o - | FileCheck %s --check-prefix=WINDOWS
4
5 struct S {
fooS6 int __attribute__((target("sse4.2"))) foo(int) { return 0; }
7 int __attribute__((target("arch=sandybridge"))) foo(int);
fooS8 int __attribute__((target("arch=ivybridge"))) foo(int) { return 1; }
fooS9 int __attribute__((target("default"))) foo(int) { return 2; }
10
operator =S11 S &__attribute__((target("arch=ivybridge"))) operator=(const S &) {
12 return *this;
13 }
operator =S14 S &__attribute__((target("default"))) operator=(const S &) {
15 return *this;
16 }
17 };
18
19 struct ConvertTo {
operator SConvertTo20 __attribute__((target("arch=ivybridge"))) operator S() const {
21 return S{};
22 }
operator SConvertTo23 __attribute__((target("default"))) operator S() const {
24 return S{};
25 }
26 };
27
bar()28 int bar() {
29 S s;
30 S s2;
31 s2 = s;
32
33 ConvertTo C;
34 s2 = static_cast<S>(C);
35
36 return s.foo(0);
37 }
38
39 struct S2 {
40 int __attribute__((target("sse4.2"))) foo(int);
41 int __attribute__((target("arch=sandybridge"))) foo(int);
42 int __attribute__((target("arch=ivybridge"))) foo(int);
43 int __attribute__((target("default"))) foo(int);
44 };
45
bar2()46 int bar2() {
47 S2 s;
48 return s.foo(0);
49 }
50
foo(int)51 int __attribute__((target("sse4.2"))) S2::foo(int) { return 0; }
foo(int)52 int __attribute__((target("arch=ivybridge"))) S2::foo(int) { return 1; }
foo(int)53 int __attribute__((target("default"))) S2::foo(int) { return 2; }
54
55 template<typename T>
56 struct templ {
footempl57 int __attribute__((target("sse4.2"))) foo(int) { return 0; }
58 int __attribute__((target("arch=sandybridge"))) foo(int);
footempl59 int __attribute__((target("arch=ivybridge"))) foo(int) { return 1; }
footempl60 int __attribute__((target("default"))) foo(int) { return 2; }
61 };
62
templ_use()63 int templ_use() {
64 templ<int> a;
65 templ<double> b;
66 return a.foo(1) + b.foo(2);
67 }
68
69 // DARWIN-NOT: comdat
70
71 // ITANIUM: @_ZN1SaSERKS_.ifunc = weak_odr ifunc ptr (ptr, ptr), ptr @_ZN1SaSERKS_.resolver
72 // ITANIUM: @_ZNK9ConvertTocv1SEv.ifunc = weak_odr ifunc void (ptr), ptr @_ZNK9ConvertTocv1SEv.resolver
73 // ITANIUM: @_ZN1S3fooEi.ifunc = weak_odr ifunc i32 (ptr, i32), ptr @_ZN1S3fooEi.resolver
74 // ITANIUM: @_ZN2S23fooEi.ifunc = weak_odr ifunc i32 (ptr, i32), ptr @_ZN2S23fooEi.resolver
75 // Templates:
76 // ITANIUM: @_ZN5templIiE3fooEi.ifunc = weak_odr ifunc i32 (ptr, i32), ptr @_ZN5templIiE3fooEi.resolver
77 // ITANIUM: @_ZN5templIdE3fooEi.ifunc = weak_odr ifunc i32 (ptr, i32), ptr @_ZN5templIdE3fooEi.resolver
78
79 // ITANIUM: define{{.*}} i32 @_Z3barv()
80 // ITANIUM: %s = alloca %struct.S, align 1
81 // ITANIUM: %s2 = alloca %struct.S, align 1
82 // ITANIUM: %C = alloca %struct.ConvertTo, align 1
83 // ITANIUM: call noundef nonnull align 1 dereferenceable(1) ptr @_ZN1SaSERKS_.ifunc(ptr {{[^,]*}} %s2
84 // ITANIUM: call void @_ZNK9ConvertTocv1SEv.ifunc(ptr {{[^,]*}} %C)
85 // ITANIUM: call noundef nonnull align 1 dereferenceable(1) ptr @_ZN1SaSERKS_.ifunc(ptr {{[^,]*}} %s2
86 // ITANIUM: call noundef i32 @_ZN1S3fooEi.ifunc(ptr {{[^,]*}} %s, i32 noundef 0)
87
88 // WINDOWS: define dso_local noundef i32 @"?bar@@YAHXZ"()
89 // WINDOWS: %s = alloca %struct.S, align 1
90 // WINDOWS: %s2 = alloca %struct.S, align 1
91 // WINDOWS: %C = alloca %struct.ConvertTo, align 1
92 // WINDOWS: call noundef nonnull align 1 dereferenceable(1) ptr @"??4S@@QEAAAEAU0@AEBU0@@Z.resolver"(ptr {{[^,]*}} %s2
93 // WINDOWS: call void @"??BConvertTo@@QEBA?AUS@@XZ.resolver"(ptr {{[^,]*}} %C
94 // WINDOWS: call noundef nonnull align 1 dereferenceable(1) ptr @"??4S@@QEAAAEAU0@AEBU0@@Z.resolver"(ptr {{[^,]*}} %s2
95 // WINDOWS: call noundef i32 @"?foo@S@@QEAAHH@Z.resolver"(ptr {{[^,]*}} %s, i32 noundef 0)
96
97 // ITANIUM: define weak_odr ptr @_ZN1SaSERKS_.resolver()
98 // LINUX-SAME: comdat
99 // ITANIUM: ret ptr @_ZN1SaSERKS_.arch_ivybridge
100 // ITANIUM: ret ptr @_ZN1SaSERKS_
101
102 // WINDOWS: define weak_odr dso_local ptr @"??4S@@QEAAAEAU0@AEBU0@@Z.resolver"(ptr %0, ptr %1)
103 // WINDOWS: call ptr @"??4S@@QEAAAEAU0@AEBU0@@Z.arch_ivybridge"
104 // WINDOWS: call ptr @"??4S@@QEAAAEAU0@AEBU0@@Z"
105
106 // ITANIUM: define weak_odr ptr @_ZNK9ConvertTocv1SEv.resolver()
107 // LINUX-SAME: comdat
108 // ITANIUM: ret ptr @_ZNK9ConvertTocv1SEv.arch_ivybridge
109 // ITANIUM: ret ptr @_ZNK9ConvertTocv1SEv
110
111 // WINDOWS: define weak_odr dso_local void @"??BConvertTo@@QEBA?AUS@@XZ.resolver"(ptr %0, ptr %1)
112 // WINDOWS: call void @"??BConvertTo@@QEBA?AUS@@XZ.arch_ivybridge"
113 // WINDOWS: call void @"??BConvertTo@@QEBA?AUS@@XZ"
114
115 // ITANIUM: define weak_odr ptr @_ZN1S3fooEi.resolver()
116 // LINUX-SAME: comdat
117 // ITANIUM: ret ptr @_ZN1S3fooEi.arch_sandybridge
118 // ITANIUM: ret ptr @_ZN1S3fooEi.arch_ivybridge
119 // ITANIUM: ret ptr @_ZN1S3fooEi.sse4.2
120 // ITANIUM: ret ptr @_ZN1S3fooEi
121
122 // WINDOWS: define weak_odr dso_local i32 @"?foo@S@@QEAAHH@Z.resolver"(ptr %0, i32 %1)
123 // WINDOWS: call i32 @"?foo@S@@QEAAHH@Z.arch_sandybridge"
124 // WINDOWS: call i32 @"?foo@S@@QEAAHH@Z.arch_ivybridge"
125 // WINDOWS: call i32 @"?foo@S@@QEAAHH@Z.sse4.2"
126 // WINDOWS: call i32 @"?foo@S@@QEAAHH@Z"
127
128 // ITANIUM: define{{.*}} i32 @_Z4bar2v()
129 // ITANIUM: call noundef i32 @_ZN2S23fooEi.ifunc
130
131 // WINDOWS: define dso_local noundef i32 @"?bar2@@YAHXZ"()
132 // WINDOWS: call noundef i32 @"?foo@S2@@QEAAHH@Z.resolver"
133
134 // ITANIUM: define weak_odr ptr @_ZN2S23fooEi.resolver()
135 // LINUX-SAME: comdat
136 // ITANIUM: ret ptr @_ZN2S23fooEi.arch_sandybridge
137 // ITANIUM: ret ptr @_ZN2S23fooEi.arch_ivybridge
138 // ITANIUM: ret ptr @_ZN2S23fooEi.sse4.2
139 // ITANIUM: ret ptr @_ZN2S23fooEi
140
141 // WINDOWS: define weak_odr dso_local i32 @"?foo@S2@@QEAAHH@Z.resolver"(ptr %0, i32 %1)
142 // WINDOWS: call i32 @"?foo@S2@@QEAAHH@Z.arch_sandybridge"
143 // WINDOWS: call i32 @"?foo@S2@@QEAAHH@Z.arch_ivybridge"
144 // WINDOWS: call i32 @"?foo@S2@@QEAAHH@Z.sse4.2"
145 // WINDOWS: call i32 @"?foo@S2@@QEAAHH@Z"
146
147 // ITANIUM: define{{.*}} i32 @_ZN2S23fooEi.sse4.2(ptr {{[^,]*}} %this, i32 noundef %0)
148 // ITANIUM: define{{.*}} i32 @_ZN2S23fooEi.arch_ivybridge(ptr {{[^,]*}} %this, i32 noundef %0)
149 // ITANIUM: define{{.*}} i32 @_ZN2S23fooEi(ptr {{[^,]*}} %this, i32 noundef %0)
150
151 // WINDOWS: define dso_local noundef i32 @"?foo@S2@@QEAAHH@Z.sse4.2"(ptr {{[^,]*}} %this, i32 noundef %0)
152 // WINDOWS: define dso_local noundef i32 @"?foo@S2@@QEAAHH@Z.arch_ivybridge"(ptr {{[^,]*}} %this, i32 noundef %0)
153 // WINDOWS: define dso_local noundef i32 @"?foo@S2@@QEAAHH@Z"(ptr {{[^,]*}} %this, i32 noundef %0)
154
155 // ITANIUM: define{{.*}} i32 @_Z9templ_usev()
156 // ITANIUM: call noundef i32 @_ZN5templIiE3fooEi.ifunc
157 // ITANIUM: call noundef i32 @_ZN5templIdE3fooEi.ifunc
158
159 // WINDOWS: define dso_local noundef i32 @"?templ_use@@YAHXZ"()
160 // WINDOWS: call noundef i32 @"?foo@?$templ@H@@QEAAHH@Z.resolver"
161 // WINDOWS: call noundef i32 @"?foo@?$templ@N@@QEAAHH@Z.resolver"
162
163 // ITANIUM: define weak_odr ptr @_ZN5templIiE3fooEi.resolver()
164 // LINUX-SAME: comdat
165 // ITANIUM: ret ptr @_ZN5templIiE3fooEi.arch_sandybridge
166 // ITANIUM: ret ptr @_ZN5templIiE3fooEi.arch_ivybridge
167 // ITANIUM: ret ptr @_ZN5templIiE3fooEi.sse4.2
168 // ITANIUM: ret ptr @_ZN5templIiE3fooEi
169
170 // WINDOWS: define weak_odr dso_local i32 @"?foo@?$templ@H@@QEAAHH@Z.resolver"(ptr %0, i32 %1)
171 // WINDOWS: call i32 @"?foo@?$templ@H@@QEAAHH@Z.arch_sandybridge"
172 // WINDOWS: call i32 @"?foo@?$templ@H@@QEAAHH@Z.arch_ivybridge"
173 // WINDOWS: call i32 @"?foo@?$templ@H@@QEAAHH@Z.sse4.2"
174 // WINDOWS: call i32 @"?foo@?$templ@H@@QEAAHH@Z"
175
176 // ITANIUM: define weak_odr ptr @_ZN5templIdE3fooEi.resolver()
177 // LINUX-SAME: comdat
178 // ITANIUM: ret ptr @_ZN5templIdE3fooEi.arch_sandybridge
179 // ITANIUM: ret ptr @_ZN5templIdE3fooEi.arch_ivybridge
180 // ITANIUM: ret ptr @_ZN5templIdE3fooEi.sse4.2
181 // ITANIUM: ret ptr @_ZN5templIdE3fooEi
182
183 // WINDOWS: define weak_odr dso_local i32 @"?foo@?$templ@N@@QEAAHH@Z.resolver"(ptr %0, i32 %1) comdat
184 // WINDOWS: call i32 @"?foo@?$templ@N@@QEAAHH@Z.arch_sandybridge"
185 // WINDOWS: call i32 @"?foo@?$templ@N@@QEAAHH@Z.arch_ivybridge"
186 // WINDOWS: call i32 @"?foo@?$templ@N@@QEAAHH@Z.sse4.2"
187 // WINDOWS: call i32 @"?foo@?$templ@N@@QEAAHH@Z"
188
189 // ITANIUM: define linkonce_odr noundef i32 @_ZN1S3fooEi.sse4.2(ptr {{[^,]*}} %this, i32 noundef %0)
190 // ITANIUM: ret i32 0
191
192 // WINDOWS: define linkonce_odr dso_local noundef i32 @"?foo@S@@QEAAHH@Z.sse4.2"(ptr {{[^,]*}} %this, i32 noundef %0)
193 // WINDOWS: ret i32 0
194
195 // ITANIUM: declare noundef i32 @_ZN1S3fooEi.arch_sandybridge(ptr {{[^,]*}}, i32 noundef)
196
197 // WINDOWS: declare dso_local noundef i32 @"?foo@S@@QEAAHH@Z.arch_sandybridge"(ptr {{[^,]*}}, i32 noundef)
198
199 // ITANIUM: define linkonce_odr noundef i32 @_ZN1S3fooEi.arch_ivybridge(ptr {{[^,]*}} %this, i32 noundef %0)
200 // ITANIUM: ret i32 1
201
202 // WINDOWS: define linkonce_odr dso_local noundef i32 @"?foo@S@@QEAAHH@Z.arch_ivybridge"(ptr {{[^,]*}} %this, i32 noundef %0)
203 // WINDOWS: ret i32 1
204
205 // ITANIUM: define linkonce_odr noundef i32 @_ZN1S3fooEi(ptr {{[^,]*}} %this, i32 noundef %0)
206 // ITANIUM: ret i32 2
207
208 // WINDOWS: define linkonce_odr dso_local noundef i32 @"?foo@S@@QEAAHH@Z"(ptr {{[^,]*}} %this, i32 noundef %0)
209 // WINDOWS: ret i32 2
210
211 // ITANIUM: define linkonce_odr noundef i32 @_ZN5templIiE3fooEi.sse4.2
212 // ITANIUM: declare noundef i32 @_ZN5templIiE3fooEi.arch_sandybridge
213 // ITANIUM: define linkonce_odr noundef i32 @_ZN5templIiE3fooEi.arch_ivybridge
214 // ITANIUM: define linkonce_odr noundef i32 @_ZN5templIiE3fooEi
215
216 // WINDOWS: define linkonce_odr dso_local noundef i32 @"?foo@?$templ@H@@QEAAHH@Z.sse4.2"
217 // WINDOWS: declare dso_local noundef i32 @"?foo@?$templ@H@@QEAAHH@Z.arch_sandybridge"
218 // WINDOWS: define linkonce_odr dso_local noundef i32 @"?foo@?$templ@H@@QEAAHH@Z.arch_ivybridge"
219 // WINDOWS: define linkonce_odr dso_local noundef i32 @"?foo@?$templ@H@@QEAAHH@Z"
220
221 // ITANIUM: define linkonce_odr noundef i32 @_ZN5templIdE3fooEi.sse4.2
222 // ITANIUM: declare noundef i32 @_ZN5templIdE3fooEi.arch_sandybridge
223 // ITANIUM: define linkonce_odr noundef i32 @_ZN5templIdE3fooEi.arch_ivybridge
224 // ITANIUM: define linkonce_odr noundef i32 @_ZN5templIdE3fooEi
225
226 // WINDOWS: define linkonce_odr dso_local noundef i32 @"?foo@?$templ@N@@QEAAHH@Z.sse4.2"
227 // WINDOWS: declare dso_local noundef i32 @"?foo@?$templ@N@@QEAAHH@Z.arch_sandybridge"
228 // WINDOWS: define linkonce_odr dso_local noundef i32 @"?foo@?$templ@N@@QEAAHH@Z.arch_ivybridge"
229 // WINDOWS: define linkonce_odr dso_local noundef i32 @"?foo@?$templ@N@@QEAAHH@Z"
230