1 // RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s
2 int __attribute__((target("sse4.2"))) foo(void) { return 0; }
3 int __attribute__((target("arch=sandybridge"))) foo(void);
4 int __attribute__((target("arch=ivybridge"))) foo(void) {return 1;}
5 int __attribute__((target("default"))) foo(void) { return 2; }
6 
7 int bar() {
8   return foo();
9 }
10 
11 inline int __attribute__((target("sse4.2"))) foo_inline(void) { return 0; }
12 inline int __attribute__((target("arch=sandybridge"))) foo_inline(void);
13 inline int __attribute__((target("arch=ivybridge"))) foo_inline(void) {return 1;}
14 inline int __attribute__((target("default"))) foo_inline(void) { return 2; }
15 
16 int bar2() {
17   return foo_inline();
18 }
19 
20 inline __attribute__((target("default"))) void foo_decls(void);
21 inline __attribute__((target("sse4.2"))) void foo_decls(void);
22 void bar3() {
23   foo_decls();
24 }
25 inline __attribute__((target("default"))) void foo_decls(void) {}
26 inline __attribute__((target("sse4.2"))) void foo_decls(void) {}
27 
28 inline __attribute__((target("default"))) void foo_multi(void) {}
29 inline __attribute__((target("avx,sse4.2"))) void foo_multi(void) {}
30 inline __attribute__((target("sse4.2,fma4"))) void foo_multi(void) {}
31 inline __attribute__((target("arch=ivybridge,fma4,sse4.2"))) void foo_multi(void) {}
32 void bar4() {
33   foo_multi();
34 }
35 
36 // CHECK: @foo.ifunc = ifunc i32 (), i32 ()* ()* @foo.resolver
37 // CHECK: @foo_inline.ifunc = ifunc i32 (), i32 ()* ()* @foo_inline.resolver
38 // CHECK: @foo_decls.ifunc = ifunc void (), void ()* ()* @foo_decls.resolver
39 
40 // CHECK: define i32 @foo.sse4.2()
41 // CHECK: ret i32 0
42 // CHECK: define i32 @foo.arch_ivybridge()
43 // CHECK: ret i32 1
44 // CHECK: define i32 @foo()
45 // CHECK: ret i32 2
46 // CHECK: define i32 @bar()
47 // CHECK: call i32 @foo.ifunc()
48 
49 // CHECK: define i32 ()* @foo.resolver() comdat
50 // CHECK: call void @__cpu_indicator_init()
51 // CHECK: ret i32 ()* @foo.arch_sandybridge
52 // CHECK: ret i32 ()* @foo.arch_ivybridge
53 // CHECK: ret i32 ()* @foo.sse4.2
54 // CHECK: ret i32 ()* @foo
55 
56 // CHECK: define i32 @bar2()
57 // CHECK: call i32 @foo_inline.ifunc()
58 
59 // CHECK: define i32 ()* @foo_inline.resolver() comdat
60 // CHECK: call void @__cpu_indicator_init()
61 // CHECK: ret i32 ()* @foo_inline.arch_sandybridge
62 // CHECK: ret i32 ()* @foo_inline.arch_ivybridge
63 // CHECK: ret i32 ()* @foo_inline.sse4.2
64 // CHECK: ret i32 ()* @foo_inline
65 
66 // CHECK: define void @bar3()
67 // CHECK: call void @foo_decls.ifunc()
68 
69 // CHECK: define void ()* @foo_decls.resolver() comdat
70 // CHECK: ret void ()* @foo_decls.sse4.2
71 // CHECK: ret void ()* @foo_decls
72 
73 // CHECK: declare i32 @foo.arch_sandybridge()
74 
75 // CHECK: define available_externally i32 @foo_inline.sse4.2()
76 // CHECK: ret i32 0
77 
78 // CHECK: declare i32 @foo_inline.arch_sandybridge()
79 //
80 // CHECK: define available_externally i32 @foo_inline.arch_ivybridge()
81 // CHECK: ret i32 1
82 // CHECK: define available_externally i32 @foo_inline()
83 // CHECK: ret i32 2
84 
85 // CHECK: define available_externally void @foo_decls()
86 // CHECK: define available_externally void @foo_decls.sse4.2()
87 
88 // CHECK: define available_externally void @foo_multi.avx_sse4.2()
89 // CHECK: define available_externally void @foo_multi.fma4_sse4.2()
90 // CHECK: define available_externally void @foo_multi.arch_ivybridge_fma4_sse4.2()
91 
92