1 // RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefixes=LINUX,CHECK
2 // RUN: %clang_cc1 -triple x86_64-windows-pc -emit-llvm %s -o - | FileCheck %s --check-prefixes=WINDOWS,CHECK
4 // LINUX: $foo.resolver = comdat any
5 // LINUX: $foo_dupes.resolver = comdat any
6 // LINUX: $unused.resolver = comdat any
7 // LINUX: $foo_inline.resolver = comdat any
8 // LINUX: $foo_inline2.resolver = comdat any
10 // WINDOWS: $foo = comdat any
11 // WINDOWS: $foo_dupes = comdat any
12 // WINDOWS: $unused = comdat any
13 // WINDOWS: $foo_inline = comdat any
14 // WINDOWS: $foo_inline2 = comdat any
16 // LINUX: @__cpu_model = external dso_local global { i32, i32, i32, [1 x i32] }
17 // LINUX: @__cpu_features2 = external dso_local global [3 x i32]
19 // LINUX: @internal.ifunc = internal ifunc i32 (), ptr @internal.resolver
20 // LINUX: @foo.ifunc = weak_odr ifunc i32 (), ptr @foo.resolver
21 // LINUX: @foo_dupes.ifunc = weak_odr ifunc void (), ptr @foo_dupes.resolver
22 // LINUX: @unused.ifunc = weak_odr ifunc void (), ptr @unused.resolver
23 // LINUX: @foo_inline.ifunc = weak_odr ifunc i32 (), ptr @foo_inline.resolver
24 // LINUX: @foo_inline2.ifunc = weak_odr ifunc i32 (), ptr @foo_inline2.resolver
25 // LINUX: @foo_used_no_defn.ifunc = weak_odr ifunc i32 (), ptr @foo_used_no_defn.resolver
27 static int __attribute__((target_clones("sse4.2, default"))) internal(void) { return 0; }
28 int use(void) { return internal(); }
29 /// Internal linkage resolvers do not use comdat.
30 // LINUX: define internal ptr @internal.resolver() {
31 // WINDOWS: define internal i32 @internal() {
33 int __attribute__((target_clones("sse4.2, default"))) foo(void) { return 0; }
34 // LINUX: define {{.*}}i32 @foo.sse4.2.0()
35 // LINUX: define {{.*}}i32 @foo.default.1()
36 // LINUX: define weak_odr ptr @foo.resolver() comdat
37 // LINUX: ret ptr @foo.sse4.2.0
38 // LINUX: ret ptr @foo.default.1
40 // WINDOWS: define dso_local i32 @foo.sse4.2.0()
41 // WINDOWS: define dso_local i32 @foo.default.1()
42 // WINDOWS: define weak_odr dso_local i32 @foo() comdat
43 // WINDOWS: musttail call i32 @foo.sse4.2.0
44 // WINDOWS: musttail call i32 @foo.default.1
46 __attribute__((target_clones("default,default ,sse4.2"))) void foo_dupes(void) {}
47 // LINUX: define {{.*}}void @foo_dupes.default.1()
48 // LINUX: define {{.*}}void @foo_dupes.sse4.2.0()
49 // LINUX: define weak_odr ptr @foo_dupes.resolver() comdat
50 // LINUX: ret ptr @foo_dupes.sse4.2.0
51 // LINUX: ret ptr @foo_dupes.default.1
53 // WINDOWS: define dso_local void @foo_dupes.default.1()
54 // WINDOWS: define dso_local void @foo_dupes.sse4.2.0()
55 // WINDOWS: define weak_odr dso_local void @foo_dupes() comdat
56 // WINDOWS: musttail call void @foo_dupes.sse4.2.0
57 // WINDOWS: musttail call void @foo_dupes.default.1
60 // LINUX: define {{.*}}void @bar2()
61 // WINDOWS: define dso_local void @bar2()
63 // LINUX: call void @foo_dupes.ifunc()
64 // WINDOWS: call void @foo_dupes()
68 // LINUX: define {{.*}}i32 @bar() #[[DEF:[0-9]+]]
69 // WINDOWS: define dso_local i32 @bar() #[[DEF:[0-9]+]]
71 // LINUX: call i32 @foo.ifunc()
72 // WINDOWS: call i32 @foo()
75 void __attribute__((target_clones("default, arch=ivybridge"))) unused(void) {}
76 // LINUX: define {{.*}}void @unused.default.1()
77 // LINUX: define {{.*}}void @unused.arch_ivybridge.0()
78 // LINUX: define weak_odr ptr @unused.resolver() comdat
79 // LINUX: ret ptr @unused.arch_ivybridge.0
80 // LINUX: ret ptr @unused.default.1
82 // WINDOWS: define dso_local void @unused.default.1()
83 // WINDOWS: define dso_local void @unused.arch_ivybridge.0()
84 // WINDOWS: define weak_odr dso_local void @unused() comdat
85 // WINDOWS: musttail call void @unused.arch_ivybridge.0
86 // WINDOWS: musttail call void @unused.default.1
89 inline int __attribute__((target_clones("arch=sandybridge,default,sse4.2")))
90 foo_inline(void) { return 0; }
91 inline int __attribute__((target_clones("arch=sandybridge,default,sse4.2")))
95 // LINUX: define {{.*}}i32 @bar3()
96 // WINDOWS: define dso_local i32 @bar3()
97 return foo_inline() + foo_inline2();
98 // LINUX: call i32 @foo_inline.ifunc()
99 // LINUX: call i32 @foo_inline2.ifunc()
100 // WINDOWS: call i32 @foo_inline()
101 // WINDOWS: call i32 @foo_inline2()
104 // LINUX: define weak_odr ptr @foo_inline.resolver() comdat
105 // LINUX: ret ptr @foo_inline.arch_sandybridge.0
106 // LINUX: ret ptr @foo_inline.sse4.2.1
107 // LINUX: ret ptr @foo_inline.default.2
109 // WINDOWS: define weak_odr dso_local i32 @foo_inline() comdat
110 // WINDOWS: musttail call i32 @foo_inline.arch_sandybridge.0
111 // WINDOWS: musttail call i32 @foo_inline.sse4.2.1
112 // WINDOWS: musttail call i32 @foo_inline.default.2
114 inline int __attribute__((target_clones("arch=sandybridge,default,sse4.2")))
115 foo_inline2(void){ return 0; }
116 // LINUX: define weak_odr ptr @foo_inline2.resolver() comdat
117 // LINUX: ret ptr @foo_inline2.arch_sandybridge.0
118 // LINUX: ret ptr @foo_inline2.sse4.2.1
119 // LINUX: ret ptr @foo_inline2.default.2
121 // WINDOWS: define weak_odr dso_local i32 @foo_inline2() comdat
122 // WINDOWS: musttail call i32 @foo_inline2.arch_sandybridge.0
123 // WINDOWS: musttail call i32 @foo_inline2.sse4.2.1
124 // WINDOWS: musttail call i32 @foo_inline2.default.2
127 int __attribute__((target_clones("default", "sse4.2")))
128 foo_unused_no_defn(void);
130 int __attribute__((target_clones("default", "sse4.2")))
131 foo_used_no_defn(void);
133 int test_foo_used_no_defn(void) {
134 // LINUX: define {{.*}}i32 @test_foo_used_no_defn()
135 // WINDOWS: define dso_local i32 @test_foo_used_no_defn()
136 return foo_used_no_defn();
137 // LINUX: call i32 @foo_used_no_defn.ifunc()
138 // WINDOWS: call i32 @foo_used_no_defn()
142 // LINUX: define weak_odr ptr @foo_used_no_defn.resolver() comdat
143 // LINUX: ret ptr @foo_used_no_defn.sse4.2.0
144 // LINUX: ret ptr @foo_used_no_defn.default.1
146 // WINDOWS: define weak_odr dso_local i32 @foo_used_no_defn() comdat
147 // WINDOWS: musttail call i32 @foo_used_no_defn.sse4.2.0
148 // WINDOWS: musttail call i32 @foo_used_no_defn.default.1
150 __attribute__((target_clones("default", "arch=x86-64", "arch=x86-64-v2", "arch=x86-64-v3", "arch=x86-64-v4")))
151 int isa_level(int) { return 0; }
152 // LINUX: define{{.*}} i32 @isa_level.default.4(
153 // LINUX: define{{.*}} i32 @isa_level.arch_x86-64.0(
154 // LINUX: define{{.*}} i32 @isa_level.arch_x86-64-v2.1(
155 // LINUX: define{{.*}} i32 @isa_level.arch_x86-64-v3.2(
156 // LINUX: define{{.*}} i32 @isa_level.arch_x86-64-v4.3(
157 // LINUX: define weak_odr ptr @isa_level.resolver() comdat
158 // LINUX: call void @__cpu_indicator_init()
159 // LINUX-NEXT: load i32, ptr getelementptr inbounds ([3 x i32], ptr @__cpu_features2, i32 0, i32 2)
160 // LINUX-NEXT: and i32 %[[#]], 4
161 // LINUX: ret ptr @isa_level.arch_x86-64-v4.3
162 // LINUX: load i32, ptr getelementptr inbounds ([3 x i32], ptr @__cpu_features2, i32 0, i32 2)
163 // LINUX-NEXT: and i32 %[[#]], 2
164 // LINUX: ret ptr @isa_level.arch_x86-64-v3.2
165 // LINUX: load i32, ptr getelementptr inbounds ([3 x i32], ptr @__cpu_features2, i32 0, i32 2)
166 // LINUX-NEXT: and i32 %[[#]], 1
167 // LINUX: ret ptr @isa_level.arch_x86-64-v2.1
168 // LINUX: load i32, ptr getelementptr inbounds ([3 x i32], ptr @__cpu_features2, i32 0, i32 1)
169 // LINUX-NEXT: and i32 %[[#]], -2147483648
170 // LINUX: ret ptr @isa_level.arch_x86-64.0
171 // LINUX: ret ptr @isa_level.default.4
173 // Deferred emission of inline definitions.
175 // LINUX: define linkonce i32 @foo_inline.arch_sandybridge.0() #[[SB:[0-9]+]]
176 // LINUX: define linkonce i32 @foo_inline.default.2() #[[DEF:[0-9]+]]
177 // LINUX: define linkonce i32 @foo_inline.sse4.2.1() #[[SSE42:[0-9]+]]
179 // WINDOWS: define linkonce_odr dso_local i32 @foo_inline.arch_sandybridge.0() #[[SB:[0-9]+]]
180 // WINDOWS: define linkonce_odr dso_local i32 @foo_inline.default.2() #[[DEF]]
181 // WINDOWS: define linkonce_odr dso_local i32 @foo_inline.sse4.2.1() #[[SSE42:[0-9]+]]
184 // LINUX: define linkonce i32 @foo_inline2.arch_sandybridge.0() #[[SB]]
185 // LINUX: define linkonce i32 @foo_inline2.default.2() #[[DEF]]
186 // LINUX: define linkonce i32 @foo_inline2.sse4.2.1() #[[SSE42]]
188 // WINDOWS: define linkonce_odr dso_local i32 @foo_inline2.arch_sandybridge.0() #[[SB]]
189 // WINDOWS: define linkonce_odr dso_local i32 @foo_inline2.default.2() #[[DEF]]
190 // WINDOWS: define linkonce_odr dso_local i32 @foo_inline2.sse4.2.1() #[[SSE42]]
193 // LINUX: declare i32 @foo_used_no_defn.default.1()
194 // LINUX: declare i32 @foo_used_no_defn.sse4.2.0()
196 // WINDOWS: declare dso_local i32 @foo_used_no_defn.default.1()
197 // WINDOWS: declare dso_local i32 @foo_used_no_defn.sse4.2.0()
200 // CHECK: attributes #[[SSE42]] =
201 // CHECK-SAME: "target-features"="+crc32,+cx8,+mmx,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87"
202 // CHECK: attributes #[[SB]] =
203 // CHECK-SAME: "target-features"="+avx,+cmov,+crc32,+cx16,+cx8,+fxsr,+mmx,+pclmul,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"