1 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-globals all --include-generated-funcs --global-value-regex ".*" --version 5 2 // RUN: %clang_cc1 -std=c++11 -triple aarch64-linux-gnu -emit-llvm %s -o - | FileCheck %s 3 4 int __attribute__((target_clones("fp16", "default"))) foo_ovl(int) { return 1; } 5 int __attribute__((target_clones("fp16"))) foo_ovl(void) { return 2; } 6 7 int bar() { 8 return foo_ovl(1) + foo_ovl(); 9 } 10 11 template <typename T1, typename T2> struct MyClass { 12 int __attribute__((target_clones("frintts", "ssbs+sme-f64f64"))) foo_tml() { return 1; } 13 }; 14 15 template <typename T> struct MyClass<int, T> { 16 int __attribute__((target_clones("frintts", "ssbs+sme-f64f64"))) foo_tml() { return 2; } 17 }; 18 19 template <typename T> struct MyClass<float, T> { 20 int foo_tml() { return 3; } 21 }; 22 23 template <> struct MyClass<double, float> { 24 int __attribute__((target_clones("default"))) foo_tml() { return 4; } 25 }; 26 27 void run_foo_tml() { 28 MyClass<short, short> Mc1; 29 Mc1.foo_tml(); 30 MyClass<int, short> Mc2; 31 Mc2.foo_tml(); 32 MyClass<float, short> Mc3; 33 Mc3.foo_tml(); 34 MyClass<double, float> Mc4; 35 Mc4.foo_tml(); 36 } 37 38 39 40 41 //. 42 // CHECK: @__aarch64_cpu_features = external dso_local global { i64 } 43 // CHECK: @_Z7foo_ovli = weak_odr ifunc i32 (i32), ptr @_Z7foo_ovli.resolver 44 // CHECK: @_Z7foo_ovlv = weak_odr ifunc i32 (), ptr @_Z7foo_ovlv.resolver 45 // CHECK: @_ZN7MyClassIssE7foo_tmlEv = weak_odr ifunc i32 (ptr), ptr @_ZN7MyClassIssE7foo_tmlEv.resolver 46 // CHECK: @_ZN7MyClassIisE7foo_tmlEv = weak_odr ifunc i32 (ptr), ptr @_ZN7MyClassIisE7foo_tmlEv.resolver 47 //. 48 // CHECK-LABEL: define dso_local noundef i32 @_Z7foo_ovli._Mfp16( 49 // CHECK-SAME: i32 noundef [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] { 50 // CHECK-NEXT: [[ENTRY:.*:]] 51 // CHECK-NEXT: [[DOTADDR:%.*]] = alloca i32, align 4 52 // CHECK-NEXT: store i32 [[TMP0]], ptr [[DOTADDR]], align 4 53 // CHECK-NEXT: ret i32 1 54 // 55 // 56 // CHECK-LABEL: define weak_odr ptr @_Z7foo_ovli.resolver() comdat { 57 // CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] 58 // CHECK-NEXT: call void @__init_cpu_features_resolver() 59 // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 60 // CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 65792 61 // CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 65792 62 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] 63 // CHECK-NEXT: br i1 [[TMP3]], label %[[RESOLVER_RETURN:.*]], label %[[RESOLVER_ELSE:.*]] 64 // CHECK: [[RESOLVER_RETURN]]: 65 // CHECK-NEXT: ret ptr @_Z7foo_ovli._Mfp16 66 // CHECK: [[RESOLVER_ELSE]]: 67 // CHECK-NEXT: ret ptr @_Z7foo_ovli.default 68 // 69 // 70 // CHECK-LABEL: define dso_local noundef i32 @_Z7foo_ovlv._Mfp16( 71 // CHECK-SAME: ) #[[ATTR0]] { 72 // CHECK-NEXT: [[ENTRY:.*:]] 73 // CHECK-NEXT: ret i32 2 74 // 75 // 76 // CHECK-LABEL: define weak_odr ptr @_Z7foo_ovlv.resolver() comdat { 77 // CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] 78 // CHECK-NEXT: call void @__init_cpu_features_resolver() 79 // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 80 // CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 65792 81 // CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 65792 82 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] 83 // CHECK-NEXT: br i1 [[TMP3]], label %[[RESOLVER_RETURN:.*]], label %[[RESOLVER_ELSE:.*]] 84 // CHECK: [[RESOLVER_RETURN]]: 85 // CHECK-NEXT: ret ptr @_Z7foo_ovlv._Mfp16 86 // CHECK: [[RESOLVER_ELSE]]: 87 // CHECK-NEXT: ret ptr @_Z7foo_ovlv.default 88 // 89 // 90 // CHECK-LABEL: define dso_local noundef i32 @_Z3barv( 91 // CHECK-SAME: ) #[[ATTR1:[0-9]+]] { 92 // CHECK-NEXT: [[ENTRY:.*:]] 93 // CHECK-NEXT: [[CALL:%.*]] = call noundef i32 @_Z7foo_ovli(i32 noundef 1) 94 // CHECK-NEXT: [[CALL1:%.*]] = call noundef i32 @_Z7foo_ovlv() 95 // CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL]], [[CALL1]] 96 // CHECK-NEXT: ret i32 [[ADD]] 97 // 98 // 99 // CHECK-LABEL: define dso_local void @_Z11run_foo_tmlv( 100 // CHECK-SAME: ) #[[ATTR1]] { 101 // CHECK-NEXT: [[ENTRY:.*:]] 102 // CHECK-NEXT: [[MC1:%.*]] = alloca [[STRUCT_MYCLASS:%.*]], align 1 103 // CHECK-NEXT: [[MC2:%.*]] = alloca [[STRUCT_MYCLASS_0:%.*]], align 1 104 // CHECK-NEXT: [[MC3:%.*]] = alloca [[STRUCT_MYCLASS_1:%.*]], align 1 105 // CHECK-NEXT: [[MC4:%.*]] = alloca [[STRUCT_MYCLASS_2:%.*]], align 1 106 // CHECK-NEXT: [[CALL:%.*]] = call noundef i32 @_ZN7MyClassIssE7foo_tmlEv(ptr noundef nonnull align 1 dereferenceable(1) [[MC1]]) 107 // CHECK-NEXT: [[CALL1:%.*]] = call noundef i32 @_ZN7MyClassIisE7foo_tmlEv(ptr noundef nonnull align 1 dereferenceable(1) [[MC2]]) 108 // CHECK-NEXT: [[CALL2:%.*]] = call noundef i32 @_ZN7MyClassIfsE7foo_tmlEv(ptr noundef nonnull align 1 dereferenceable(1) [[MC3]]) 109 // CHECK-NEXT: [[CALL3:%.*]] = call noundef i32 @_ZN7MyClassIdfE7foo_tmlEv(ptr noundef nonnull align 1 dereferenceable(1) [[MC4]]) 110 // CHECK-NEXT: ret void 111 // 112 // 113 // CHECK-LABEL: define linkonce_odr noundef i32 @_ZN7MyClassIfsE7foo_tmlEv( 114 // CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR1]] comdat { 115 // CHECK-NEXT: [[ENTRY:.*:]] 116 // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 117 // CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 118 // CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 119 // CHECK-NEXT: ret i32 3 120 // 121 // 122 // CHECK-LABEL: define linkonce_odr noundef i32 @_ZN7MyClassIdfE7foo_tmlEv( 123 // CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR1]] comdat { 124 // CHECK-NEXT: [[ENTRY:.*:]] 125 // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 126 // CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 127 // CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 128 // CHECK-NEXT: ret i32 4 129 // 130 // 131 // CHECK-LABEL: define dso_local noundef i32 @_Z7foo_ovli.default( 132 // CHECK-SAME: i32 noundef [[TMP0:%.*]]) #[[ATTR2:[0-9]+]] { 133 // CHECK-NEXT: [[ENTRY:.*:]] 134 // CHECK-NEXT: [[DOTADDR:%.*]] = alloca i32, align 4 135 // CHECK-NEXT: store i32 [[TMP0]], ptr [[DOTADDR]], align 4 136 // CHECK-NEXT: ret i32 1 137 // 138 // 139 // CHECK-LABEL: define dso_local noundef i32 @_Z7foo_ovlv.default( 140 // CHECK-SAME: ) #[[ATTR2]] { 141 // CHECK-NEXT: [[ENTRY:.*:]] 142 // CHECK-NEXT: ret i32 2 143 // 144 // 145 // CHECK-LABEL: define linkonce_odr noundef i32 @_ZN7MyClassIssE7foo_tmlEv._Mfrintts( 146 // CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR3:[0-9]+]] comdat { 147 // CHECK-NEXT: [[ENTRY:.*:]] 148 // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 149 // CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 150 // CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 151 // CHECK-NEXT: ret i32 1 152 // 153 // 154 // CHECK-LABEL: define linkonce_odr noundef i32 @_ZN7MyClassIssE7foo_tmlEv._Msme-f64f64Mssbs( 155 // CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR4:[0-9]+]] comdat { 156 // CHECK-NEXT: [[ENTRY:.*:]] 157 // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 158 // CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 159 // CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 160 // CHECK-NEXT: ret i32 1 161 // 162 // 163 // CHECK-LABEL: define linkonce_odr noundef i32 @_ZN7MyClassIssE7foo_tmlEv.default( 164 // CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR2]] comdat { 165 // CHECK-NEXT: [[ENTRY:.*:]] 166 // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 167 // CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 168 // CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 169 // CHECK-NEXT: ret i32 1 170 // 171 // 172 // CHECK-LABEL: define weak_odr ptr @_ZN7MyClassIssE7foo_tmlEv.resolver() comdat { 173 // CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] 174 // CHECK-NEXT: call void @__init_cpu_features_resolver() 175 // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 176 // CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 36596145153180416 177 // CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 36596145153180416 178 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] 179 // CHECK-NEXT: br i1 [[TMP3]], label %[[RESOLVER_RETURN:.*]], label %[[RESOLVER_ELSE:.*]] 180 // CHECK: [[RESOLVER_RETURN]]: 181 // CHECK-NEXT: ret ptr @_ZN7MyClassIssE7foo_tmlEv._Msme-f64f64Mssbs 182 // CHECK: [[RESOLVER_ELSE]]: 183 // CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 184 // CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 16777472 185 // CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 16777472 186 // CHECK-NEXT: [[TMP7:%.*]] = and i1 true, [[TMP6]] 187 // CHECK-NEXT: br i1 [[TMP7]], label %[[RESOLVER_RETURN1:.*]], label %[[RESOLVER_ELSE2:.*]] 188 // CHECK: [[RESOLVER_RETURN1]]: 189 // CHECK-NEXT: ret ptr @_ZN7MyClassIssE7foo_tmlEv._Mfrintts 190 // CHECK: [[RESOLVER_ELSE2]]: 191 // CHECK-NEXT: ret ptr @_ZN7MyClassIssE7foo_tmlEv.default 192 // 193 // 194 // CHECK-LABEL: define linkonce_odr noundef i32 @_ZN7MyClassIisE7foo_tmlEv._Mfrintts( 195 // CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR3]] comdat { 196 // CHECK-NEXT: [[ENTRY:.*:]] 197 // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 198 // CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 199 // CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 200 // CHECK-NEXT: ret i32 2 201 // 202 // 203 // CHECK-LABEL: define linkonce_odr noundef i32 @_ZN7MyClassIisE7foo_tmlEv._Msme-f64f64Mssbs( 204 // CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR4]] comdat { 205 // CHECK-NEXT: [[ENTRY:.*:]] 206 // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 207 // CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 208 // CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 209 // CHECK-NEXT: ret i32 2 210 // 211 // 212 // CHECK-LABEL: define linkonce_odr noundef i32 @_ZN7MyClassIisE7foo_tmlEv.default( 213 // CHECK-SAME: ptr noundef nonnull align 1 dereferenceable(1) [[THIS:%.*]]) #[[ATTR2]] comdat { 214 // CHECK-NEXT: [[ENTRY:.*:]] 215 // CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 216 // CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 217 // CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 218 // CHECK-NEXT: ret i32 2 219 // 220 // 221 // CHECK-LABEL: define weak_odr ptr @_ZN7MyClassIisE7foo_tmlEv.resolver() comdat { 222 // CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] 223 // CHECK-NEXT: call void @__init_cpu_features_resolver() 224 // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 225 // CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 36596145153180416 226 // CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 36596145153180416 227 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] 228 // CHECK-NEXT: br i1 [[TMP3]], label %[[RESOLVER_RETURN:.*]], label %[[RESOLVER_ELSE:.*]] 229 // CHECK: [[RESOLVER_RETURN]]: 230 // CHECK-NEXT: ret ptr @_ZN7MyClassIisE7foo_tmlEv._Msme-f64f64Mssbs 231 // CHECK: [[RESOLVER_ELSE]]: 232 // CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 233 // CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 16777472 234 // CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 16777472 235 // CHECK-NEXT: [[TMP7:%.*]] = and i1 true, [[TMP6]] 236 // CHECK-NEXT: br i1 [[TMP7]], label %[[RESOLVER_RETURN1:.*]], label %[[RESOLVER_ELSE2:.*]] 237 // CHECK: [[RESOLVER_RETURN1]]: 238 // CHECK-NEXT: ret ptr @_ZN7MyClassIisE7foo_tmlEv._Mfrintts 239 // CHECK: [[RESOLVER_ELSE2]]: 240 // CHECK-NEXT: ret ptr @_ZN7MyClassIisE7foo_tmlEv.default 241 // 242 //. 243 // CHECK: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4} 244 // CHECK: [[META1:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"} 245 //. 246