1 // RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s 2 3 struct S { 4 int __attribute__((target("sse4.2"))) foo(int) { return 0; } 5 int __attribute__((target("arch=sandybridge"))) foo(int); 6 int __attribute__((target("arch=ivybridge"))) foo(int) { return 1; } 7 int __attribute__((target("default"))) foo(int) { return 2; } 8 9 S &__attribute__((target("arch=ivybridge"))) operator=(const S &) { 10 return *this; 11 } 12 S &__attribute__((target("default"))) operator=(const S &) { 13 return *this; 14 } 15 }; 16 17 struct ConvertTo { 18 __attribute__((target("arch=ivybridge"))) operator S() const { 19 return S{}; 20 } 21 __attribute__((target("default"))) operator S() const { 22 return S{}; 23 } 24 }; 25 26 int bar() { 27 S s; 28 S s2; 29 s2 = s; 30 31 ConvertTo C; 32 s2 = static_cast<S>(C); 33 34 return s.foo(0); 35 } 36 37 struct S2 { 38 int __attribute__((target("sse4.2"))) foo(int); 39 int __attribute__((target("arch=sandybridge"))) foo(int); 40 int __attribute__((target("arch=ivybridge"))) foo(int); 41 int __attribute__((target("default"))) foo(int); 42 }; 43 44 int bar2() { 45 S2 s; 46 return s.foo(0); 47 } 48 49 int __attribute__((target("sse4.2"))) S2::foo(int) { return 0; } 50 int __attribute__((target("arch=ivybridge"))) S2::foo(int) { return 1; } 51 int __attribute__((target("default"))) S2::foo(int) { return 2; } 52 53 template<typename T> 54 struct templ { 55 int __attribute__((target("sse4.2"))) foo(int) { return 0; } 56 int __attribute__((target("arch=sandybridge"))) foo(int); 57 int __attribute__((target("arch=ivybridge"))) foo(int) { return 1; } 58 int __attribute__((target("default"))) foo(int) { return 2; } 59 }; 60 61 int templ_use() { 62 templ<int> a; 63 templ<double> b; 64 return a.foo(1) + b.foo(2); 65 } 66 67 // CHECK: @_ZN1SaSERKS_.ifunc = ifunc %struct.S* (%struct.S*, %struct.S*), %struct.S* (%struct.S*, %struct.S*)* ()* @_ZN1SaSERKS_.resolver 68 // CHECK: @_ZNK9ConvertTocv1SEv.ifunc = ifunc void (%struct.ConvertTo*), void (%struct.ConvertTo*)* ()* @_ZNK9ConvertTocv1SEv.resolver 69 // CHECK: @_ZN1S3fooEi.ifunc = ifunc i32 (%struct.S*, i32), i32 (%struct.S*, i32)* ()* @_ZN1S3fooEi.resolver 70 // CHECK: @_ZN2S23fooEi.ifunc = ifunc i32 (%struct.S2*, i32), i32 (%struct.S2*, i32)* ()* @_ZN2S23fooEi.resolver 71 // Templates: 72 // CHECK: @_ZN5templIiE3fooEi.ifunc = ifunc i32 (%struct.templ*, i32), i32 (%struct.templ*, i32)* ()* @_ZN5templIiE3fooEi.resolver 73 // CHECK: @_ZN5templIdE3fooEi.ifunc = ifunc i32 (%struct.templ.0*, i32), i32 (%struct.templ.0*, i32)* ()* @_ZN5templIdE3fooEi.resolver 74 75 // CHECK: define i32 @_Z3barv() 76 // CHECK: %s = alloca %struct.S, align 1 77 // CHECK: %s2 = alloca %struct.S, align 1 78 // CHECK: %C = alloca %struct.ConvertTo, align 1 79 // CHECK: call dereferenceable(1) %struct.S* @_ZN1SaSERKS_.ifunc(%struct.S* %s2 80 // CHECK: call void @_ZNK9ConvertTocv1SEv.ifunc(%struct.ConvertTo* %C) 81 // CHECK: call dereferenceable(1) %struct.S* @_ZN1SaSERKS_.ifunc(%struct.S* %s2 82 // CHECK: call i32 @_ZN1S3fooEi.ifunc(%struct.S* %s, i32 0) 83 84 // CHECK: define %struct.S* (%struct.S*, %struct.S*)* @_ZN1SaSERKS_.resolver() comdat 85 // CHECK: ret %struct.S* (%struct.S*, %struct.S*)* @_ZN1SaSERKS_.arch_ivybridge 86 // CHECK: ret %struct.S* (%struct.S*, %struct.S*)* @_ZN1SaSERKS_ 87 88 // CHECK: define void (%struct.ConvertTo*)* @_ZNK9ConvertTocv1SEv.resolver() comdat 89 // CHECK: ret void (%struct.ConvertTo*)* @_ZNK9ConvertTocv1SEv.arch_ivybridge 90 // CHECK: ret void (%struct.ConvertTo*)* @_ZNK9ConvertTocv1SEv 91 92 // CHECK: define i32 (%struct.S*, i32)* @_ZN1S3fooEi.resolver() comdat 93 // CHECK: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi.arch_sandybridge 94 // CHECK: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi.arch_ivybridge 95 // CHECK: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi.sse4.2 96 // CHECK: ret i32 (%struct.S*, i32)* @_ZN1S3fooEi 97 98 // CHECK: define i32 @_Z4bar2v() 99 // CHECK:call i32 @_ZN2S23fooEi.ifunc 100 // define i32 (%struct.S2*, i32)* @_ZN2S23fooEi.resolver() comdat 101 // CHECK: ret i32 (%struct.S2*, i32)* @_ZN2S23fooEi.arch_sandybridge 102 // CHECK: ret i32 (%struct.S2*, i32)* @_ZN2S23fooEi.arch_ivybridge 103 // CHECK: ret i32 (%struct.S2*, i32)* @_ZN2S23fooEi.sse4.2 104 // CHECK: ret i32 (%struct.S2*, i32)* @_ZN2S23fooEi 105 106 // CHECK: define i32 @_ZN2S23fooEi.sse4.2(%struct.S2* %this, i32) 107 // CHECK: define i32 @_ZN2S23fooEi.arch_ivybridge(%struct.S2* %this, i32) 108 // CHECK: define i32 @_ZN2S23fooEi(%struct.S2* %this, i32) 109 110 // CHECK: define i32 @_Z9templ_usev() 111 // CHECK: call i32 @_ZN5templIiE3fooEi.ifunc 112 // CHECK: call i32 @_ZN5templIdE3fooEi.ifunc 113 114 115 // CHECK: define i32 (%struct.templ*, i32)* @_ZN5templIiE3fooEi.resolver() comdat 116 // CHECK: ret i32 (%struct.templ*, i32)* @_ZN5templIiE3fooEi.arch_sandybridge 117 // CHECK: ret i32 (%struct.templ*, i32)* @_ZN5templIiE3fooEi.arch_ivybridge 118 // CHECK: ret i32 (%struct.templ*, i32)* @_ZN5templIiE3fooEi.sse4.2 119 // CHECK: ret i32 (%struct.templ*, i32)* @_ZN5templIiE3fooEi 120 // 121 // CHECK: define i32 (%struct.templ.0*, i32)* @_ZN5templIdE3fooEi.resolver() comdat 122 // CHECK: ret i32 (%struct.templ.0*, i32)* @_ZN5templIdE3fooEi.arch_sandybridge 123 // CHECK: ret i32 (%struct.templ.0*, i32)* @_ZN5templIdE3fooEi.arch_ivybridge 124 // CHECK: ret i32 (%struct.templ.0*, i32)* @_ZN5templIdE3fooEi.sse4.2 125 // CHECK: ret i32 (%struct.templ.0*, i32)* @_ZN5templIdE3fooEi 126 127 // CHECK: define linkonce_odr i32 @_ZN1S3fooEi.sse4.2(%struct.S* %this, i32) 128 // CHECK: ret i32 0 129 130 // CHECK: declare i32 @_ZN1S3fooEi.arch_sandybridge(%struct.S*, i32) 131 132 // CHECK: define linkonce_odr i32 @_ZN1S3fooEi.arch_ivybridge(%struct.S* %this, i32) 133 // CHECK: ret i32 1 134 135 // CHECK: define linkonce_odr i32 @_ZN1S3fooEi(%struct.S* %this, i32) 136 // CHECK: ret i32 2 137 138