Clang Project

clang_source_code/test/CodeGen/attr-target-mv.c
1// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=LINUX
2// RUN: %clang_cc1 -triple x86_64-windows-pc -emit-llvm %s -o - | FileCheck %s --check-prefix=WINDOWS
3
4int __attribute__((target("sse4.2"))) foo(void) { return 0; }
5int __attribute__((target("arch=sandybridge"))) foo(void);
6int __attribute__((target("arch=ivybridge"))) foo(void) {return 1;}
7int __attribute__((target("default"))) foo(void) { return 2; }
8
9int bar() {
10  return foo();
11}
12
13inline int __attribute__((target("sse4.2"))) foo_inline(void) { return 0; }
14inline int __attribute__((target("arch=sandybridge"))) foo_inline(void);
15inline int __attribute__((target("arch=ivybridge"))) foo_inline(void) {return 1;}
16inline int __attribute__((target("default"))) foo_inline(void) { return 2; }
17
18int bar2() {
19  return foo_inline();
20}
21
22inline __attribute__((target("default"))) void foo_decls(void);
23inline __attribute__((target("sse4.2"))) void foo_decls(void);
24void bar3() {
25  foo_decls();
26}
27inline __attribute__((target("default"))) void foo_decls(void) {}
28inline __attribute__((target("sse4.2"))) void foo_decls(void) {}
29
30inline __attribute__((target("default"))) void foo_multi(int i, double d) {}
31inline __attribute__((target("avx,sse4.2"))) void foo_multi(int i, double d) {}
32inline __attribute__((target("sse4.2,fma4"))) void foo_multi(int i, double d) {}
33inline __attribute__((target("arch=ivybridge,fma4,sse4.2"))) void foo_multi(int i, double d) {}
34void bar4() {
35  foo_multi(1, 5.0);
36}
37
38int fwd_decl_default(void);
39int __attribute__((target("default"))) fwd_decl_default(void) { return 2; }
40
41int fwd_decl_avx(void);
42int __attribute__((target("avx"))) fwd_decl_avx(void) { return 2; }
43int __attribute__((target("default"))) fwd_decl_avx(void) { return 2; }
44
45void bar5() {
46  fwd_decl_default();
47  fwd_decl_avx();
48}
49
50// LINUX: @foo.ifunc = ifunc i32 (), i32 ()* ()* @foo.resolver
51// LINUX: @foo_inline.ifunc = ifunc i32 (), i32 ()* ()* @foo_inline.resolver
52// LINUX: @foo_decls.ifunc = ifunc void (), void ()* ()* @foo_decls.resolver
53// LINUX: @foo_multi.ifunc = ifunc void (i32, double), void (i32, double)* ()* @foo_multi.resolver
54// LINUX: @fwd_decl_default.ifunc = ifunc i32 (), i32 ()* ()* @fwd_decl_default.resolver
55// LINUX: @fwd_decl_avx.ifunc = ifunc i32 (), i32 ()* ()* @fwd_decl_avx.resolver
56
57// LINUX: define i32 @foo.sse4.2()
58// LINUX: ret i32 0
59// LINUX: define i32 @foo.arch_ivybridge()
60// LINUX: ret i32 1
61// LINUX: define i32 @foo()
62// LINUX: ret i32 2
63// LINUX: define i32 @bar()
64// LINUX: call i32 @foo.ifunc()
65
66// WINDOWS: define dso_local i32 @foo.sse4.2()
67// WINDOWS: ret i32 0
68// WINDOWS: define dso_local i32 @foo.arch_ivybridge()
69// WINDOWS: ret i32 1
70// WINDOWS: define dso_local i32 @foo()
71// WINDOWS: ret i32 2
72// WINDOWS: define dso_local i32 @bar()
73// WINDOWS: call i32 @foo.resolver()
74
75// LINUX: define i32 ()* @foo.resolver() comdat
76// LINUX: call void @__cpu_indicator_init()
77// LINUX: ret i32 ()* @foo.arch_sandybridge
78// LINUX: ret i32 ()* @foo.arch_ivybridge
79// LINUX: ret i32 ()* @foo.sse4.2
80// LINUX: ret i32 ()* @foo
81
82// WINDOWS: define dso_local i32 @foo.resolver() comdat
83// WINDOWS: call void @__cpu_indicator_init()
84// WINDOWS: call i32 @foo.arch_sandybridge
85// WINDOWS: call i32 @foo.arch_ivybridge
86// WINDOWS: call i32 @foo.sse4.2
87// WINDOWS: call i32 @foo
88
89// LINUX: define i32 @bar2()
90// LINUX: call i32 @foo_inline.ifunc()
91
92// WINDOWS: define dso_local i32 @bar2()
93// WINDOWS: call i32 @foo_inline.resolver()
94
95// LINUX: define i32 ()* @foo_inline.resolver() comdat
96// LINUX: call void @__cpu_indicator_init()
97// LINUX: ret i32 ()* @foo_inline.arch_sandybridge
98// LINUX: ret i32 ()* @foo_inline.arch_ivybridge
99// LINUX: ret i32 ()* @foo_inline.sse4.2
100// LINUX: ret i32 ()* @foo_inline
101
102// WINDOWS: define dso_local i32 @foo_inline.resolver() comdat
103// WINDOWS: call void @__cpu_indicator_init()
104// WINDOWS: call i32 @foo_inline.arch_sandybridge
105// WINDOWS: call i32 @foo_inline.arch_ivybridge
106// WINDOWS: call i32 @foo_inline.sse4.2
107// WINDOWS: call i32 @foo_inline
108
109// LINUX: define void @bar3()
110// LINUX: call void @foo_decls.ifunc()
111
112// WINDOWS: define dso_local void @bar3()
113// WINDOWS: call void @foo_decls.resolver()
114
115// LINUX: define void ()* @foo_decls.resolver() comdat
116// LINUX: ret void ()* @foo_decls.sse4.2
117// LINUX: ret void ()* @foo_decls
118
119// WINDOWS: define dso_local void @foo_decls.resolver() comdat
120// WINDOWS: call void @foo_decls.sse4.2
121// WINDOWS: call void @foo_decls
122
123// LINUX: define void @bar4()
124// LINUX: call void @foo_multi.ifunc(i32 1, double 5.{{[0+e]*}})
125
126// WINDOWS: define dso_local void @bar4()
127// WINDOWS: call void @foo_multi.resolver(i32 1, double 5.{{[0+e]*}})
128
129// LINUX: define void (i32, double)* @foo_multi.resolver() comdat
130// LINUX: and i32 %{{.*}}, 4352
131// LINUX: icmp eq i32 %{{.*}}, 4352
132// LINUX: ret void (i32, double)* @foo_multi.fma4_sse4.2
133// LINUX: icmp eq i32 %{{.*}}, 12
134// LINUX: and i32 %{{.*}}, 4352
135// LINUX: icmp eq i32 %{{.*}}, 4352
136// LINUX: ret void (i32, double)* @foo_multi.arch_ivybridge_fma4_sse4.2
137// LINUX: and i32 %{{.*}}, 768
138// LINUX: icmp eq i32 %{{.*}}, 768
139// LINUX: ret void (i32, double)* @foo_multi.avx_sse4.2
140// LINUX: ret void (i32, double)* @foo_multi
141
142// WINDOWS: define dso_local void @foo_multi.resolver(i32, double) comdat
143// WINDOWS: and i32 %{{.*}}, 4352
144// WINDOWS: icmp eq i32 %{{.*}}, 4352
145// WINDOWS: call void @foo_multi.fma4_sse4.2(i32 %0, double %1)
146// WINDOWS-NEXT: ret void
147// WINDOWS: icmp eq i32 %{{.*}}, 12
148// WINDOWS: and i32 %{{.*}}, 4352
149// WINDOWS: icmp eq i32 %{{.*}}, 4352
150// WINDOWS: call void @foo_multi.arch_ivybridge_fma4_sse4.2(i32 %0, double %1)
151// WINDOWS-NEXT: ret void
152// WINDOWS: and i32 %{{.*}}, 768
153// WINDOWS: icmp eq i32 %{{.*}}, 768
154// WINDOWS: call void @foo_multi.avx_sse4.2(i32 %0, double %1)
155// WINDOWS-NEXT: ret void
156// WINDOWS: call void @foo_multi(i32 %0, double %1)
157// WINDOWS-NEXT: ret void
158
159// LINUX: define i32 @fwd_decl_default()
160// LINUX: ret i32 2
161// LINUX: define i32 @fwd_decl_avx.avx()
162// LINUX: ret i32 2
163// LINUX: define i32 @fwd_decl_avx()
164// LINUX: ret i32 2
165
166// WINDOWS: define dso_local i32 @fwd_decl_default()
167// WINDOWS: ret i32 2
168// WINDOWS: define dso_local i32 @fwd_decl_avx.avx()
169// WINDOWS: ret i32 2
170// WINDOWS: define dso_local i32 @fwd_decl_avx()
171// WINDOWS: ret i32 2
172
173// LINUX: define void @bar5()
174// LINUX: call i32 @fwd_decl_default.ifunc()
175// LINUX: call i32 @fwd_decl_avx.ifunc()
176
177// WINDOWS: define dso_local void @bar5()
178// WINDOWS: call i32 @fwd_decl_default.resolver()
179// WINDOWS: call i32 @fwd_decl_avx.resolver()
180
181// LINUX: define i32 ()* @fwd_decl_default.resolver() comdat
182// LINUX: call void @__cpu_indicator_init()
183// LINUX: ret i32 ()* @fwd_decl_default
184// LINUX: define i32 ()* @fwd_decl_avx.resolver() comdat
185// LINUX: call void @__cpu_indicator_init()
186// LINUX: ret i32 ()* @fwd_decl_avx.avx
187// LINUX: ret i32 ()* @fwd_decl_avx
188
189// WINDOWS: define dso_local i32 @fwd_decl_default.resolver() comdat
190// WINDOWS: call void @__cpu_indicator_init()
191// WINDOWS: call i32 @fwd_decl_default
192// WINDOWS: define dso_local i32 @fwd_decl_avx.resolver() comdat
193// WINDOWS: call void @__cpu_indicator_init()
194// WINDOWS: call i32 @fwd_decl_avx.avx
195// WINDOWS: call i32 @fwd_decl_avx
196
197// LINUX: declare i32 @foo.arch_sandybridge()
198// WINDOWS: declare dso_local i32 @foo.arch_sandybridge()
199
200// LINUX: define linkonce i32 @foo_inline.sse4.2()
201// LINUX: ret i32 0
202
203// WINDOWS: define linkonce_odr dso_local i32 @foo_inline.sse4.2()
204// WINDOWS: ret i32 0
205
206// LINUX: declare i32 @foo_inline.arch_sandybridge()
207
208// WINDOWS: declare dso_local i32 @foo_inline.arch_sandybridge()
209
210// LINUX: define linkonce i32 @foo_inline.arch_ivybridge()
211// LINUX: ret i32 1
212// LINUX: define linkonce i32 @foo_inline()
213// LINUX: ret i32 2
214
215// WINDOWS: define linkonce_odr dso_local i32 @foo_inline.arch_ivybridge()
216// WINDOWS: ret i32 1
217// WINDOWS: define linkonce_odr dso_local i32 @foo_inline()
218// WINDOWS: ret i32 2
219
220// LINUX: define linkonce void @foo_decls()
221// LINUX: define linkonce void @foo_decls.sse4.2()
222
223// WINDOWS: define linkonce_odr dso_local void @foo_decls()
224// WINDOWS: define linkonce_odr dso_local void @foo_decls.sse4.2()
225
226// LINUX: define linkonce void @foo_multi(i32 %{{[^,]+}}, double %{{[^\)]+}})
227// LINUX: define linkonce void @foo_multi.avx_sse4.2(i32 %{{[^,]+}}, double %{{[^\)]+}})
228// LINUX: define linkonce void @foo_multi.fma4_sse4.2(i32 %{{[^,]+}}, double %{{[^\)]+}})
229// LINUX: define linkonce void @foo_multi.arch_ivybridge_fma4_sse4.2(i32 %{{[^,]+}}, double %{{[^\)]+}})
230
231// WINDOWS: define linkonce_odr dso_local void @foo_multi(i32 %{{[^,]+}}, double %{{[^\)]+}})
232// WINDOWS: define linkonce_odr dso_local void @foo_multi.avx_sse4.2(i32 %{{[^,]+}}, double %{{[^\)]+}})
233// WINDOWS: define linkonce_odr dso_local void @foo_multi.fma4_sse4.2(i32 %{{[^,]+}}, double %{{[^\)]+}})
234// WINDOWS: define linkonce_odr dso_local void @foo_multi.arch_ivybridge_fma4_sse4.2(i32 %{{[^,]+}}, double %{{[^\)]+}})
235