| ; 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 | 
 |  | 
 | ; REQUIRES: aarch64-registered-target | 
 |  | 
 | ; RUN: opt --passes=globalopt -o - -S < %s | FileCheck %s | 
 |  | 
 | target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" | 
 | target triple = "aarch64-unknown-linux-gnu" | 
 |  | 
 | $test_single_bb_resolver.resolver = comdat any | 
 | $test_multi_bb_resolver.resolver = comdat any | 
 | $test_caller_feats_not_implied.resolver = comdat any | 
 | $test_non_fmv_caller.resolver = comdat any | 
 | $test_priority.resolver = comdat any | 
 | $test_alternative_names.resolver = comdat any | 
 |  | 
 | @__aarch64_cpu_features = external local_unnamed_addr global { i64 } | 
 |  | 
 | @test_single_bb_resolver = weak_odr ifunc i32 (), ptr @test_single_bb_resolver.resolver | 
 | @test_multi_bb_resolver = weak_odr ifunc i32 (), ptr @test_multi_bb_resolver.resolver | 
 | @test_caller_feats_not_implied = weak_odr ifunc i32 (), ptr @test_caller_feats_not_implied.resolver | 
 | @test_non_fmv_caller = weak_odr ifunc i32 (), ptr @test_non_fmv_caller.resolver | 
 | @test_priority = weak_odr ifunc i32 (), ptr @test_priority.resolver | 
 | @test_alternative_names = weak_odr ifunc i32 (), ptr @test_alternative_names.resolver | 
 |  | 
 | declare void @__init_cpu_features_resolver() local_unnamed_addr | 
 |  | 
 | declare i32 @test_single_bb_resolver.default() #0 | 
 | declare i32 @test_single_bb_resolver._Msve() #1 | 
 | declare i32 @test_single_bb_resolver._Msve2() #2 | 
 |  | 
 | define weak_odr ptr @test_single_bb_resolver.resolver() comdat { | 
 | ; CHECK-LABEL: define weak_odr ptr @test_single_bb_resolver.resolver() comdat { | 
 | resolver_entry: | 
 |   tail call void @__init_cpu_features_resolver() | 
 |   %0 = load i64, ptr @__aarch64_cpu_features, align 8 | 
 |   %1 = and i64 %0, 68719476736 | 
 |   %.not = icmp eq i64 %1, 0 | 
 |   %2 = and i64 %0, 1073741824 | 
 |   %.not3 = icmp eq i64 %2, 0 | 
 |   %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 | 
 |   %common.ret.op = select i1 %.not, ptr %test_single_bb_resolver._Msve.test_single_bb_resolver.default, ptr @test_single_bb_resolver._Msve2 | 
 |   ret ptr %common.ret.op | 
 | } | 
 |  | 
 | define i32 @caller1._Msve() #1 { | 
 | ; CHECK-LABEL: define i32 @caller1._Msve( | 
 | ; CHECK-SAME: ) local_unnamed_addr #[[ATTR1:[0-9]+]] { | 
 | ; CHECK:    [[CALL:%.*]] = tail call i32 @test_single_bb_resolver._Msve() | 
 | ; | 
 | entry: | 
 |   %call = tail call i32 @test_single_bb_resolver() | 
 |   ret i32 %call | 
 | } | 
 |  | 
 | define i32 @caller1._Msve2() #2 { | 
 | ; CHECK-LABEL: define i32 @caller1._Msve2( | 
 | ; CHECK-SAME: ) local_unnamed_addr #[[ATTR2:[0-9]+]] { | 
 | ; CHECK:    [[CALL:%.*]] = tail call i32 @test_single_bb_resolver._Msve2() | 
 | ; | 
 | entry: | 
 |   %call = tail call i32 @test_single_bb_resolver() | 
 |   ret i32 %call | 
 | } | 
 |  | 
 | define i32 @caller1.default() #0 { | 
 | ; CHECK-LABEL: define i32 @caller1.default( | 
 | ; CHECK-SAME: ) local_unnamed_addr #[[ATTR0:[0-9]+]] { | 
 | ; CHECK:    [[CALL:%.*]] = tail call i32 @test_single_bb_resolver.default() | 
 | ; | 
 | entry: | 
 |   %call = tail call i32 @test_single_bb_resolver() | 
 |   ret i32 %call | 
 | } | 
 |  | 
 | declare i32 @test_multi_bb_resolver._Mmops() #3 | 
 | declare i32 @test_multi_bb_resolver._Msve2() #2 | 
 | declare i32 @test_multi_bb_resolver._Msve() #1 | 
 | declare i32 @test_multi_bb_resolver.default() #0 | 
 |  | 
 | define weak_odr ptr @test_multi_bb_resolver.resolver() comdat { | 
 | ; CHECK-LABEL: define weak_odr ptr @test_multi_bb_resolver.resolver() comdat { | 
 | resolver_entry: | 
 |   tail call void @__init_cpu_features_resolver() | 
 |   %0 = load i64, ptr @__aarch64_cpu_features, align 8 | 
 |   %1 = and i64 %0, 576460752303423488 | 
 |   %.not = icmp eq i64 %1, 0 | 
 |   br i1 %.not, label %resolver_else, label %common.ret | 
 |  | 
 | common.ret:                                       ; preds = %resolver_else2, %resolver_else, %resolver_entry | 
 |   %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 ] | 
 |   ret ptr %common.ret.op | 
 |  | 
 | resolver_else:                                    ; preds = %resolver_entry | 
 |   %2 = and i64 %0, 68719476736 | 
 |   %.not5 = icmp eq i64 %2, 0 | 
 |   br i1 %.not5, label %resolver_else2, label %common.ret | 
 |  | 
 | resolver_else2:                                   ; preds = %resolver_else | 
 |   %3 = and i64 %0, 1073741824 | 
 |   %.not6 = icmp eq i64 %3, 0 | 
 |   %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 | 
 |   br label %common.ret | 
 | } | 
 |  | 
 | define i32 @caller2._MmopsMsve2() #4 { | 
 | ; CHECK-LABEL: define i32 @caller2._MmopsMsve2( | 
 | ; CHECK-SAME: ) local_unnamed_addr #[[ATTR4:[0-9]+]] { | 
 | ; CHECK:    [[CALL:%.*]] = tail call i32 @test_multi_bb_resolver._Mmops() | 
 | ; | 
 | entry: | 
 |   %call = tail call i32 @test_multi_bb_resolver() | 
 |   ret i32 %call | 
 | } | 
 |  | 
 | define i32 @caller2._Mmops() #3 { | 
 | ; CHECK-LABEL: define i32 @caller2._Mmops( | 
 | ; CHECK-SAME: ) local_unnamed_addr #[[ATTR3:[0-9]+]] { | 
 | ; CHECK:    [[CALL:%.*]] = tail call i32 @test_multi_bb_resolver._Mmops() | 
 | ; | 
 | entry: | 
 |   %call = tail call i32 @test_multi_bb_resolver() | 
 |   ret i32 %call | 
 | } | 
 |  | 
 | define i32 @caller2._Msve() #1 { | 
 | ; CHECK-LABEL: define i32 @caller2._Msve( | 
 | ; CHECK-SAME: ) local_unnamed_addr #[[ATTR1]] { | 
 | ; CHECK:    [[CALL:%.*]] = tail call i32 @test_multi_bb_resolver() | 
 | ; | 
 | entry: | 
 |   %call = tail call i32 @test_multi_bb_resolver() | 
 |   ret i32 %call | 
 | } | 
 |  | 
 | define i32 @caller2.default() #0 { | 
 | ; CHECK-LABEL: define i32 @caller2.default( | 
 | ; CHECK-SAME: ) local_unnamed_addr #[[ATTR0]] { | 
 | ; CHECK:    [[CALL:%.*]] = tail call i32 @test_multi_bb_resolver.default() | 
 | ; | 
 | entry: | 
 |   %call = tail call i32 @test_multi_bb_resolver() | 
 |   ret i32 %call | 
 | } | 
 |  | 
 | declare i32 @test_caller_feats_not_implied._Mmops() #3 | 
 | declare i32 @test_caller_feats_not_implied._Msme() #5 | 
 | declare i32 @test_caller_feats_not_implied._Msve() #1 | 
 | declare i32 @test_caller_feats_not_implied.default() #0 | 
 |  | 
 | define weak_odr ptr @test_caller_feats_not_implied.resolver() comdat { | 
 | ; CHECK-LABEL: define weak_odr ptr @test_caller_feats_not_implied.resolver() comdat { | 
 | resolver_entry: | 
 |   tail call void @__init_cpu_features_resolver() | 
 |   %0 = load i64, ptr @__aarch64_cpu_features, align 8 | 
 |   %1 = and i64 %0, 576460752303423488 | 
 |   %.not = icmp eq i64 %1, 0 | 
 |   br i1 %.not, label %resolver_else, label %common.ret | 
 |  | 
 | common.ret:                                       ; preds = %resolver_else2, %resolver_else, %resolver_entry | 
 |   %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 ] | 
 |   ret ptr %common.ret.op | 
 |  | 
 | resolver_else:                                    ; preds = %resolver_entry | 
 |   %2 = and i64 %0, 4398046511104 | 
 |   %.not5 = icmp eq i64 %2, 0 | 
 |   br i1 %.not5, label %resolver_else2, label %common.ret | 
 |  | 
 | resolver_else2:                                   ; preds = %resolver_else | 
 |   %3 = and i64 %0, 1073741824 | 
 |   %.not6 = icmp eq i64 %3, 0 | 
 |   %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 | 
 |   br label %common.ret | 
 | } | 
 |  | 
 | define i32 @caller3._Mmops() #3 { | 
 | ; CHECK-LABEL: define i32 @caller3._Mmops( | 
 | ; CHECK-SAME: ) local_unnamed_addr #[[ATTR3]] { | 
 | ; CHECK:    [[CALL:%.*]] = tail call i32 @test_caller_feats_not_implied._Mmops() | 
 | ; | 
 | entry: | 
 |   %call = tail call i32 @test_caller_feats_not_implied() | 
 |   ret i32 %call | 
 | } | 
 |  | 
 | define i32 @caller3._Msve() #1 { | 
 | ; CHECK-LABEL: define i32 @caller3._Msve( | 
 | ; CHECK-SAME: ) local_unnamed_addr #[[ATTR1]] { | 
 | ; CHECK:    [[CALL:%.*]] = tail call i32 @test_caller_feats_not_implied() | 
 | ; | 
 | entry: | 
 |   %call = tail call i32 @test_caller_feats_not_implied() | 
 |   ret i32 %call | 
 | } | 
 |  | 
 | define i32 @caller3.default() #0 { | 
 | ; CHECK-LABEL: define i32 @caller3.default( | 
 | ; CHECK-SAME: ) local_unnamed_addr #[[ATTR0]] { | 
 | ; CHECK:    [[CALL:%.*]] = tail call i32 @test_caller_feats_not_implied() | 
 | ; | 
 | entry: | 
 |   %call = tail call i32 @test_caller_feats_not_implied() | 
 |   ret i32 %call | 
 | } | 
 |  | 
 | declare i32 @test_non_fmv_caller._Maes() #6 | 
 | declare i32 @test_non_fmv_caller._Msm4() #7 | 
 | declare i32 @test_non_fmv_caller.default() #0 | 
 |  | 
 | define weak_odr ptr @test_non_fmv_caller.resolver() comdat { | 
 | ; CHECK-LABEL: define weak_odr ptr @test_non_fmv_caller.resolver() comdat { | 
 | resolver_entry: | 
 |   tail call void @__init_cpu_features_resolver() | 
 |   %0 = load i64, ptr @__aarch64_cpu_features, align 8 | 
 |   %1 = and i64 %0, 32768 | 
 |   %.not = icmp eq i64 %1, 0 | 
 |   %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 | 
 |   ret ptr %test_non_fmv_caller._Maes.test_non_fmv_caller.default | 
 | } | 
 |  | 
 | define i32 @caller4() #8 { | 
 | ; CHECK-LABEL: define i32 @caller4( | 
 | ; CHECK-SAME: ) local_unnamed_addr #[[ATTR7:[0-9]+]] { | 
 | ; CHECK:    [[CALL:%.*]] = tail call i32 @test_non_fmv_caller._Maes() | 
 | ; | 
 | entry: | 
 |   %call = tail call i32 @test_non_fmv_caller() | 
 |   ret i32 %call | 
 | } | 
 |  | 
 | define i32 @caller5() #9 { | 
 | ; CHECK-LABEL: define i32 @caller5( | 
 | ; CHECK-SAME: ) local_unnamed_addr #[[ATTR8:[0-9]+]] { | 
 | ; CHECK:    [[CALL:%.*]] = tail call i32 @test_non_fmv_caller() | 
 | ; | 
 | entry: | 
 |   %call = tail call i32 @test_non_fmv_caller() | 
 |   ret i32 %call | 
 | } | 
 |  | 
 | declare i32 @test_priority._Msve2-sha3() #10 | 
 | declare i32 @test_priority._Mls64Mssbs() #11 | 
 | declare i32 @test_priority._MflagmMlseMrng() #12 | 
 | declare i32 @test_priority.default() #0 | 
 |  | 
 | define weak_odr ptr @test_priority.resolver() comdat { | 
 | ; CHECK-LABEL: define weak_odr ptr @test_priority.resolver() comdat { | 
 | resolver_entry: | 
 |   tail call void @__init_cpu_features_resolver() | 
 |   %0 = load i64, ptr @__aarch64_cpu_features, align 8 | 
 |   %1 = and i64 %0, 131 | 
 |   %2 = icmp eq i64 %1, 131 | 
 |   br i1 %2, label %common.ret, label %resolver_else | 
 |  | 
 | common.ret:                                       ; preds = %resolver_else2, %resolver_else, %resolver_entry | 
 |   %common.ret.op = phi ptr [ @test_priority._MflagmMlseMrng, %resolver_entry ], [ @test_priority._Mls64Mssbs, %resolver_else ], [ %test_priority._Msve2-sha3.test_priority.default, %resolver_else2 ] | 
 |   ret ptr %common.ret.op | 
 |  | 
 | resolver_else:                                    ; preds = %resolver_entry | 
 |   %3 = and i64 %0, 9570149208162304 | 
 |   %4 = icmp eq i64 %3, 9570149208162304 | 
 |   br i1 %4, label %common.ret, label %resolver_else2 | 
 |  | 
 | resolver_else2:                                   ; preds = %resolver_else | 
 |   %5 = and i64 %0, 1099511627776 | 
 |   %.not = icmp eq i64 %5, 0 | 
 |   %test_priority._Msve2-sha3.test_priority.default = select i1 %.not, ptr @test_priority.default, ptr @test_priority._Msve2-sha3 | 
 |   br label %common.ret | 
 | } | 
 |  | 
 | define i32 @caller6._MflagmMls64MlseMrngMssbsMsve2-sha3() #13 { | 
 | ; CHECK-LABEL: define i32 @caller6._MflagmMls64MlseMrngMssbsMsve2-sha3( | 
 | ; CHECK-SAME: ) local_unnamed_addr #[[ATTR12:[0-9]+]] { | 
 | ; CHECK:    [[CALL:%.*]] = tail call i32 @test_priority._Mls64Mssbs() | 
 | ; | 
 | entry: | 
 |   %call = tail call i32 @test_priority() | 
 |   ret i32 %call | 
 | } | 
 |  | 
 | declare i32 @test_alternative_names._Mdpb2Mfrintts() #14 | 
 | declare i32 @test_alternative_names._Mflagm2Mfrintts() #15 | 
 | declare i32 @test_alternative_names._Mrcpc2() #16 | 
 | declare i32 @test_alternative_names.default() #0 | 
 |  | 
 | define weak_odr ptr @test_alternative_names.resolver() comdat { | 
 | ; CHECK-LABEL: define weak_odr ptr @test_alternative_names.resolver() comdat { | 
 | resolver_entry: | 
 |   tail call void @__init_cpu_features_resolver() | 
 |   %0 = load i64, ptr @__aarch64_cpu_features, align 8 | 
 |   %1 = and i64 %0, 17563904 | 
 |   %2 = icmp eq i64 %1, 17563904 | 
 |   br i1 %2, label %common.ret, label %resolver_else | 
 |  | 
 | common.ret:                                       ; preds = %resolver_else2, %resolver_else, %resolver_entry | 
 |   %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 ] | 
 |   ret ptr %common.ret.op | 
 |  | 
 | resolver_else:                                    ; preds = %resolver_entry | 
 |   %3 = and i64 %0, 16777478 | 
 |   %4 = icmp eq i64 %3, 16777478 | 
 |   br i1 %4, label %common.ret, label %resolver_else2 | 
 |  | 
 | resolver_else2:                                   ; preds = %resolver_else | 
 |   %5 = and i64 %0, 12582912 | 
 |   %6 = icmp eq i64 %5, 12582912 | 
 |   %test_alternative_names._Mrcpc2.test_alternative_names.default = select i1 %6, ptr @test_alternative_names._Mrcpc2, ptr @test_alternative_names.default | 
 |   br label %common.ret | 
 | } | 
 |  | 
 | define i32 @caller7._Mdpb2Mfrintts() #14 { | 
 | ; CHECK-LABEL: define i32 @caller7._Mdpb2Mfrintts( | 
 | ; CHECK-SAME: ) local_unnamed_addr #[[ATTR13:[0-9]+]] { | 
 | ; CHECK:    [[CALL:%.*]] = tail call i32 @test_alternative_names._Mdpb2Mfrintts() | 
 | ; | 
 | entry: | 
 |   %call = tail call i32 @test_alternative_names() | 
 |   ret i32 %call | 
 | } | 
 |  | 
 | define i32 @caller7._Mfrintts() #17 { | 
 | ; CHECK-LABEL: define i32 @caller7._Mfrintts( | 
 | ; CHECK-SAME: ) local_unnamed_addr #[[ATTR16:[0-9]+]] { | 
 | ; CHECK:    [[CALL:%.*]] = tail call i32 @test_alternative_names() | 
 | ; | 
 | entry: | 
 |   %call = tail call i32 @test_alternative_names() | 
 |   ret i32 %call | 
 | } | 
 |  | 
 | define i32 @caller7._Mrcpc2() #16 { | 
 | ; CHECK-LABEL: define i32 @caller7._Mrcpc2( | 
 | ; CHECK-SAME: ) local_unnamed_addr #[[ATTR15:[0-9]+]] { | 
 | ; CHECK:    [[CALL:%.*]] = tail call i32 @test_alternative_names._Mrcpc2() | 
 | ; | 
 | entry: | 
 |   %call = tail call i32 @test_alternative_names() | 
 |   ret i32 %call | 
 | } | 
 |  | 
 | define i32 @caller7.default() #0 { | 
 | ; CHECK-LABEL: define i32 @caller7.default( | 
 | ; CHECK-SAME: ) local_unnamed_addr #[[ATTR0]] { | 
 | ; CHECK:    [[CALL:%.*]] = tail call i32 @test_alternative_names.default() | 
 | ; | 
 | entry: | 
 |   %call = tail call i32 @test_alternative_names() | 
 |   ret i32 %call | 
 | } | 
 |  | 
 | attributes #0 = { "fmv-features" } | 
 | attributes #1 = { "fmv-features"="sve" } | 
 | attributes #2 = { "fmv-features"="sve2" } | 
 | attributes #3 = { "fmv-features"="mops" } | 
 | attributes #4 = { "fmv-features"="mops,sve2" } | 
 | attributes #5 = { "fmv-features"="sme" } | 
 | attributes #6 = { "fmv-features"="aes" } | 
 | attributes #7 = { "fmv-features"="sm4" } | 
 | attributes #8 = { "target-features"="+aes,+fp-armv8,+neon,+outline-atomics,+v8a" } | 
 | attributes #9 = { "target-features"="+fp-armv8,+neon,+outline-atomics,+v8a,+sm4" } | 
 | attributes #10 = { "fmv-features"="sve2-sha3" } | 
 | attributes #11 = { "fmv-features"="ls64,ssbs" } | 
 | attributes #12 = { "fmv-features"="flagm,lse,rng" } | 
 | attributes #13 = { "fmv-features"="flagm,ls64,lse,rng,ssbs,sve2-sha3" } | 
 | attributes #14 = { "fmv-features"="dpb2,frintts" } | 
 | attributes #15 = { "fmv-features"="flagm2,frintts" } | 
 | attributes #16 = { "fmv-features"="rcpc2" } | 
 | attributes #17 = { "fmv-features"="frintts" } |