1 // RUN: %clang_cc1 -no-opaque-pointers -std=c++11 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=LINUX 2 // RUN: %clang_cc1 -no-opaque-pointers -std=c++11 -triple x86_64-windows-pc -emit-llvm %s -o - | FileCheck %s --check-prefix=WINDOWS 3 4 struct 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 18 struct 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 27 int 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 38 struct 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 45 int bar2() { 46 S2 s; 47 return s.foo(0); 48 } 49 50 int __attribute__((target("sse4.2"))) S2::foo(int) { return 0; } 51 int __attribute__((target("arch=ivybridge"))) S2::foo(int) { return 1; } 52 int __attribute__((target("default"))) S2::foo(int) { return 2; } 53 54 template<typename T> 55 struct 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 62 int templ_use() { 63 templ<int> a; 64 templ<double> b; 65 return a.foo(1) + b.foo(2); 66 } 67 68 // LINUX: @_ZN1SaSERKS_.ifunc = weak_odr ifunc %struct.S* (%struct.S*, %struct.S*), %struct.S* (%struct.S*, %struct.S*)* ()* @_ZN1SaSERKS_.resolver 69 // LINUX: @_ZNK9ConvertTocv1SEv.ifunc = weak_odr ifunc void (%struct.ConvertTo*), void (%struct.ConvertTo*)* ()* @_ZNK9ConvertTocv1SEv.resolver 70 // LINUX: @_ZN1S3fooEi.ifunc = weak_odr ifunc i32 (%struct.S*, i32), i32 (%struct.S*, i32)* ()* @_ZN1S3fooEi.resolver 71 // LINUX: @_ZN2S23fooEi.ifunc = weak_odr ifunc i32 (%struct.S2*, i32), i32 (%struct.S2*, i32)* ()* @_ZN2S23fooEi.resolver 72 // Templates: 73 // LINUX: @_ZN5templIiE3fooEi.ifunc = weak_odr ifunc i32 (%struct.templ*, i32), i32 (%struct.templ*, i32)* ()* @_ZN5templIiE3fooEi.resolver 74 // LINUX: @_ZN5templIdE3fooEi.ifunc = weak_odr 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 noundef nonnull align 1 dereferenceable(1) %struct.S* @_ZN1SaSERKS_.ifunc(%struct.S* {{[^,]*}} %s2 81 // LINUX: call void @_ZNK9ConvertTocv1SEv.ifunc(%struct.ConvertTo* {{[^,]*}} %C) 82 // LINUX: call noundef nonnull align 1 dereferenceable(1) %struct.S* @_ZN1SaSERKS_.ifunc(%struct.S* {{[^,]*}} %s2 83 // LINUX: call noundef i32 @_ZN1S3fooEi.ifunc(%struct.S* {{[^,]*}} %s, i32 noundef 0) 84 85 // WINDOWS: define dso_local noundef 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 noundef nonnull align 1 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 noundef nonnull align 1 dereferenceable(1) %struct.S* @"??4S@@QEAAAEAU0@AEBU0@@Z.resolver"(%struct.S* {{[^,]*}} %s2 92 // WINDOWS: call noundef i32 @"?foo@S@@[email protected]"(%struct.S* {{[^,]*}} %s, i32 noundef 0) 93 94 // LINUX: define weak_odr %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 weak_odr dso_local %struct.S* @"??4S@@QEAAAEAU0@AEBU0@@Z.resolver"(%struct.S* %0, %struct.S* %1) 99 // WINDOWS: call %struct.S* @"??4S@@QEAAAEAU0@AEBU0@@Z.arch_ivybridge" 100 // WINDOWS: call %struct.S* @"??4S@@QEAAAEAU0@AEBU0@@Z" 101 102 // LINUX: define weak_odr 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 weak_odr dso_local void @"??BConvertTo@@QEBA?AUS@@XZ.resolver"(%struct.ConvertTo* %0, %struct.S* %1) 107 // WINDOWS: call void @"??BConvertTo@@QEBA?AUS@@XZ.arch_ivybridge" 108 // WINDOWS: call void @"??BConvertTo@@QEBA?AUS@@XZ" 109 110 // LINUX: define weak_odr 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 weak_odr dso_local i32 @"?foo@S@@[email protected]"(%struct.S* %0, i32 %1) 117 // WINDOWS: call i32 @"?foo@S@@[email protected]_sandybridge" 118 // WINDOWS: call i32 @"?foo@S@@[email protected]_ivybridge" 119 // WINDOWS: call i32 @"?foo@S@@[email protected]" 120 // WINDOWS: call i32 @"?foo@S@@QEAAHH@Z" 121 122 // LINUX: define{{.*}} i32 @_Z4bar2v() 123 // LINUX: call noundef i32 @_ZN2S23fooEi.ifunc 124 125 // WINDOWS: define dso_local noundef i32 @"?bar2@@YAHXZ"() 126 // WINDOWS: call noundef i32 @"?foo@S2@@[email protected]" 127 128 // LINUX: define weak_odr 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 weak_odr dso_local i32 @"?foo@S2@@[email protected]"(%struct.S2* %0, i32 %1) 135 // WINDOWS: call i32 @"?foo@S2@@[email protected]_sandybridge" 136 // WINDOWS: call i32 @"?foo@S2@@[email protected]_ivybridge" 137 // WINDOWS: call i32 @"?foo@S2@@[email protected]" 138 // WINDOWS: call i32 @"?foo@S2@@QEAAHH@Z" 139 140 // LINUX: define{{.*}} i32 @_ZN2S23fooEi.sse4.2(%struct.S2* {{[^,]*}} %this, i32 noundef %0) 141 // LINUX: define{{.*}} i32 @_ZN2S23fooEi.arch_ivybridge(%struct.S2* {{[^,]*}} %this, i32 noundef %0) 142 // LINUX: define{{.*}} i32 @_ZN2S23fooEi(%struct.S2* {{[^,]*}} %this, i32 noundef %0) 143 144 // WINDOWS: define dso_local noundef i32 @"?foo@S2@@[email protected]"(%struct.S2* {{[^,]*}} %this, i32 noundef %0) 145 // WINDOWS: define dso_local noundef i32 @"?foo@S2@@[email protected]_ivybridge"(%struct.S2* {{[^,]*}} %this, i32 noundef %0) 146 // WINDOWS: define dso_local noundef i32 @"?foo@S2@@QEAAHH@Z"(%struct.S2* {{[^,]*}} %this, i32 noundef %0) 147 148 // LINUX: define{{.*}} i32 @_Z9templ_usev() 149 // LINUX: call noundef i32 @_ZN5templIiE3fooEi.ifunc 150 // LINUX: call noundef i32 @_ZN5templIdE3fooEi.ifunc 151 152 // WINDOWS: define dso_local noundef i32 @"?templ_use@@YAHXZ"() 153 // WINDOWS: call noundef i32 @"?foo@?$templ@H@@[email protected]" 154 // WINDOWS: call noundef i32 @"?foo@?$templ@N@@[email protected]" 155 156 // LINUX: define weak_odr 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 weak_odr dso_local i32 @"?foo@?$templ@H@@[email protected]"(%struct.templ* %0, i32 %1) 163 // WINDOWS: call i32 @"?foo@?$templ@H@@[email protected]_sandybridge" 164 // WINDOWS: call i32 @"?foo@?$templ@H@@[email protected]_ivybridge" 165 // WINDOWS: call i32 @"?foo@?$templ@H@@[email protected]" 166 // WINDOWS: call i32 @"?foo@?$templ@H@@QEAAHH@Z" 167 168 // LINUX: define weak_odr 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 weak_odr dso_local i32 @"?foo@?$templ@N@@[email protected]"(%struct.templ.0* %0, i32 %1) comdat 175 // WINDOWS: call i32 @"?foo@?$templ@N@@[email protected]_sandybridge" 176 // WINDOWS: call i32 @"?foo@?$templ@N@@[email protected]_ivybridge" 177 // WINDOWS: call i32 @"?foo@?$templ@N@@[email protected]" 178 // WINDOWS: call i32 @"?foo@?$templ@N@@QEAAHH@Z" 179 180 // LINUX: define linkonce_odr noundef i32 @_ZN1S3fooEi.sse4.2(%struct.S* {{[^,]*}} %this, i32 noundef %0) 181 // LINUX: ret i32 0 182 183 // WINDOWS: define linkonce_odr dso_local noundef i32 @"?foo@S@@[email protected]"(%struct.S* {{[^,]*}} %this, i32 noundef %0) 184 // WINDOWS: ret i32 0 185 186 // LINUX: declare noundef i32 @_ZN1S3fooEi.arch_sandybridge(%struct.S* {{[^,]*}}, i32 noundef) 187 188 // WINDOWS: declare dso_local noundef i32 @"?foo@S@@[email protected]_sandybridge"(%struct.S* {{[^,]*}}, i32 noundef) 189 190 // LINUX: define linkonce_odr noundef i32 @_ZN1S3fooEi.arch_ivybridge(%struct.S* {{[^,]*}} %this, i32 noundef %0) 191 // LINUX: ret i32 1 192 193 // WINDOWS: define linkonce_odr dso_local noundef i32 @"?foo@S@@[email protected]_ivybridge"(%struct.S* {{[^,]*}} %this, i32 noundef %0) 194 // WINDOWS: ret i32 1 195 196 // LINUX: define linkonce_odr noundef i32 @_ZN1S3fooEi(%struct.S* {{[^,]*}} %this, i32 noundef %0) 197 // LINUX: ret i32 2 198 199 // WINDOWS: define linkonce_odr dso_local noundef i32 @"?foo@S@@QEAAHH@Z"(%struct.S* {{[^,]*}} %this, i32 noundef %0) 200 // WINDOWS: ret i32 2 201 202 // LINUX: define linkonce_odr noundef i32 @_ZN5templIiE3fooEi.sse4.2 203 // LINUX: declare noundef i32 @_ZN5templIiE3fooEi.arch_sandybridge 204 // LINUX: define linkonce_odr noundef i32 @_ZN5templIiE3fooEi.arch_ivybridge 205 // LINUX: define linkonce_odr noundef i32 @_ZN5templIiE3fooEi 206 207 // WINDOWS: define linkonce_odr dso_local noundef i32 @"?foo@?$templ@H@@[email protected]" 208 // WINDOWS: declare dso_local noundef i32 @"?foo@?$templ@H@@[email protected]_sandybridge" 209 // WINDOWS: define linkonce_odr dso_local noundef i32 @"?foo@?$templ@H@@[email protected]_ivybridge" 210 // WINDOWS: define linkonce_odr dso_local noundef i32 @"?foo@?$templ@H@@QEAAHH@Z" 211 212 // LINUX: define linkonce_odr noundef i32 @_ZN5templIdE3fooEi.sse4.2 213 // LINUX: declare noundef i32 @_ZN5templIdE3fooEi.arch_sandybridge 214 // LINUX: define linkonce_odr noundef i32 @_ZN5templIdE3fooEi.arch_ivybridge 215 // LINUX: define linkonce_odr noundef i32 @_ZN5templIdE3fooEi 216 217 // WINDOWS: define linkonce_odr dso_local noundef i32 @"?foo@?$templ@N@@[email protected]" 218 // WINDOWS: declare dso_local noundef i32 @"?foo@?$templ@N@@[email protected]_sandybridge" 219 // WINDOWS: define linkonce_odr dso_local noundef i32 @"?foo@?$templ@N@@[email protected]_ivybridge" 220 // WINDOWS: define linkonce_odr dso_local noundef i32 @"?foo@?$templ@N@@QEAAHH@Z" 221