xref: /llvm-project/clang/test/CodeGenCXX/attr-target-clones-aarch64.cpp (revision 474f5d2aefb44430b89ed72774a3c1d26a0adfb1)
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