Clang Project

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