xref: /llvm-project/clang/test/CodeGenCXX/attr-target-mv-member-funcs.cpp (revision 6c12fd91540fe2f86b5032b10f04b74910b4c411)
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