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 // Test ensures that this properly differentiates between types in different
4 // namespaces.
foo(int)5 int __attribute__((target("sse4.2"))) foo(int) { return 0; }
6 int __attribute__((target("arch=sandybridge"))) foo(int);
foo(int)7 int __attribute__((target("arch=ivybridge"))) foo(int) {return 1;}
foo(int)8 int __attribute__((target("default"))) foo(int) { return 2; }
9 
10 namespace ns {
foo(int)11 int __attribute__((target("sse4.2"))) foo(int) { return 0; }
12 int __attribute__((target("arch=sandybridge"))) foo(int);
foo(int)13 int __attribute__((target("arch=ivybridge"))) foo(int) {return 1;}
foo(int)14 int __attribute__((target("default"))) foo(int) { return 2; }
15 }
16 
bar()17 int bar() {
18   return foo(1) + ns::foo(2);
19 }
20 
21 // LINUX: @_Z3fooi.ifunc = weak_odr ifunc i32 (i32), i32 (i32)* ()* @_Z3fooi.resolver
22 // LINUX: @_ZN2ns3fooEi.ifunc = weak_odr ifunc i32 (i32), i32 (i32)* ()* @_ZN2ns3fooEi.resolver
23 
24 // LINUX: define{{.*}} i32 @_Z3fooi.sse4.2(i32 %0)
25 // LINUX: ret i32 0
26 // LINUX: define{{.*}} i32 @_Z3fooi.arch_ivybridge(i32 %0)
27 // LINUX: ret i32 1
28 // LINUX: define{{.*}} i32 @_Z3fooi(i32 %0)
29 // LINUX: ret i32 2
30 
31 // WINDOWS: define dso_local i32 @"?foo@@YAHH@Z.sse4.2"(i32 %0)
32 // WINDOWS: ret i32 0
33 // WINDOWS: define dso_local i32 @"?foo@@YAHH@Z.arch_ivybridge"(i32 %0)
34 // WINDOWS: ret i32 1
35 // WINDOWS: define dso_local i32 @"?foo@@YAHH@Z"(i32 %0)
36 // WINDOWS: ret i32 2
37 
38 // LINUX: define{{.*}} i32 @_ZN2ns3fooEi.sse4.2(i32 %0)
39 // LINUX: ret i32 0
40 // LINUX: define{{.*}} i32 @_ZN2ns3fooEi.arch_ivybridge(i32 %0)
41 // LINUX: ret i32 1
42 // LINUX: define{{.*}} i32 @_ZN2ns3fooEi(i32 %0)
43 // LINUX: ret i32 2
44 
45 // WINDOWS: define dso_local i32 @"?foo@ns@@YAHH@Z.sse4.2"(i32 %0)
46 // WINDOWS: ret i32 0
47 // WINDOWS: define dso_local i32 @"?foo@ns@@YAHH@Z.arch_ivybridge"(i32 %0)
48 // WINDOWS: ret i32 1
49 // WINDOWS: define dso_local i32 @"?foo@ns@@YAHH@Z"(i32 %0)
50 // WINDOWS: ret i32 2
51 
52 // LINUX: define{{.*}} i32 @_Z3barv()
53 // LINUX: call i32 @_Z3fooi.ifunc(i32 1)
54 // LINUX: call i32 @_ZN2ns3fooEi.ifunc(i32 2)
55 
56 // WINDOWS: define dso_local i32 @"?bar@@YAHXZ"()
57 // WINDOWS: call i32 @"?foo@@YAHH@Z.resolver"(i32 1)
58 // WINDOWS: call i32 @"?foo@ns@@YAHH@Z.resolver"(i32 2)
59 
60 // LINUX: define weak_odr i32 (i32)* @_Z3fooi.resolver() comdat
61 // LINUX: ret i32 (i32)* @_Z3fooi.arch_sandybridge
62 // LINUX: ret i32 (i32)* @_Z3fooi.arch_ivybridge
63 // LINUX: ret i32 (i32)* @_Z3fooi.sse4.2
64 // LINUX: ret i32 (i32)* @_Z3fooi
65 
66 // WINDOWS: define weak_odr dso_local i32 @"?foo@@YAHH@Z.resolver"(i32 %0) comdat
67 // WINDOWS: call i32 @"?foo@@YAHH@Z.arch_sandybridge"(i32 %0)
68 // WINDOWS: call i32 @"?foo@@YAHH@Z.arch_ivybridge"(i32 %0)
69 // WINDOWS: call i32 @"?foo@@YAHH@Z.sse4.2"(i32 %0)
70 // WINDOWS: call i32 @"?foo@@YAHH@Z"(i32 %0)
71 
72 // LINUX: define weak_odr i32 (i32)* @_ZN2ns3fooEi.resolver() comdat
73 // LINUX: ret i32 (i32)* @_ZN2ns3fooEi.arch_sandybridge
74 // LINUX: ret i32 (i32)* @_ZN2ns3fooEi.arch_ivybridge
75 // LINUX: ret i32 (i32)* @_ZN2ns3fooEi.sse4.2
76 // LINUX: ret i32 (i32)* @_ZN2ns3fooEi
77 
78 // WINDOWS: define weak_odr dso_local i32 @"?foo@ns@@YAHH@Z.resolver"(i32 %0) comdat
79 // WINDOWS: call i32 @"?foo@ns@@YAHH@Z.arch_sandybridge"(i32 %0)
80 // WINDOWS: call i32 @"?foo@ns@@YAHH@Z.arch_ivybridge"(i32 %0)
81 // WINDOWS: call i32 @"?foo@ns@@YAHH@Z.sse4.2"(i32 %0)
82 // WINDOWS: call i32 @"?foo@ns@@YAHH@Z"(i32 %0)
83 
84 // LINUX: declare i32 @_Z3fooi.arch_sandybridge(i32)
85 // LINUX: declare i32 @_ZN2ns3fooEi.arch_sandybridge(i32)
86 
87 // WINDOWS: declare dso_local i32 @"?foo@@YAHH@Z.arch_sandybridge"(i32)
88 // WINDOWS: declare dso_local i32 @"?foo@ns@@YAHH@Z.arch_sandybridge"(i32)
89