1 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-globals --include-generated-funcs
2 // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +ls64 -target-feature +fullfp16 -S -emit-llvm -o - %s | FileCheck %s
3 // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature -fmv -S -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK-NOFMV
5 int __attribute__((target_version("rng+flagm+fp16fml"))) fmv(void) { return 1; }
6 int __attribute__((target_version("flagm2+sme-i16i64"))) fmv(void) { return 2; }
7 int __attribute__((target_version("lse+sha2"))) fmv(void) { return 3; }
8 int __attribute__((target_version("dotprod+ls64_accdata"))) fmv(void) { return 4; }
9 int __attribute__((target_version("fp16fml+memtag"))) fmv(void) { return 5; }
10 int __attribute__((target_version("fp+aes"))) fmv(void) { return 6; }
11 int __attribute__((target_version("crc+ls64_v"))) fmv(void) { return 7; }
12 int __attribute__((target_version("bti"))) fmv(void) { return 8; }
13 int __attribute__((target_version("sme2"))) fmv(void) { return 9; }
14 int __attribute__((target_version("default"))) fmv(void) { return 0; }
15 int __attribute__((target_version("ls64+simd"))) fmv_one(void) { return 1; }
16 int __attribute__((target_version("dpb"))) fmv_one(void) { return 2; }
17 int __attribute__((target_version("default"))) fmv_one(void) { return 0; }
18 int __attribute__((target_version("fp"))) fmv_two(void) { return 1; }
19 int __attribute__((target_version("simd"))) fmv_two(void) { return 2; }
20 int __attribute__((target_version("dgh"))) fmv_two(void) { return 3; }
21 int __attribute__((target_version("fp16+simd"))) fmv_two(void) { return 4; }
22 int __attribute__((target_version("default"))) fmv_two(void) { return 0; }
24 return fmv()+fmv_one()+fmv_two();
27 inline int __attribute__((target_version("sha1+pmull+f64mm"))) fmv_inline(void) { return 1; }
28 inline int __attribute__((target_version("fp16+fcma+sme+ fp16 "))) fmv_inline(void) { return 2; }
29 inline int __attribute__((target_version("sha3+i8mm+f32mm"))) fmv_inline(void) { return 12; }
30 inline int __attribute__((target_version("dit+sve-ebf16"))) fmv_inline(void) { return 8; }
31 inline int __attribute__((target_version("dpb+rcpc2 "))) fmv_inline(void) { return 6; }
32 inline int __attribute__((target_version(" dpb2 + jscvt"))) fmv_inline(void) { return 7; }
33 inline int __attribute__((target_version("rcpc+frintts"))) fmv_inline(void) { return 3; }
34 inline int __attribute__((target_version("sve+sve-bf16"))) fmv_inline(void) { return 4; }
35 inline int __attribute__((target_version("sve2-aes+sve2-sha3"))) fmv_inline(void) { return 5; }
36 inline int __attribute__((target_version("sve2+sve2-pmull128+sve2-bitperm"))) fmv_inline(void) { return 9; }
37 inline int __attribute__((target_version("sve2-sm4+memtag2"))) fmv_inline(void) { return 10; }
38 inline int __attribute__((target_version("memtag3+rcpc3"))) fmv_inline(void) { return 11; }
39 inline int __attribute__((target_version("default"))) fmv_inline(void) { return 3; }
41 __attribute__((target_version("ls64"))) int fmv_e(void);
42 int fmv_e(void) { return 20; }
44 static __attribute__((target_version("sb"))) inline int fmv_d(void);
45 static __attribute__((target_version("default"))) inline int fmv_d(void);
47 int __attribute__((target_version("default"))) fmv_default(void) { return 111; }
48 int fmv_default(void);
51 void __attribute__((target_version("ssbs"))) fmv_c(void){};
52 void __attribute__((target_version("default"))) fmv_c(void){};
61 static inline int __attribute__((target_version("sb"))) fmv_d(void) { return 0; }
62 static inline int __attribute__((target_version(" default "))) fmv_d(void) { return 1; }
64 static void func(void) {}
65 inline __attribute__((target_version("default"))) void recb(void) { func(); }
66 inline __attribute__((target_version("default"))) void reca(void) { recb(); }
67 void recur(void) { reca(); }
69 int __attribute__((target_version("default"))) main(void) {
74 typedef int (*Fptr
)();
83 // CHECK: @__aarch64_cpu_features = external dso_local global { i64 }
84 // CHECK: @fmv.ifunc = weak_odr ifunc i32 (), ptr @fmv.resolver
85 // CHECK: @fmv_one.ifunc = weak_odr ifunc i32 (), ptr @fmv_one.resolver
86 // CHECK: @fmv_two.ifunc = weak_odr ifunc i32 (), ptr @fmv_two.resolver
87 // CHECK: @fmv_inline.ifunc = weak_odr ifunc i32 (), ptr @fmv_inline.resolver
88 // CHECK: @fmv_e.ifunc = weak_odr ifunc i32 (), ptr @fmv_e.resolver
89 // CHECK: @fmv_d.ifunc = internal ifunc i32 (), ptr @fmv_d.resolver
90 // CHECK: @fmv_c.ifunc = weak_odr ifunc void (), ptr @fmv_c.resolver
92 // CHECK-LABEL: @fmv._MrngMflagmMfp16fml(
94 // CHECK-NEXT: ret i32 1
95 // CHECK-LABEL: @fmv._Mflagm2Msme-i16i64(
97 // CHECK-NEXT: ret i32 2
98 // CHECK-LABEL: @fmv._MlseMsha2(
100 // CHECK-NEXT: ret i32 3
101 // CHECK-LABEL: @fmv._MdotprodMls64_accdata(
102 // CHECK-NEXT: entry:
103 // CHECK-NEXT: ret i32 4
104 // CHECK-LABEL: @fmv._Mfp16fmlMmemtag(
105 // CHECK-NEXT: entry:
106 // CHECK-NEXT: ret i32 5
107 // CHECK-LABEL: @fmv._MfpMaes(
108 // CHECK-NEXT: entry:
109 // CHECK-NEXT: ret i32 6
110 // CHECK-LABEL: @fmv._McrcMls64_v(
111 // CHECK-NEXT: entry:
112 // CHECK-NEXT: ret i32 7
113 // CHECK-LABEL: @fmv._Mbti(
114 // CHECK-NEXT: entry:
115 // CHECK-NEXT: ret i32 8
116 // CHECK-LABEL: @fmv._Msme2(
117 // CHECK-NEXT: entry:
118 // CHECK-NEXT: ret i32 9
119 // CHECK-LABEL: @fmv(
120 // CHECK-NEXT: entry:
121 // CHECK-NEXT: ret i32 0
122 // CHECK-LABEL: @fmv_one._MsimdMls64(
123 // CHECK-NEXT: entry:
124 // CHECK-NEXT: ret i32 1
125 // CHECK-LABEL: @fmv_one._Mdpb(
126 // CHECK-NEXT: entry:
127 // CHECK-NEXT: ret i32 2
128 // CHECK-LABEL: @fmv_one(
129 // CHECK-NEXT: entry:
130 // CHECK-NEXT: ret i32 0
131 // CHECK-LABEL: @fmv_two._Mfp(
132 // CHECK-NEXT: entry:
133 // CHECK-NEXT: ret i32 1
134 // CHECK-LABEL: @fmv_two._Msimd(
135 // CHECK-NEXT: entry:
136 // CHECK-NEXT: ret i32 2
137 // CHECK-LABEL: @fmv_two._Mdgh(
138 // CHECK-NEXT: entry:
139 // CHECK-NEXT: ret i32 3
140 // CHECK-LABEL: @fmv_two._MsimdMfp16(
141 // CHECK-NEXT: entry:
142 // CHECK-NEXT: ret i32 4
143 // CHECK-LABEL: @fmv_two(
144 // CHECK-NEXT: entry:
145 // CHECK-NEXT: ret i32 0
146 // CHECK-LABEL: @foo(
147 // CHECK-NEXT: entry:
148 // CHECK-NEXT: [[CALL:%.*]] = call i32 @fmv.ifunc()
149 // CHECK-NEXT: [[CALL1:%.*]] = call i32 @fmv_one.ifunc()
150 // CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL]], [[CALL1]]
151 // CHECK-NEXT: [[CALL2:%.*]] = call i32 @fmv_two.ifunc()
152 // CHECK-NEXT: [[ADD3:%.*]] = add nsw i32 [[ADD]], [[CALL2]]
153 // CHECK-NEXT: ret i32 [[ADD3]]
154 // CHECK-LABEL: @fmv.resolver(
155 // CHECK-NEXT: resolver_entry:
156 // CHECK-NEXT: call void @__init_cpu_features_resolver()
157 // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
158 // CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 11
159 // CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 11
160 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]]
161 // CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]]
162 // CHECK: resolver_return:
163 // CHECK-NEXT: ret ptr @fmv._MrngMflagmMfp16fml
164 // CHECK: resolver_else:
165 // CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
166 // CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 72057594037927940
167 // CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 72057594037927940
168 // CHECK-NEXT: [[TMP7:%.*]] = and i1 true, [[TMP6]]
169 // CHECK-NEXT: br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]]
170 // CHECK: resolver_return1:
171 // CHECK-NEXT: ret ptr @fmv._Mflagm2Msme-i16i64
172 // CHECK: resolver_else2:
173 // CHECK-NEXT: [[TMP8:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
174 // CHECK-NEXT: [[TMP9:%.*]] = and i64 [[TMP8]], 16
175 // CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 16
176 // CHECK-NEXT: [[TMP11:%.*]] = and i1 true, [[TMP10]]
177 // CHECK-NEXT: br i1 [[TMP11]], label [[RESOLVER_RETURN3:%.*]], label [[RESOLVER_ELSE4:%.*]]
178 // CHECK: resolver_return3:
179 // CHECK-NEXT: ret ptr @fmv._MdotprodMls64_accdata
180 // CHECK: resolver_else4:
181 // CHECK-NEXT: [[TMP12:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
182 // CHECK-NEXT: [[TMP13:%.*]] = and i64 [[TMP12]], 1024
183 // CHECK-NEXT: [[TMP14:%.*]] = icmp eq i64 [[TMP13]], 1024
184 // CHECK-NEXT: [[TMP15:%.*]] = and i1 true, [[TMP14]]
185 // CHECK-NEXT: br i1 [[TMP15]], label [[RESOLVER_RETURN5:%.*]], label [[RESOLVER_ELSE6:%.*]]
186 // CHECK: resolver_return5:
187 // CHECK-NEXT: ret ptr @fmv._McrcMls64_v
188 // CHECK: resolver_else6:
189 // CHECK-NEXT: [[TMP16:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
190 // CHECK-NEXT: [[TMP17:%.*]] = and i64 [[TMP16]], 8796093022216
191 // CHECK-NEXT: [[TMP18:%.*]] = icmp eq i64 [[TMP17]], 8796093022216
192 // CHECK-NEXT: [[TMP19:%.*]] = and i1 true, [[TMP18]]
193 // CHECK-NEXT: br i1 [[TMP19]], label [[RESOLVER_RETURN7:%.*]], label [[RESOLVER_ELSE8:%.*]]
194 // CHECK: resolver_return7:
195 // CHECK-NEXT: ret ptr @fmv._Mfp16fmlMmemtag
196 // CHECK: resolver_else8:
197 // CHECK-NEXT: [[TMP20:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
198 // CHECK-NEXT: [[TMP21:%.*]] = and i64 [[TMP20]], 16384
199 // CHECK-NEXT: [[TMP22:%.*]] = icmp eq i64 [[TMP21]], 16384
200 // CHECK-NEXT: [[TMP23:%.*]] = and i1 true, [[TMP22]]
201 // CHECK-NEXT: br i1 [[TMP23]], label [[RESOLVER_RETURN9:%.*]], label [[RESOLVER_ELSE10:%.*]]
202 // CHECK: resolver_return9:
203 // CHECK-NEXT: ret ptr @fmv._MfpMaes
204 // CHECK: resolver_else10:
205 // CHECK-NEXT: [[TMP24:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
206 // CHECK-NEXT: [[TMP25:%.*]] = and i64 [[TMP24]], 4224
207 // CHECK-NEXT: [[TMP26:%.*]] = icmp eq i64 [[TMP25]], 4224
208 // CHECK-NEXT: [[TMP27:%.*]] = and i1 true, [[TMP26]]
209 // CHECK-NEXT: br i1 [[TMP27]], label [[RESOLVER_RETURN11:%.*]], label [[RESOLVER_ELSE12:%.*]]
210 // CHECK: resolver_return11:
211 // CHECK-NEXT: ret ptr @fmv._MlseMsha2
212 // CHECK: resolver_else12:
213 // CHECK-NEXT: [[TMP28:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
214 // CHECK-NEXT: [[TMP29:%.*]] = and i64 [[TMP28]], 144115188075855872
215 // CHECK-NEXT: [[TMP30:%.*]] = icmp eq i64 [[TMP29]], 144115188075855872
216 // CHECK-NEXT: [[TMP31:%.*]] = and i1 true, [[TMP30]]
217 // CHECK-NEXT: br i1 [[TMP31]], label [[RESOLVER_RETURN13:%.*]], label [[RESOLVER_ELSE14:%.*]]
218 // CHECK: resolver_return13:
219 // CHECK-NEXT: ret ptr @fmv._Msme2
220 // CHECK: resolver_else14:
221 // CHECK-NEXT: [[TMP32:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
222 // CHECK-NEXT: [[TMP33:%.*]] = and i64 [[TMP32]], 1125899906842624
223 // CHECK-NEXT: [[TMP34:%.*]] = icmp eq i64 [[TMP33]], 1125899906842624
224 // CHECK-NEXT: [[TMP35:%.*]] = and i1 true, [[TMP34]]
225 // CHECK-NEXT: br i1 [[TMP35]], label [[RESOLVER_RETURN15:%.*]], label [[RESOLVER_ELSE16:%.*]]
226 // CHECK: resolver_return15:
227 // CHECK-NEXT: ret ptr @fmv._Mbti
228 // CHECK: resolver_else16:
229 // CHECK-NEXT: ret ptr @fmv
230 // CHECK-LABEL: @fmv_one.resolver(
231 // CHECK-NEXT: resolver_entry:
232 // CHECK-NEXT: ret ptr @fmv_one._MsimdMls64
233 // CHECK-LABEL: @fmv_two.resolver(
234 // CHECK-NEXT: resolver_entry:
235 // CHECK-NEXT: ret ptr @fmv_two._MsimdMfp16
236 // CHECK-LABEL: @fmv_e(
237 // CHECK-NEXT: entry:
238 // CHECK-NEXT: ret i32 20
239 // CHECK-LABEL: @fmv_default(
240 // CHECK-NEXT: entry:
241 // CHECK-NEXT: ret i32 111
242 // CHECK-LABEL: @fmv_c._Mssbs(
243 // CHECK-NEXT: entry:
244 // CHECK-NEXT: ret void
245 // CHECK-LABEL: @fmv_c(
246 // CHECK-NEXT: entry:
247 // CHECK-NEXT: ret void
248 // CHECK-LABEL: @goo(
249 // CHECK-NEXT: entry:
250 // CHECK-NEXT: [[CALL:%.*]] = call i32 @fmv_inline.ifunc()
251 // CHECK-NEXT: [[CALL1:%.*]] = call i32 @fmv_e.ifunc()
252 // CHECK-NEXT: [[CALL2:%.*]] = call i32 @fmv_d.ifunc()
253 // CHECK-NEXT: call void @fmv_c.ifunc()
254 // CHECK-NEXT: [[CALL3:%.*]] = call i32 @fmv_default()
255 // CHECK-NEXT: ret i32 [[CALL3]]
256 // CHECK-LABEL: @fmv_inline.resolver(
257 // CHECK-NEXT: resolver_entry:
258 // CHECK-NEXT: call void @__init_cpu_features_resolver()
259 // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
260 // CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 4398048608256
261 // CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 4398048608256
262 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]]
263 // CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]]
264 // CHECK: resolver_return:
265 // CHECK-NEXT: ret ptr @fmv_inline._Mfp16Mfp16MfcmaMsme
266 // CHECK: resolver_else:
267 // CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
268 // CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 893353197568
269 // CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 893353197568
270 // CHECK-NEXT: [[TMP7:%.*]] = and i1 true, [[TMP6]]
271 // CHECK-NEXT: br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]]
272 // CHECK: resolver_return1:
273 // CHECK-NEXT: ret ptr @fmv_inline._Msve2Msve2-pmull128Msve2-bitperm
274 // CHECK: resolver_else2:
275 // CHECK-NEXT: [[TMP8:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
276 // CHECK-NEXT: [[TMP9:%.*]] = and i64 [[TMP8]], 34359773184
277 // CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 34359773184
278 // CHECK-NEXT: [[TMP11:%.*]] = and i1 true, [[TMP10]]
279 // CHECK-NEXT: br i1 [[TMP11]], label [[RESOLVER_RETURN3:%.*]], label [[RESOLVER_ELSE4:%.*]]
280 // CHECK: resolver_return3:
281 // CHECK-NEXT: ret ptr @fmv_inline._Msha1MpmullMf64mm
282 // CHECK: resolver_else4:
283 // CHECK-NEXT: [[TMP12:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
284 // CHECK-NEXT: [[TMP13:%.*]] = and i64 [[TMP12]], 17246986240
285 // CHECK-NEXT: [[TMP14:%.*]] = icmp eq i64 [[TMP13]], 17246986240
286 // CHECK-NEXT: [[TMP15:%.*]] = and i1 true, [[TMP14]]
287 // CHECK-NEXT: br i1 [[TMP15]], label [[RESOLVER_RETURN5:%.*]], label [[RESOLVER_ELSE6:%.*]]
288 // CHECK: resolver_return5:
289 // CHECK-NEXT: ret ptr @fmv_inline._Msha3Mi8mmMf32mm
290 // CHECK: resolver_else6:
291 // CHECK-NEXT: [[TMP16:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
292 // CHECK-NEXT: [[TMP17:%.*]] = and i64 [[TMP16]], 288265560523800576
293 // CHECK-NEXT: [[TMP18:%.*]] = icmp eq i64 [[TMP17]], 288265560523800576
294 // CHECK-NEXT: [[TMP19:%.*]] = and i1 true, [[TMP18]]
295 // CHECK-NEXT: br i1 [[TMP19]], label [[RESOLVER_RETURN7:%.*]], label [[RESOLVER_ELSE8:%.*]]
296 // CHECK: resolver_return7:
297 // CHECK-NEXT: ret ptr @fmv_inline._Mrcpc3Mmemtag3
298 // CHECK: resolver_else8:
299 // CHECK-NEXT: [[TMP20:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
300 // CHECK-NEXT: [[TMP21:%.*]] = and i64 [[TMP20]], 19791209299968
301 // CHECK-NEXT: [[TMP22:%.*]] = icmp eq i64 [[TMP21]], 19791209299968
302 // CHECK-NEXT: [[TMP23:%.*]] = and i1 true, [[TMP22]]
303 // CHECK-NEXT: br i1 [[TMP23]], label [[RESOLVER_RETURN9:%.*]], label [[RESOLVER_ELSE10:%.*]]
304 // CHECK: resolver_return9:
305 // CHECK-NEXT: ret ptr @fmv_inline._Msve2-sm4Mmemtag2
306 // CHECK: resolver_else10:
307 // CHECK-NEXT: [[TMP24:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
308 // CHECK-NEXT: [[TMP25:%.*]] = and i64 [[TMP24]], 1236950581248
309 // CHECK-NEXT: [[TMP26:%.*]] = icmp eq i64 [[TMP25]], 1236950581248
310 // CHECK-NEXT: [[TMP27:%.*]] = and i1 true, [[TMP26]]
311 // CHECK-NEXT: br i1 [[TMP27]], label [[RESOLVER_RETURN11:%.*]], label [[RESOLVER_ELSE12:%.*]]
312 // CHECK: resolver_return11:
313 // CHECK-NEXT: ret ptr @fmv_inline._Msve2-aesMsve2-sha3
314 // CHECK: resolver_else12:
315 // CHECK-NEXT: [[TMP28:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
316 // CHECK-NEXT: [[TMP29:%.*]] = and i64 [[TMP28]], 4295098368
317 // CHECK-NEXT: [[TMP30:%.*]] = icmp eq i64 [[TMP29]], 4295098368
318 // CHECK-NEXT: [[TMP31:%.*]] = and i1 true, [[TMP30]]
319 // CHECK-NEXT: br i1 [[TMP31]], label [[RESOLVER_RETURN13:%.*]], label [[RESOLVER_ELSE14:%.*]]
320 // CHECK: resolver_return13:
321 // CHECK-NEXT: ret ptr @fmv_inline._MditMsve-ebf16
322 // CHECK: resolver_else14:
323 // CHECK-NEXT: [[TMP32:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
324 // CHECK-NEXT: [[TMP33:%.*]] = and i64 [[TMP32]], 3221225472
325 // CHECK-NEXT: [[TMP34:%.*]] = icmp eq i64 [[TMP33]], 3221225472
326 // CHECK-NEXT: [[TMP35:%.*]] = and i1 true, [[TMP34]]
327 // CHECK-NEXT: br i1 [[TMP35]], label [[RESOLVER_RETURN15:%.*]], label [[RESOLVER_ELSE16:%.*]]
328 // CHECK: resolver_return15:
329 // CHECK-NEXT: ret ptr @fmv_inline._MsveMsve-bf16
330 // CHECK: resolver_else16:
331 // CHECK-NEXT: [[TMP36:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
332 // CHECK-NEXT: [[TMP37:%.*]] = and i64 [[TMP36]], 20971520
333 // CHECK-NEXT: [[TMP38:%.*]] = icmp eq i64 [[TMP37]], 20971520
334 // CHECK-NEXT: [[TMP39:%.*]] = and i1 true, [[TMP38]]
335 // CHECK-NEXT: br i1 [[TMP39]], label [[RESOLVER_RETURN17:%.*]], label [[RESOLVER_ELSE18:%.*]]
336 // CHECK: resolver_return17:
337 // CHECK-NEXT: ret ptr @fmv_inline._MrcpcMfrintts
338 // CHECK: resolver_else18:
339 // CHECK-NEXT: [[TMP40:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
340 // CHECK-NEXT: [[TMP41:%.*]] = and i64 [[TMP40]], 8650752
341 // CHECK-NEXT: [[TMP42:%.*]] = icmp eq i64 [[TMP41]], 8650752
342 // CHECK-NEXT: [[TMP43:%.*]] = and i1 true, [[TMP42]]
343 // CHECK-NEXT: br i1 [[TMP43]], label [[RESOLVER_RETURN19:%.*]], label [[RESOLVER_ELSE20:%.*]]
344 // CHECK: resolver_return19:
345 // CHECK-NEXT: ret ptr @fmv_inline._MdpbMrcpc2
346 // CHECK: resolver_else20:
347 // CHECK-NEXT: [[TMP44:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
348 // CHECK-NEXT: [[TMP45:%.*]] = and i64 [[TMP44]], 1572864
349 // CHECK-NEXT: [[TMP46:%.*]] = icmp eq i64 [[TMP45]], 1572864
350 // CHECK-NEXT: [[TMP47:%.*]] = and i1 true, [[TMP46]]
351 // CHECK-NEXT: br i1 [[TMP47]], label [[RESOLVER_RETURN21:%.*]], label [[RESOLVER_ELSE22:%.*]]
352 // CHECK: resolver_return21:
353 // CHECK-NEXT: ret ptr @fmv_inline._Mdpb2Mjscvt
354 // CHECK: resolver_else22:
355 // CHECK-NEXT: ret ptr @fmv_inline
356 // CHECK-LABEL: @fmv_e.resolver(
357 // CHECK-NEXT: resolver_entry:
358 // CHECK-NEXT: ret ptr @fmv_e._Mls64
359 // CHECK-LABEL: @fmv_d.resolver(
360 // CHECK-NEXT: resolver_entry:
361 // CHECK-NEXT: call void @__init_cpu_features_resolver()
362 // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
363 // CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 70368744177664
364 // CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 70368744177664
365 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]]
366 // CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]]
367 // CHECK: resolver_return:
368 // CHECK-NEXT: ret ptr @fmv_d._Msb
369 // CHECK: resolver_else:
370 // CHECK-NEXT: ret ptr @fmv_d
371 // CHECK-LABEL: @fmv_c.resolver(
372 // CHECK-NEXT: resolver_entry:
373 // CHECK-NEXT: call void @__init_cpu_features_resolver()
374 // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
375 // CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 281474976710656
376 // CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 281474976710656
377 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]]
378 // CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]]
379 // CHECK: resolver_return:
380 // CHECK-NEXT: ret ptr @fmv_c._Mssbs
381 // CHECK: resolver_else:
382 // CHECK-NEXT: ret ptr @fmv_c
383 // CHECK-LABEL: @recur(
384 // CHECK-NEXT: entry:
385 // CHECK-NEXT: call void @reca()
386 // CHECK-NEXT: ret void
387 // CHECK-LABEL: @main(
388 // CHECK-NEXT: entry:
389 // CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
390 // CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4
391 // CHECK-NEXT: call void @recur()
392 // CHECK-NEXT: [[CALL:%.*]] = call i32 @goo()
393 // CHECK-NEXT: ret i32 [[CALL]]
394 // CHECK-LABEL: @hoo(
395 // CHECK-NEXT: entry:
396 // CHECK-NEXT: [[FP1:%.*]] = alloca ptr, align 8
397 // CHECK-NEXT: [[FP2:%.*]] = alloca ptr, align 8
398 // CHECK-NEXT: call void @f(ptr noundef @fmv.ifunc)
399 // CHECK-NEXT: store ptr @fmv.ifunc, ptr [[FP1]], align 8
400 // CHECK-NEXT: store ptr @fmv.ifunc, ptr [[FP2]], align 8
401 // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[FP1]], align 8
402 // CHECK-NEXT: [[CALL:%.*]] = call i32 [[TMP0]]()
403 // CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[FP2]], align 8
404 // CHECK-NEXT: [[CALL1:%.*]] = call i32 [[TMP1]]()
405 // CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL]], [[CALL1]]
406 // CHECK-NEXT: ret i32 [[ADD]]
407 // CHECK-LABEL: @fmv_inline._Msha1MpmullMf64mm(
408 // CHECK-NEXT: entry:
409 // CHECK-NEXT: ret i32 1
410 // CHECK-LABEL: @fmv_inline._Mfp16Mfp16MfcmaMsme(
411 // CHECK-NEXT: entry:
412 // CHECK-NEXT: ret i32 2
413 // CHECK-LABEL: @fmv_inline._Msha3Mi8mmMf32mm(
414 // CHECK-NEXT: entry:
415 // CHECK-NEXT: ret i32 12
416 // CHECK-LABEL: @fmv_inline._MditMsve-ebf16(
417 // CHECK-NEXT: entry:
418 // CHECK-NEXT: ret i32 8
419 // CHECK-LABEL: @fmv_inline._MdpbMrcpc2(
420 // CHECK-NEXT: entry:
421 // CHECK-NEXT: ret i32 6
422 // CHECK-LABEL: @fmv_inline._Mdpb2Mjscvt(
423 // CHECK-NEXT: entry:
424 // CHECK-NEXT: ret i32 7
425 // CHECK-LABEL: @fmv_inline._MrcpcMfrintts(
426 // CHECK-NEXT: entry:
427 // CHECK-NEXT: ret i32 3
428 // CHECK-LABEL: @fmv_inline._MsveMsve-bf16(
429 // CHECK-NEXT: entry:
430 // CHECK-NEXT: ret i32 4
431 // CHECK-LABEL: @fmv_inline._Msve2-aesMsve2-sha3(
432 // CHECK-NEXT: entry:
433 // CHECK-NEXT: ret i32 5
434 // CHECK-LABEL: @fmv_inline._Msve2Msve2-pmull128Msve2-bitperm(
435 // CHECK-NEXT: entry:
436 // CHECK-NEXT: ret i32 9
437 // CHECK-LABEL: @fmv_inline._Msve2-sm4Mmemtag2(
438 // CHECK-NEXT: entry:
439 // CHECK-NEXT: ret i32 10
440 // CHECK-LABEL: @fmv_inline._Mrcpc3Mmemtag3(
441 // CHECK-NEXT: entry:
442 // CHECK-NEXT: ret i32 11
443 // CHECK-LABEL: @fmv_inline(
444 // CHECK-NEXT: entry:
445 // CHECK-NEXT: ret i32 3
446 // CHECK-LABEL: @fmv_d._Msb(
447 // CHECK-NEXT: entry:
448 // CHECK-NEXT: ret i32 0
449 // CHECK-LABEL: define internal i32 @fmv_d(
450 // CHECK-NEXT: entry:
451 // CHECK-NEXT: ret i32 1
452 // CHECK-NOFMV-LABEL: @fmv(
453 // CHECK-NOFMV-NEXT: entry:
454 // CHECK-NOFMV-NEXT: ret i32 0
455 // CHECK-NOFMV-LABEL: @fmv_one(
456 // CHECK-NOFMV-NEXT: entry:
457 // CHECK-NOFMV-NEXT: ret i32 0
458 // CHECK-NOFMV-LABEL: @fmv_two(
459 // CHECK-NOFMV-NEXT: entry:
460 // CHECK-NOFMV-NEXT: ret i32 0
461 // CHECK-NOFMV-LABEL: @foo(
462 // CHECK-NOFMV-NEXT: entry:
463 // CHECK-NOFMV-NEXT: [[CALL:%.*]] = call i32 @fmv()
464 // CHECK-NOFMV-NEXT: [[CALL1:%.*]] = call i32 @fmv_one()
465 // CHECK-NOFMV-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL]], [[CALL1]]
466 // CHECK-NOFMV-NEXT: [[CALL2:%.*]] = call i32 @fmv_two()
467 // CHECK-NOFMV-NEXT: [[ADD3:%.*]] = add nsw i32 [[ADD]], [[CALL2]]
468 // CHECK-NOFMV-NEXT: ret i32 [[ADD3]]
469 // CHECK-NOFMV-LABEL: @fmv_e(
470 // CHECK-NOFMV-NEXT: entry:
471 // CHECK-NOFMV-NEXT: ret i32 20
472 // CHECK-NOFMV-LABEL: @fmv_default(
473 // CHECK-NOFMV-NEXT: entry:
474 // CHECK-NOFMV-NEXT: ret i32 111
475 // CHECK-NOFMV-LABEL: @fmv_c(
476 // CHECK-NOFMV-NEXT: entry:
477 // CHECK-NOFMV-NEXT: ret void
478 // CHECK-NOFMV-LABEL: @goo(
479 // CHECK-NOFMV-NEXT: entry:
480 // CHECK-NOFMV-NEXT: [[CALL:%.*]] = call i32 @fmv_inline()
481 // CHECK-NOFMV-NEXT: [[CALL1:%.*]] = call i32 @fmv_e()
482 // CHECK-NOFMV-NEXT: [[CALL2:%.*]] = call i32 @fmv_d()
483 // CHECK-NOFMV-NEXT: call void @fmv_c()
484 // CHECK-NOFMV-NEXT: [[CALL3:%.*]] = call i32 @fmv_default()
485 // CHECK-NOFMV-NEXT: ret i32 [[CALL3]]
486 // CHECK-NOFMV-LABEL: define internal i32 @fmv_d(
487 // CHECK-NOFMV-NEXT: entry:
488 // CHECK-NOFMV-NEXT: ret i32 1
489 // CHECK-NOFMV-LABEL: @recur(
490 // CHECK-NOFMV-NEXT: entry:
491 // CHECK-NOFMV-NEXT: call void @reca()
492 // CHECK-NOFMV-NEXT: ret void
493 // CHECK-NOFMV-LABEL: @main(
494 // CHECK-NOFMV-NEXT: entry:
495 // CHECK-NOFMV-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
496 // CHECK-NOFMV-NEXT: store i32 0, ptr [[RETVAL]], align 4
497 // CHECK-NOFMV-NEXT: call void @recur()
498 // CHECK-NOFMV-NEXT: [[CALL:%.*]] = call i32 @goo()
499 // CHECK-NOFMV-NEXT: ret i32 [[CALL]]
500 // CHECK-NOFMV-LABEL: @hoo(
501 // CHECK-NOFMV-NEXT: entry:
502 // CHECK-NOFMV-NEXT: [[FP1:%.*]] = alloca ptr, align 8
503 // CHECK-NOFMV-NEXT: [[FP2:%.*]] = alloca ptr, align 8
504 // CHECK-NOFMV-NEXT: call void @f(ptr noundef @fmv)
505 // CHECK-NOFMV-NEXT: store ptr @fmv, ptr [[FP1]], align 8
506 // CHECK-NOFMV-NEXT: store ptr @fmv, ptr [[FP2]], align 8
507 // CHECK-NOFMV-NEXT: [[TMP0:%.*]] = load ptr, ptr [[FP1]], align 8
508 // CHECK-NOFMV-NEXT: [[CALL:%.*]] = call i32 [[TMP0]]()
509 // CHECK-NOFMV-NEXT: [[TMP1:%.*]] = load ptr, ptr [[FP2]], align 8
510 // CHECK-NOFMV-NEXT: [[CALL1:%.*]] = call i32 [[TMP1]]()
511 // CHECK-NOFMV-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL]], [[CALL1]]
512 // CHECK-NOFMV-NEXT: ret i32 [[ADD]]
514 // CHECK: attributes #0 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+flagm,+fp-armv8,+fp16fml,+fullfp16,+ls64,+neon,+rand" }
515 // CHECK: attributes #1 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+altnzcv,+bf16,+flagm,+fullfp16,+ls64,+sme,+sme-i16i64" }
516 // CHECK: attributes #2 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+ls64,+lse,+neon,+sha2" }
517 // CHECK: attributes #3 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+dotprod,+fp-armv8,+fullfp16,+ls64,+neon" }
518 // CHECK: attributes #4 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fp16fml,+fullfp16,+ls64,+neon" }
519 // CHECK: attributes #5 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+ls64,+neon" }
520 // CHECK: attributes #6 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+crc,+fullfp16,+ls64" }
521 // CHECK: attributes #7 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bti,+fullfp16,+ls64" }
522 // CHECK: attributes #8 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+fullfp16,+ls64,+sme,+sme2" }
523 // CHECK: attributes #9 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fullfp16,+ls64" }
524 // CHECK: attributes #10 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ccpp,+fullfp16,+ls64" }
525 // CHECK: attributes #11 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fullfp16,+ls64" }
526 // CHECK: attributes #12 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+aes,+f64mm,+fp-armv8,+fullfp16,+ls64,+neon,+sve" }
527 // CHECK: attributes #13 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+complxnum,+fp-armv8,+fullfp16,+ls64,+neon,+sme" }
528 // CHECK: attributes #14 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+f32mm,+fp-armv8,+fullfp16,+i8mm,+ls64,+neon,+sha2,+sha3,+sve" }
529 // CHECK: attributes #15 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+dit,+fp-armv8,+fullfp16,+ls64,+neon,+sve" }
530 // CHECK: attributes #16 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ccpp,+fullfp16,+ls64,+rcpc" }
531 // CHECK: attributes #17 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ccdp,+ccpp,+fp-armv8,+fullfp16,+jsconv,+ls64,+neon" }
532 // CHECK: attributes #18 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fptoint,+fullfp16,+ls64,+rcpc" }
533 // CHECK: attributes #19 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+fp-armv8,+fullfp16,+ls64,+neon,+sve" }
534 // CHECK: attributes #20 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+ls64,+neon,+sve,+sve2,+sve2-aes,+sve2-sha3" }
535 // CHECK: attributes #21 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+ls64,+neon,+sve,+sve2,+sve2-aes,+sve2-bitperm" }
536 // CHECK: attributes #22 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+ls64,+mte,+neon,+sve,+sve2,+sve2-sm4" }
537 // CHECK: attributes #23 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fullfp16,+ls64,+mte,+rcpc,+rcpc3" }
538 // CHECK: attributes #24 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fullfp16,+ls64,+sb" }
540 // CHECK-NOFMV: attributes #0 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="-fmv" }
541 // CHECK-NOFMV: attributes #1 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="-fmv" }