xref: /llvm-project/llvm/test/Transforms/GlobalOpt/resolve-fmv-ifunc.ll (revision 1b1270f30bbdb2c7a310009d0512e167b09bac48)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --filter "call i32 @(test_single_bb_resolver|test_multi_bb_resolver|test_caller_feats_not_implied|test_non_fmv_caller|test_priority|test_alternative_names)" --version 4
2
3; REQUIRES: aarch64-registered-target
4
5; RUN: opt --passes=globalopt -o - -S < %s | FileCheck %s
6
7target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
8target triple = "aarch64-unknown-linux-gnu"
9
10$test_single_bb_resolver.resolver = comdat any
11$test_multi_bb_resolver.resolver = comdat any
12$test_caller_feats_not_implied.resolver = comdat any
13$test_non_fmv_caller.resolver = comdat any
14$test_priority.resolver = comdat any
15$test_alternative_names.resolver = comdat any
16
17@__aarch64_cpu_features = external local_unnamed_addr global { i64 }
18
19@test_single_bb_resolver = weak_odr ifunc i32 (), ptr @test_single_bb_resolver.resolver
20@test_multi_bb_resolver = weak_odr ifunc i32 (), ptr @test_multi_bb_resolver.resolver
21@test_caller_feats_not_implied = weak_odr ifunc i32 (), ptr @test_caller_feats_not_implied.resolver
22@test_non_fmv_caller = weak_odr ifunc i32 (), ptr @test_non_fmv_caller.resolver
23@test_priority = weak_odr ifunc i32 (), ptr @test_priority.resolver
24@test_alternative_names = weak_odr ifunc i32 (), ptr @test_alternative_names.resolver
25
26declare void @__init_cpu_features_resolver() local_unnamed_addr
27
28declare i32 @test_single_bb_resolver.default() #0
29declare i32 @test_single_bb_resolver._Msve() #1
30declare i32 @test_single_bb_resolver._Msve2() #2
31
32define weak_odr ptr @test_single_bb_resolver.resolver() comdat {
33; CHECK-LABEL: define weak_odr ptr @test_single_bb_resolver.resolver() comdat {
34resolver_entry:
35  tail call void @__init_cpu_features_resolver()
36  %0 = load i64, ptr @__aarch64_cpu_features, align 8
37  %1 = and i64 %0, 68719476736
38  %.not = icmp eq i64 %1, 0
39  %2 = and i64 %0, 1073741824
40  %.not3 = icmp eq i64 %2, 0
41  %test_single_bb_resolver._Msve.test_single_bb_resolver.default = select i1 %.not3, ptr @test_single_bb_resolver.default, ptr @test_single_bb_resolver._Msve
42  %common.ret.op = select i1 %.not, ptr %test_single_bb_resolver._Msve.test_single_bb_resolver.default, ptr @test_single_bb_resolver._Msve2
43  ret ptr %common.ret.op
44}
45
46define i32 @caller1._Msve() #1 {
47; CHECK-LABEL: define i32 @caller1._Msve(
48; CHECK-SAME: ) local_unnamed_addr #[[ATTR1:[0-9]+]] {
49; CHECK:    [[CALL:%.*]] = tail call i32 @test_single_bb_resolver._Msve()
50;
51entry:
52  %call = tail call i32 @test_single_bb_resolver()
53  ret i32 %call
54}
55
56define i32 @caller1._Msve2() #2 {
57; CHECK-LABEL: define i32 @caller1._Msve2(
58; CHECK-SAME: ) local_unnamed_addr #[[ATTR2:[0-9]+]] {
59; CHECK:    [[CALL:%.*]] = tail call i32 @test_single_bb_resolver._Msve2()
60;
61entry:
62  %call = tail call i32 @test_single_bb_resolver()
63  ret i32 %call
64}
65
66define i32 @caller1.default() #0 {
67; CHECK-LABEL: define i32 @caller1.default(
68; CHECK-SAME: ) local_unnamed_addr #[[ATTR0:[0-9]+]] {
69; CHECK:    [[CALL:%.*]] = tail call i32 @test_single_bb_resolver.default()
70;
71entry:
72  %call = tail call i32 @test_single_bb_resolver()
73  ret i32 %call
74}
75
76declare i32 @test_multi_bb_resolver._Mmops() #3
77declare i32 @test_multi_bb_resolver._Msve2() #2
78declare i32 @test_multi_bb_resolver._Msve() #1
79declare i32 @test_multi_bb_resolver.default() #0
80
81define weak_odr ptr @test_multi_bb_resolver.resolver() comdat {
82; CHECK-LABEL: define weak_odr ptr @test_multi_bb_resolver.resolver() comdat {
83resolver_entry:
84  tail call void @__init_cpu_features_resolver()
85  %0 = load i64, ptr @__aarch64_cpu_features, align 8
86  %1 = and i64 %0, 576460752303423488
87  %.not = icmp eq i64 %1, 0
88  br i1 %.not, label %resolver_else, label %common.ret
89
90common.ret:                                       ; preds = %resolver_else2, %resolver_else, %resolver_entry
91  %common.ret.op = phi ptr [ @test_multi_bb_resolver._Mmops, %resolver_entry ], [ @test_multi_bb_resolver._Msve2, %resolver_else ], [ %test_multi_bb_resolver._Msve.test_multi_bb_resolver.default, %resolver_else2 ]
92  ret ptr %common.ret.op
93
94resolver_else:                                    ; preds = %resolver_entry
95  %2 = and i64 %0, 68719476736
96  %.not5 = icmp eq i64 %2, 0
97  br i1 %.not5, label %resolver_else2, label %common.ret
98
99resolver_else2:                                   ; preds = %resolver_else
100  %3 = and i64 %0, 1073741824
101  %.not6 = icmp eq i64 %3, 0
102  %test_multi_bb_resolver._Msve.test_multi_bb_resolver.default = select i1 %.not6, ptr @test_multi_bb_resolver.default, ptr @test_multi_bb_resolver._Msve
103  br label %common.ret
104}
105
106define i32 @caller2._MmopsMsve2() #4 {
107; CHECK-LABEL: define i32 @caller2._MmopsMsve2(
108; CHECK-SAME: ) local_unnamed_addr #[[ATTR4:[0-9]+]] {
109; CHECK:    [[CALL:%.*]] = tail call i32 @test_multi_bb_resolver._Mmops()
110;
111entry:
112  %call = tail call i32 @test_multi_bb_resolver()
113  ret i32 %call
114}
115
116define i32 @caller2._Mmops() #3 {
117; CHECK-LABEL: define i32 @caller2._Mmops(
118; CHECK-SAME: ) local_unnamed_addr #[[ATTR3:[0-9]+]] {
119; CHECK:    [[CALL:%.*]] = tail call i32 @test_multi_bb_resolver._Mmops()
120;
121entry:
122  %call = tail call i32 @test_multi_bb_resolver()
123  ret i32 %call
124}
125
126define i32 @caller2._Msve() #1 {
127; CHECK-LABEL: define i32 @caller2._Msve(
128; CHECK-SAME: ) local_unnamed_addr #[[ATTR1]] {
129; CHECK:    [[CALL:%.*]] = tail call i32 @test_multi_bb_resolver()
130;
131entry:
132  %call = tail call i32 @test_multi_bb_resolver()
133  ret i32 %call
134}
135
136define i32 @caller2.default() #0 {
137; CHECK-LABEL: define i32 @caller2.default(
138; CHECK-SAME: ) local_unnamed_addr #[[ATTR0]] {
139; CHECK:    [[CALL:%.*]] = tail call i32 @test_multi_bb_resolver.default()
140;
141entry:
142  %call = tail call i32 @test_multi_bb_resolver()
143  ret i32 %call
144}
145
146declare i32 @test_caller_feats_not_implied._Mmops() #3
147declare i32 @test_caller_feats_not_implied._Msme() #5
148declare i32 @test_caller_feats_not_implied._Msve() #1
149declare i32 @test_caller_feats_not_implied.default() #0
150
151define weak_odr ptr @test_caller_feats_not_implied.resolver() comdat {
152; CHECK-LABEL: define weak_odr ptr @test_caller_feats_not_implied.resolver() comdat {
153resolver_entry:
154  tail call void @__init_cpu_features_resolver()
155  %0 = load i64, ptr @__aarch64_cpu_features, align 8
156  %1 = and i64 %0, 576460752303423488
157  %.not = icmp eq i64 %1, 0
158  br i1 %.not, label %resolver_else, label %common.ret
159
160common.ret:                                       ; preds = %resolver_else2, %resolver_else, %resolver_entry
161  %common.ret.op = phi ptr [ @test_caller_feats_not_implied._Mmops, %resolver_entry ], [ @test_caller_feats_not_implied._Msme, %resolver_else ], [ %test_caller_feats_not_implied._Msve.test_caller_feats_not_implied.default, %resolver_else2 ]
162  ret ptr %common.ret.op
163
164resolver_else:                                    ; preds = %resolver_entry
165  %2 = and i64 %0, 4398046511104
166  %.not5 = icmp eq i64 %2, 0
167  br i1 %.not5, label %resolver_else2, label %common.ret
168
169resolver_else2:                                   ; preds = %resolver_else
170  %3 = and i64 %0, 1073741824
171  %.not6 = icmp eq i64 %3, 0
172  %test_caller_feats_not_implied._Msve.test_caller_feats_not_implied.default = select i1 %.not6, ptr @test_caller_feats_not_implied.default, ptr @test_caller_feats_not_implied._Msve
173  br label %common.ret
174}
175
176define i32 @caller3._Mmops() #3 {
177; CHECK-LABEL: define i32 @caller3._Mmops(
178; CHECK-SAME: ) local_unnamed_addr #[[ATTR3]] {
179; CHECK:    [[CALL:%.*]] = tail call i32 @test_caller_feats_not_implied._Mmops()
180;
181entry:
182  %call = tail call i32 @test_caller_feats_not_implied()
183  ret i32 %call
184}
185
186define i32 @caller3._Msve() #1 {
187; CHECK-LABEL: define i32 @caller3._Msve(
188; CHECK-SAME: ) local_unnamed_addr #[[ATTR1]] {
189; CHECK:    [[CALL:%.*]] = tail call i32 @test_caller_feats_not_implied()
190;
191entry:
192  %call = tail call i32 @test_caller_feats_not_implied()
193  ret i32 %call
194}
195
196define i32 @caller3.default() #0 {
197; CHECK-LABEL: define i32 @caller3.default(
198; CHECK-SAME: ) local_unnamed_addr #[[ATTR0]] {
199; CHECK:    [[CALL:%.*]] = tail call i32 @test_caller_feats_not_implied()
200;
201entry:
202  %call = tail call i32 @test_caller_feats_not_implied()
203  ret i32 %call
204}
205
206declare i32 @test_non_fmv_caller._Maes() #6
207declare i32 @test_non_fmv_caller._Msm4() #7
208declare i32 @test_non_fmv_caller.default() #0
209
210define weak_odr ptr @test_non_fmv_caller.resolver() comdat {
211; CHECK-LABEL: define weak_odr ptr @test_non_fmv_caller.resolver() comdat {
212resolver_entry:
213  tail call void @__init_cpu_features_resolver()
214  %0 = load i64, ptr @__aarch64_cpu_features, align 8
215  %1 = and i64 %0, 32768
216  %.not = icmp eq i64 %1, 0
217  %test_non_fmv_caller._Maes.test_non_fmv_caller.default = select i1 %.not, ptr @test_non_fmv_caller.default, ptr @test_non_fmv_caller._Maes
218  ret ptr %test_non_fmv_caller._Maes.test_non_fmv_caller.default
219}
220
221define i32 @caller4() #8 {
222; CHECK-LABEL: define i32 @caller4(
223; CHECK-SAME: ) local_unnamed_addr #[[ATTR7:[0-9]+]] {
224; CHECK:    [[CALL:%.*]] = tail call i32 @test_non_fmv_caller._Maes()
225;
226entry:
227  %call = tail call i32 @test_non_fmv_caller()
228  ret i32 %call
229}
230
231define i32 @caller5() #9 {
232; CHECK-LABEL: define i32 @caller5(
233; CHECK-SAME: ) local_unnamed_addr #[[ATTR8:[0-9]+]] {
234; CHECK:    [[CALL:%.*]] = tail call i32 @test_non_fmv_caller()
235;
236entry:
237  %call = tail call i32 @test_non_fmv_caller()
238  ret i32 %call
239}
240
241declare i32 @test_priority._Msve2-sha3() #10
242declare i32 @test_priority._Mls64Mssbs() #11
243declare i32 @test_priority._MflagmMlseMrng() #12
244declare i32 @test_priority.default() #0
245
246define weak_odr ptr @test_priority.resolver() comdat {
247; CHECK-LABEL: define weak_odr ptr @test_priority.resolver() comdat {
248resolver_entry:
249  tail call void @__init_cpu_features_resolver()
250  %0 = load i64, ptr @__aarch64_cpu_features, align 8
251  %1 = and i64 %0, 131
252  %2 = icmp eq i64 %1, 131
253  br i1 %2, label %common.ret, label %resolver_else
254
255common.ret:                                       ; preds = %resolver_else2, %resolver_else, %resolver_entry
256  %common.ret.op = phi ptr [ @test_priority._MflagmMlseMrng, %resolver_entry ], [ @test_priority._Mls64Mssbs, %resolver_else ], [ %test_priority._Msve2-sha3.test_priority.default, %resolver_else2 ]
257  ret ptr %common.ret.op
258
259resolver_else:                                    ; preds = %resolver_entry
260  %3 = and i64 %0, 9570149208162304
261  %4 = icmp eq i64 %3, 9570149208162304
262  br i1 %4, label %common.ret, label %resolver_else2
263
264resolver_else2:                                   ; preds = %resolver_else
265  %5 = and i64 %0, 1099511627776
266  %.not = icmp eq i64 %5, 0
267  %test_priority._Msve2-sha3.test_priority.default = select i1 %.not, ptr @test_priority.default, ptr @test_priority._Msve2-sha3
268  br label %common.ret
269}
270
271define i32 @caller6._MflagmMls64MlseMrngMssbsMsve2-sha3() #13 {
272; CHECK-LABEL: define i32 @caller6._MflagmMls64MlseMrngMssbsMsve2-sha3(
273; CHECK-SAME: ) local_unnamed_addr #[[ATTR12:[0-9]+]] {
274; CHECK:    [[CALL:%.*]] = tail call i32 @test_priority._Mls64Mssbs()
275;
276entry:
277  %call = tail call i32 @test_priority()
278  ret i32 %call
279}
280
281declare i32 @test_alternative_names._Mdpb2Mfrintts() #14
282declare i32 @test_alternative_names._Mflagm2Mfrintts() #15
283declare i32 @test_alternative_names._Mrcpc2() #16
284declare i32 @test_alternative_names.default() #0
285
286define weak_odr ptr @test_alternative_names.resolver() comdat {
287; CHECK-LABEL: define weak_odr ptr @test_alternative_names.resolver() comdat {
288resolver_entry:
289  tail call void @__init_cpu_features_resolver()
290  %0 = load i64, ptr @__aarch64_cpu_features, align 8
291  %1 = and i64 %0, 17563904
292  %2 = icmp eq i64 %1, 17563904
293  br i1 %2, label %common.ret, label %resolver_else
294
295common.ret:                                       ; preds = %resolver_else2, %resolver_else, %resolver_entry
296  %common.ret.op = phi ptr [ @test_alternative_names._Mdpb2Mfrintts, %resolver_entry ], [ @test_alternative_names._Mflagm2Mfrintts, %resolver_else ], [ %test_alternative_names._Mrcpc2.test_alternative_names.default, %resolver_else2 ]
297  ret ptr %common.ret.op
298
299resolver_else:                                    ; preds = %resolver_entry
300  %3 = and i64 %0, 16777478
301  %4 = icmp eq i64 %3, 16777478
302  br i1 %4, label %common.ret, label %resolver_else2
303
304resolver_else2:                                   ; preds = %resolver_else
305  %5 = and i64 %0, 12582912
306  %6 = icmp eq i64 %5, 12582912
307  %test_alternative_names._Mrcpc2.test_alternative_names.default = select i1 %6, ptr @test_alternative_names._Mrcpc2, ptr @test_alternative_names.default
308  br label %common.ret
309}
310
311define i32 @caller7._Mdpb2Mfrintts() #14 {
312; CHECK-LABEL: define i32 @caller7._Mdpb2Mfrintts(
313; CHECK-SAME: ) local_unnamed_addr #[[ATTR13:[0-9]+]] {
314; CHECK:    [[CALL:%.*]] = tail call i32 @test_alternative_names._Mdpb2Mfrintts()
315;
316entry:
317  %call = tail call i32 @test_alternative_names()
318  ret i32 %call
319}
320
321define i32 @caller7._Mfrintts() #17 {
322; CHECK-LABEL: define i32 @caller7._Mfrintts(
323; CHECK-SAME: ) local_unnamed_addr #[[ATTR16:[0-9]+]] {
324; CHECK:    [[CALL:%.*]] = tail call i32 @test_alternative_names()
325;
326entry:
327  %call = tail call i32 @test_alternative_names()
328  ret i32 %call
329}
330
331define i32 @caller7._Mrcpc2() #16 {
332; CHECK-LABEL: define i32 @caller7._Mrcpc2(
333; CHECK-SAME: ) local_unnamed_addr #[[ATTR15:[0-9]+]] {
334; CHECK:    [[CALL:%.*]] = tail call i32 @test_alternative_names._Mrcpc2()
335;
336entry:
337  %call = tail call i32 @test_alternative_names()
338  ret i32 %call
339}
340
341define i32 @caller7.default() #0 {
342; CHECK-LABEL: define i32 @caller7.default(
343; CHECK-SAME: ) local_unnamed_addr #[[ATTR0]] {
344; CHECK:    [[CALL:%.*]] = tail call i32 @test_alternative_names.default()
345;
346entry:
347  %call = tail call i32 @test_alternative_names()
348  ret i32 %call
349}
350
351attributes #0 = { "fmv-features" }
352attributes #1 = { "fmv-features"="sve" }
353attributes #2 = { "fmv-features"="sve2" }
354attributes #3 = { "fmv-features"="mops" }
355attributes #4 = { "fmv-features"="mops,sve2" }
356attributes #5 = { "fmv-features"="sme" }
357attributes #6 = { "fmv-features"="aes" }
358attributes #7 = { "fmv-features"="sm4" }
359attributes #8 = { "target-features"="+aes,+fp-armv8,+neon,+outline-atomics,+v8a" }
360attributes #9 = { "target-features"="+fp-armv8,+neon,+outline-atomics,+v8a,+sm4" }
361attributes #10 = { "fmv-features"="sve2-sha3" }
362attributes #11 = { "fmv-features"="ls64,ssbs" }
363attributes #12 = { "fmv-features"="flagm,lse,rng" }
364attributes #13 = { "fmv-features"="flagm,ls64,lse,rng,ssbs,sve2-sha3" }
365attributes #14 = { "fmv-features"="dpb2,frintts" }
366attributes #15 = { "fmv-features"="flagm2,frintts" }
367attributes #16 = { "fmv-features"="rcpc2" }
368attributes #17 = { "fmv-features"="frintts" }
369