| // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-globals --include-generated-funcs |
| // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +ls64 -target-feature +fullfp16 -S -emit-llvm -o - %s | FileCheck %s |
| // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature -fmv -S -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK-NOFMV |
| |
| int __attribute__((target_version("rng+flagm+fp16fml"))) fmv(void) { return 1; } |
| int __attribute__((target_version("flagm2+sme-i16i64"))) fmv(void) { return 2; } |
| int __attribute__((target_version("lse+sha2"))) fmv(void) { return 3; } |
| int __attribute__((target_version("dotprod+ls64_accdata"))) fmv(void) { return 4; } |
| int __attribute__((target_version("fp16fml+memtag"))) fmv(void) { return 5; } |
| int __attribute__((target_version("fp+aes"))) fmv(void) { return 6; } |
| int __attribute__((target_version("crc+ls64_v"))) fmv(void) { return 7; } |
| int __attribute__((target_version("bti"))) fmv(void) { return 8; } |
| int __attribute__((target_version("sme2"))) fmv(void) { return 9; } |
| int __attribute__((target_version("default"))) fmv(void) { return 0; } |
| int __attribute__((target_version("ls64+simd"))) fmv_one(void) { return 1; } |
| int __attribute__((target_version("dpb"))) fmv_one(void) { return 2; } |
| int __attribute__((target_version("default"))) fmv_one(void) { return 0; } |
| int __attribute__((target_version("fp"))) fmv_two(void) { return 1; } |
| int __attribute__((target_version("simd"))) fmv_two(void) { return 2; } |
| int __attribute__((target_version("dgh"))) fmv_two(void) { return 3; } |
| int __attribute__((target_version("fp16+simd"))) fmv_two(void) { return 4; } |
| int __attribute__((target_version("default"))) fmv_two(void) { return 0; } |
| int foo() { |
| return fmv()+fmv_one()+fmv_two(); |
| } |
| |
| inline int __attribute__((target_version("sha1+pmull+f64mm"))) fmv_inline(void) { return 1; } |
| inline int __attribute__((target_version("fp16+fcma+sme+ fp16 "))) fmv_inline(void) { return 2; } |
| inline int __attribute__((target_version("sha3+i8mm+f32mm"))) fmv_inline(void) { return 12; } |
| inline int __attribute__((target_version("dit+sve-ebf16"))) fmv_inline(void) { return 8; } |
| inline int __attribute__((target_version("dpb+rcpc2 "))) fmv_inline(void) { return 6; } |
| inline int __attribute__((target_version(" dpb2 + jscvt"))) fmv_inline(void) { return 7; } |
| inline int __attribute__((target_version("rcpc+frintts"))) fmv_inline(void) { return 3; } |
| inline int __attribute__((target_version("sve+sve-bf16"))) fmv_inline(void) { return 4; } |
| inline int __attribute__((target_version("sve2-aes+sve2-sha3"))) fmv_inline(void) { return 5; } |
| inline int __attribute__((target_version("sve2+sve2-pmull128+sve2-bitperm"))) fmv_inline(void) { return 9; } |
| inline int __attribute__((target_version("sve2-sm4+memtag2"))) fmv_inline(void) { return 10; } |
| inline int __attribute__((target_version("memtag3"))) fmv_inline(void) { return 11; } |
| inline int __attribute__((target_version("default"))) fmv_inline(void) { return 3; } |
| |
| __attribute__((target_version("ls64"))) int fmv_e(void); |
| int fmv_e(void) { return 20; } |
| |
| static __attribute__((target_version("sb"))) inline int fmv_d(void); |
| static __attribute__((target_version("default"))) inline int fmv_d(void); |
| |
| int __attribute__((target_version("default"))) fmv_default(void) { return 111; } |
| int fmv_default(void); |
| |
| void fmv_c(void); |
| void __attribute__((target_version("ssbs"))) fmv_c(void){}; |
| void __attribute__((target_version("default"))) fmv_c(void){}; |
| |
| int goo() { |
| fmv_inline(); |
| fmv_e(); |
| fmv_d(); |
| fmv_c(); |
| return fmv_default(); |
| } |
| static inline int __attribute__((target_version("sb"))) fmv_d(void) { return 0; } |
| static inline int __attribute__((target_version(" default "))) fmv_d(void) { return 1; } |
| |
| static void func(void) {} |
| inline __attribute__((target_version("default"))) void recb(void) { func(); } |
| inline __attribute__((target_version("default"))) void reca(void) { recb(); } |
| void recur(void) { reca(); } |
| |
| int __attribute__((target_version("default"))) main(void) { |
| recur(); |
| return goo(); |
| } |
| |
| typedef int (*Fptr)(); |
| void f(Fptr); |
| int hoo(void) { |
| f(fmv); |
| Fptr fp1 = &fmv; |
| Fptr fp2 = fmv; |
| return fp1() + fp2(); |
| } |
| |
| // CHECK: @__aarch64_cpu_features = external dso_local global { i64 } |
| // CHECK: @fmv.ifunc = weak_odr ifunc i32 (), ptr @fmv.resolver |
| // CHECK: @fmv_one.ifunc = weak_odr ifunc i32 (), ptr @fmv_one.resolver |
| // CHECK: @fmv_two.ifunc = weak_odr ifunc i32 (), ptr @fmv_two.resolver |
| // CHECK: @fmv_inline.ifunc = weak_odr ifunc i32 (), ptr @fmv_inline.resolver |
| // CHECK: @fmv_e.ifunc = weak_odr ifunc i32 (), ptr @fmv_e.resolver |
| // CHECK: @fmv_d.ifunc = internal ifunc i32 (), ptr @fmv_d.resolver |
| // CHECK: @fmv_c.ifunc = weak_odr ifunc void (), ptr @fmv_c.resolver |
| |
| // CHECK-LABEL: @fmv._MrngMflagmMfp16fml( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret i32 1 |
| // CHECK-LABEL: @fmv._Mflagm2Msme-i16i64( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret i32 2 |
| // CHECK-LABEL: @fmv._MlseMsha2( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret i32 3 |
| // CHECK-LABEL: @fmv._MdotprodMls64_accdata( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret i32 4 |
| // CHECK-LABEL: @fmv._Mfp16fmlMmemtag( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret i32 5 |
| // CHECK-LABEL: @fmv._MfpMaes( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret i32 6 |
| // CHECK-LABEL: @fmv._McrcMls64_v( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret i32 7 |
| // CHECK-LABEL: @fmv._Mbti( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret i32 8 |
| // CHECK-LABEL: @fmv._Msme2( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret i32 9 |
| // CHECK-LABEL: @fmv( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret i32 0 |
| // CHECK-LABEL: @fmv_one._MsimdMls64( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret i32 1 |
| // CHECK-LABEL: @fmv_one._Mdpb( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret i32 2 |
| // CHECK-LABEL: @fmv_one( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret i32 0 |
| // CHECK-LABEL: @fmv_two._Mfp( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret i32 1 |
| // CHECK-LABEL: @fmv_two._Msimd( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret i32 2 |
| // CHECK-LABEL: @fmv_two._Mdgh( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret i32 3 |
| // CHECK-LABEL: @fmv_two._MsimdMfp16( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret i32 4 |
| // CHECK-LABEL: @fmv_two( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret i32 0 |
| // CHECK-LABEL: @foo( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[CALL:%.*]] = call i32 @fmv.ifunc() |
| // CHECK-NEXT: [[CALL1:%.*]] = call i32 @fmv_one.ifunc() |
| // CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL]], [[CALL1]] |
| // CHECK-NEXT: [[CALL2:%.*]] = call i32 @fmv_two.ifunc() |
| // CHECK-NEXT: [[ADD3:%.*]] = add nsw i32 [[ADD]], [[CALL2]] |
| // CHECK-NEXT: ret i32 [[ADD3]] |
| // CHECK-LABEL: @fmv.resolver( |
| // CHECK-NEXT: resolver_entry: |
| // CHECK-NEXT: call void @init_cpu_features_resolver() |
| // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 |
| // CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 11 |
| // CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 11 |
| // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] |
| // CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] |
| // CHECK: resolver_return: |
| // CHECK-NEXT: ret ptr @fmv._MrngMflagmMfp16fml |
| // CHECK: resolver_else: |
| // CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 |
| // CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 72057594037927940 |
| // CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 72057594037927940 |
| // CHECK-NEXT: [[TMP7:%.*]] = and i1 true, [[TMP6]] |
| // CHECK-NEXT: br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]] |
| // CHECK: resolver_return1: |
| // CHECK-NEXT: ret ptr @fmv._Mflagm2Msme-i16i64 |
| // CHECK: resolver_else2: |
| // CHECK-NEXT: [[TMP8:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 |
| // CHECK-NEXT: [[TMP9:%.*]] = and i64 [[TMP8]], 16 |
| // CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 16 |
| // CHECK-NEXT: [[TMP11:%.*]] = and i1 true, [[TMP10]] |
| // CHECK-NEXT: br i1 [[TMP11]], label [[RESOLVER_RETURN3:%.*]], label [[RESOLVER_ELSE4:%.*]] |
| // CHECK: resolver_return3: |
| // CHECK-NEXT: ret ptr @fmv._MdotprodMls64_accdata |
| // CHECK: resolver_else4: |
| // CHECK-NEXT: [[TMP12:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 |
| // CHECK-NEXT: [[TMP13:%.*]] = and i64 [[TMP12]], 1024 |
| // CHECK-NEXT: [[TMP14:%.*]] = icmp eq i64 [[TMP13]], 1024 |
| // CHECK-NEXT: [[TMP15:%.*]] = and i1 true, [[TMP14]] |
| // CHECK-NEXT: br i1 [[TMP15]], label [[RESOLVER_RETURN5:%.*]], label [[RESOLVER_ELSE6:%.*]] |
| // CHECK: resolver_return5: |
| // CHECK-NEXT: ret ptr @fmv._McrcMls64_v |
| // CHECK: resolver_else6: |
| // CHECK-NEXT: [[TMP16:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 |
| // CHECK-NEXT: [[TMP17:%.*]] = and i64 [[TMP16]], 8796093022216 |
| // CHECK-NEXT: [[TMP18:%.*]] = icmp eq i64 [[TMP17]], 8796093022216 |
| // CHECK-NEXT: [[TMP19:%.*]] = and i1 true, [[TMP18]] |
| // CHECK-NEXT: br i1 [[TMP19]], label [[RESOLVER_RETURN7:%.*]], label [[RESOLVER_ELSE8:%.*]] |
| // CHECK: resolver_return7: |
| // CHECK-NEXT: ret ptr @fmv._Mfp16fmlMmemtag |
| // CHECK: resolver_else8: |
| // CHECK-NEXT: [[TMP20:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 |
| // CHECK-NEXT: [[TMP21:%.*]] = and i64 [[TMP20]], 16384 |
| // CHECK-NEXT: [[TMP22:%.*]] = icmp eq i64 [[TMP21]], 16384 |
| // CHECK-NEXT: [[TMP23:%.*]] = and i1 true, [[TMP22]] |
| // CHECK-NEXT: br i1 [[TMP23]], label [[RESOLVER_RETURN9:%.*]], label [[RESOLVER_ELSE10:%.*]] |
| // CHECK: resolver_return9: |
| // CHECK-NEXT: ret ptr @fmv._MfpMaes |
| // CHECK: resolver_else10: |
| // CHECK-NEXT: [[TMP24:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 |
| // CHECK-NEXT: [[TMP25:%.*]] = and i64 [[TMP24]], 4224 |
| // CHECK-NEXT: [[TMP26:%.*]] = icmp eq i64 [[TMP25]], 4224 |
| // CHECK-NEXT: [[TMP27:%.*]] = and i1 true, [[TMP26]] |
| // CHECK-NEXT: br i1 [[TMP27]], label [[RESOLVER_RETURN11:%.*]], label [[RESOLVER_ELSE12:%.*]] |
| // CHECK: resolver_return11: |
| // CHECK-NEXT: ret ptr @fmv._MlseMsha2 |
| // CHECK: resolver_else12: |
| // CHECK-NEXT: [[TMP28:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 |
| // CHECK-NEXT: [[TMP29:%.*]] = and i64 [[TMP28]], 144115188075855872 |
| // CHECK-NEXT: [[TMP30:%.*]] = icmp eq i64 [[TMP29]], 144115188075855872 |
| // CHECK-NEXT: [[TMP31:%.*]] = and i1 true, [[TMP30]] |
| // CHECK-NEXT: br i1 [[TMP31]], label [[RESOLVER_RETURN13:%.*]], label [[RESOLVER_ELSE14:%.*]] |
| // CHECK: resolver_return13: |
| // CHECK-NEXT: ret ptr @fmv._Msme2 |
| // CHECK: resolver_else14: |
| // CHECK-NEXT: [[TMP32:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 |
| // CHECK-NEXT: [[TMP33:%.*]] = and i64 [[TMP32]], 1125899906842624 |
| // CHECK-NEXT: [[TMP34:%.*]] = icmp eq i64 [[TMP33]], 1125899906842624 |
| // CHECK-NEXT: [[TMP35:%.*]] = and i1 true, [[TMP34]] |
| // CHECK-NEXT: br i1 [[TMP35]], label [[RESOLVER_RETURN15:%.*]], label [[RESOLVER_ELSE16:%.*]] |
| // CHECK: resolver_return15: |
| // CHECK-NEXT: ret ptr @fmv._Mbti |
| // CHECK: resolver_else16: |
| // CHECK-NEXT: ret ptr @fmv |
| // CHECK-LABEL: @fmv_one.resolver( |
| // CHECK-NEXT: resolver_entry: |
| // CHECK-NEXT: ret ptr @fmv_one._MsimdMls64 |
| // CHECK-LABEL: @fmv_two.resolver( |
| // CHECK-NEXT: resolver_entry: |
| // CHECK-NEXT: ret ptr @fmv_two._MsimdMfp16 |
| // CHECK-LABEL: @fmv_e( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret i32 20 |
| // CHECK-LABEL: @fmv_default( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret i32 111 |
| // CHECK-LABEL: @fmv_c._Mssbs( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret void |
| // CHECK-LABEL: @fmv_c( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret void |
| // CHECK-LABEL: @goo( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[CALL:%.*]] = call i32 @fmv_inline.ifunc() |
| // CHECK-NEXT: [[CALL1:%.*]] = call i32 @fmv_e.ifunc() |
| // CHECK-NEXT: [[CALL2:%.*]] = call i32 @fmv_d.ifunc() |
| // CHECK-NEXT: call void @fmv_c.ifunc() |
| // CHECK-NEXT: [[CALL3:%.*]] = call i32 @fmv_default() |
| // CHECK-NEXT: ret i32 [[CALL3]] |
| // CHECK-LABEL: @fmv_inline.resolver( |
| // CHECK-NEXT: resolver_entry: |
| // CHECK-NEXT: call void @init_cpu_features_resolver() |
| // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 |
| // CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 4398048608256 |
| // CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 4398048608256 |
| // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] |
| // CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] |
| // CHECK: resolver_return: |
| // CHECK-NEXT: ret ptr @fmv_inline._Mfp16Mfp16MfcmaMsme |
| // CHECK: resolver_else: |
| // CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 |
| // CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 893353197568 |
| // CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 893353197568 |
| // CHECK-NEXT: [[TMP7:%.*]] = and i1 true, [[TMP6]] |
| // CHECK-NEXT: br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]] |
| // CHECK: resolver_return1: |
| // CHECK-NEXT: ret ptr @fmv_inline._Msve2Msve2-pmull128Msve2-bitperm |
| // CHECK: resolver_else2: |
| // CHECK-NEXT: [[TMP8:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 |
| // CHECK-NEXT: [[TMP9:%.*]] = and i64 [[TMP8]], 34359773184 |
| // CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 34359773184 |
| // CHECK-NEXT: [[TMP11:%.*]] = and i1 true, [[TMP10]] |
| // CHECK-NEXT: br i1 [[TMP11]], label [[RESOLVER_RETURN3:%.*]], label [[RESOLVER_ELSE4:%.*]] |
| // CHECK: resolver_return3: |
| // CHECK-NEXT: ret ptr @fmv_inline._Msha1MpmullMf64mm |
| // CHECK: resolver_else4: |
| // CHECK-NEXT: [[TMP12:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 |
| // CHECK-NEXT: [[TMP13:%.*]] = and i64 [[TMP12]], 17246986240 |
| // CHECK-NEXT: [[TMP14:%.*]] = icmp eq i64 [[TMP13]], 17246986240 |
| // CHECK-NEXT: [[TMP15:%.*]] = and i1 true, [[TMP14]] |
| // CHECK-NEXT: br i1 [[TMP15]], label [[RESOLVER_RETURN5:%.*]], label [[RESOLVER_ELSE6:%.*]] |
| // CHECK: resolver_return5: |
| // CHECK-NEXT: ret ptr @fmv_inline._Msha3Mi8mmMf32mm |
| // CHECK: resolver_else6: |
| // CHECK-NEXT: [[TMP16:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 |
| // CHECK-NEXT: [[TMP17:%.*]] = and i64 [[TMP16]], 19791209299968 |
| // CHECK-NEXT: [[TMP18:%.*]] = icmp eq i64 [[TMP17]], 19791209299968 |
| // CHECK-NEXT: [[TMP19:%.*]] = and i1 true, [[TMP18]] |
| // CHECK-NEXT: br i1 [[TMP19]], label [[RESOLVER_RETURN7:%.*]], label [[RESOLVER_ELSE8:%.*]] |
| // CHECK: resolver_return7: |
| // CHECK-NEXT: ret ptr @fmv_inline._Msve2-sm4Mmemtag2 |
| // CHECK: resolver_else8: |
| // CHECK-NEXT: [[TMP20:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 |
| // CHECK-NEXT: [[TMP21:%.*]] = and i64 [[TMP20]], 1236950581248 |
| // CHECK-NEXT: [[TMP22:%.*]] = icmp eq i64 [[TMP21]], 1236950581248 |
| // CHECK-NEXT: [[TMP23:%.*]] = and i1 true, [[TMP22]] |
| // CHECK-NEXT: br i1 [[TMP23]], label [[RESOLVER_RETURN9:%.*]], label [[RESOLVER_ELSE10:%.*]] |
| // CHECK: resolver_return9: |
| // CHECK-NEXT: ret ptr @fmv_inline._Msve2-aesMsve2-sha3 |
| // CHECK: resolver_else10: |
| // CHECK-NEXT: [[TMP24:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 |
| // CHECK-NEXT: [[TMP25:%.*]] = and i64 [[TMP24]], 4295098368 |
| // CHECK-NEXT: [[TMP26:%.*]] = icmp eq i64 [[TMP25]], 4295098368 |
| // CHECK-NEXT: [[TMP27:%.*]] = and i1 true, [[TMP26]] |
| // CHECK-NEXT: br i1 [[TMP27]], label [[RESOLVER_RETURN11:%.*]], label [[RESOLVER_ELSE12:%.*]] |
| // CHECK: resolver_return11: |
| // CHECK-NEXT: ret ptr @fmv_inline._MditMsve-ebf16 |
| // CHECK: resolver_else12: |
| // CHECK-NEXT: [[TMP28:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 |
| // CHECK-NEXT: [[TMP29:%.*]] = and i64 [[TMP28]], 3221225472 |
| // CHECK-NEXT: [[TMP30:%.*]] = icmp eq i64 [[TMP29]], 3221225472 |
| // CHECK-NEXT: [[TMP31:%.*]] = and i1 true, [[TMP30]] |
| // CHECK-NEXT: br i1 [[TMP31]], label [[RESOLVER_RETURN13:%.*]], label [[RESOLVER_ELSE14:%.*]] |
| // CHECK: resolver_return13: |
| // CHECK-NEXT: ret ptr @fmv_inline._MsveMsve-bf16 |
| // CHECK: resolver_else14: |
| // CHECK-NEXT: [[TMP32:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 |
| // CHECK-NEXT: [[TMP33:%.*]] = and i64 [[TMP32]], 20971520 |
| // CHECK-NEXT: [[TMP34:%.*]] = icmp eq i64 [[TMP33]], 20971520 |
| // CHECK-NEXT: [[TMP35:%.*]] = and i1 true, [[TMP34]] |
| // CHECK-NEXT: br i1 [[TMP35]], label [[RESOLVER_RETURN15:%.*]], label [[RESOLVER_ELSE16:%.*]] |
| // CHECK: resolver_return15: |
| // CHECK-NEXT: ret ptr @fmv_inline._MrcpcMfrintts |
| // CHECK: resolver_else16: |
| // CHECK-NEXT: [[TMP36:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 |
| // CHECK-NEXT: [[TMP37:%.*]] = and i64 [[TMP36]], 8650752 |
| // CHECK-NEXT: [[TMP38:%.*]] = icmp eq i64 [[TMP37]], 8650752 |
| // CHECK-NEXT: [[TMP39:%.*]] = and i1 true, [[TMP38]] |
| // CHECK-NEXT: br i1 [[TMP39]], label [[RESOLVER_RETURN17:%.*]], label [[RESOLVER_ELSE18:%.*]] |
| // CHECK: resolver_return17: |
| // CHECK-NEXT: ret ptr @fmv_inline._MdpbMrcpc2 |
| // CHECK: resolver_else18: |
| // CHECK-NEXT: [[TMP40:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 |
| // CHECK-NEXT: [[TMP41:%.*]] = and i64 [[TMP40]], 1572864 |
| // CHECK-NEXT: [[TMP42:%.*]] = icmp eq i64 [[TMP41]], 1572864 |
| // CHECK-NEXT: [[TMP43:%.*]] = and i1 true, [[TMP42]] |
| // CHECK-NEXT: br i1 [[TMP43]], label [[RESOLVER_RETURN19:%.*]], label [[RESOLVER_ELSE20:%.*]] |
| // CHECK: resolver_return19: |
| // CHECK-NEXT: ret ptr @fmv_inline._Mdpb2Mjscvt |
| // CHECK: resolver_else20: |
| // CHECK-NEXT: [[TMP44:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 |
| // CHECK-NEXT: [[TMP45:%.*]] = and i64 [[TMP44]], 35184372088832 |
| // CHECK-NEXT: [[TMP46:%.*]] = icmp eq i64 [[TMP45]], 35184372088832 |
| // CHECK-NEXT: [[TMP47:%.*]] = and i1 true, [[TMP46]] |
| // CHECK-NEXT: br i1 [[TMP47]], label [[RESOLVER_RETURN21:%.*]], label [[RESOLVER_ELSE22:%.*]] |
| // CHECK: resolver_return21: |
| // CHECK-NEXT: ret ptr @fmv_inline._Mmemtag3 |
| // CHECK: resolver_else22: |
| // CHECK-NEXT: ret ptr @fmv_inline |
| // CHECK-LABEL: @fmv_e.resolver( |
| // CHECK-NEXT: resolver_entry: |
| // CHECK-NEXT: ret ptr @fmv_e._Mls64 |
| // CHECK-LABEL: @fmv_d.resolver( |
| // CHECK-NEXT: resolver_entry: |
| // CHECK-NEXT: call void @init_cpu_features_resolver() |
| // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 |
| // CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 70368744177664 |
| // CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 70368744177664 |
| // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] |
| // CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] |
| // CHECK: resolver_return: |
| // CHECK-NEXT: ret ptr @fmv_d._Msb |
| // CHECK: resolver_else: |
| // CHECK-NEXT: ret ptr @fmv_d |
| // CHECK-LABEL: @fmv_c.resolver( |
| // CHECK-NEXT: resolver_entry: |
| // CHECK-NEXT: call void @init_cpu_features_resolver() |
| // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 |
| // CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 281474976710656 |
| // CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 281474976710656 |
| // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] |
| // CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] |
| // CHECK: resolver_return: |
| // CHECK-NEXT: ret ptr @fmv_c._Mssbs |
| // CHECK: resolver_else: |
| // CHECK-NEXT: ret ptr @fmv_c |
| // CHECK-LABEL: @recur( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: call void @reca() |
| // CHECK-NEXT: ret void |
| // CHECK-LABEL: @main( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 |
| // CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4 |
| // CHECK-NEXT: call void @recur() |
| // CHECK-NEXT: [[CALL:%.*]] = call i32 @goo() |
| // CHECK-NEXT: ret i32 [[CALL]] |
| // CHECK-LABEL: @hoo( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: [[FP1:%.*]] = alloca ptr, align 8 |
| // CHECK-NEXT: [[FP2:%.*]] = alloca ptr, align 8 |
| // CHECK-NEXT: call void @f(ptr noundef @fmv.ifunc) |
| // CHECK-NEXT: store ptr @fmv.ifunc, ptr [[FP1]], align 8 |
| // CHECK-NEXT: store ptr @fmv.ifunc, ptr [[FP2]], align 8 |
| // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[FP1]], align 8 |
| // CHECK-NEXT: [[CALL:%.*]] = call i32 [[TMP0]]() |
| // CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[FP2]], align 8 |
| // CHECK-NEXT: [[CALL1:%.*]] = call i32 [[TMP1]]() |
| // CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL]], [[CALL1]] |
| // CHECK-NEXT: ret i32 [[ADD]] |
| // CHECK-LABEL: @fmv_inline._Msha1MpmullMf64mm( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret i32 1 |
| // CHECK-LABEL: @fmv_inline._Mfp16Mfp16MfcmaMsme( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret i32 2 |
| // CHECK-LABEL: @fmv_inline._Msha3Mi8mmMf32mm( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret i32 12 |
| // CHECK-LABEL: @fmv_inline._MditMsve-ebf16( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret i32 8 |
| // CHECK-LABEL: @fmv_inline._MdpbMrcpc2( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret i32 6 |
| // CHECK-LABEL: @fmv_inline._Mdpb2Mjscvt( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret i32 7 |
| // CHECK-LABEL: @fmv_inline._MrcpcMfrintts( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret i32 3 |
| // CHECK-LABEL: @fmv_inline._MsveMsve-bf16( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret i32 4 |
| // CHECK-LABEL: @fmv_inline._Msve2-aesMsve2-sha3( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret i32 5 |
| // CHECK-LABEL: @fmv_inline._Msve2Msve2-pmull128Msve2-bitperm( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret i32 9 |
| // CHECK-LABEL: @fmv_inline._Msve2-sm4Mmemtag2( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret i32 10 |
| // CHECK-LABEL: @fmv_inline._Mmemtag3( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret i32 11 |
| // CHECK-LABEL: @fmv_inline( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret i32 3 |
| // CHECK-LABEL: @fmv_d._Msb( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret i32 0 |
| // CHECK-LABEL: define internal i32 @fmv_d( |
| // CHECK-NEXT: entry: |
| // CHECK-NEXT: ret i32 1 |
| // CHECK-NOFMV-LABEL: @fmv( |
| // CHECK-NOFMV-NEXT: entry: |
| // CHECK-NOFMV-NEXT: ret i32 0 |
| // CHECK-NOFMV-LABEL: @fmv_one( |
| // CHECK-NOFMV-NEXT: entry: |
| // CHECK-NOFMV-NEXT: ret i32 0 |
| // CHECK-NOFMV-LABEL: @fmv_two( |
| // CHECK-NOFMV-NEXT: entry: |
| // CHECK-NOFMV-NEXT: ret i32 0 |
| // CHECK-NOFMV-LABEL: @foo( |
| // CHECK-NOFMV-NEXT: entry: |
| // CHECK-NOFMV-NEXT: [[CALL:%.*]] = call i32 @fmv() |
| // CHECK-NOFMV-NEXT: [[CALL1:%.*]] = call i32 @fmv_one() |
| // CHECK-NOFMV-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL]], [[CALL1]] |
| // CHECK-NOFMV-NEXT: [[CALL2:%.*]] = call i32 @fmv_two() |
| // CHECK-NOFMV-NEXT: [[ADD3:%.*]] = add nsw i32 [[ADD]], [[CALL2]] |
| // CHECK-NOFMV-NEXT: ret i32 [[ADD3]] |
| // CHECK-NOFMV-LABEL: @fmv_e( |
| // CHECK-NOFMV-NEXT: entry: |
| // CHECK-NOFMV-NEXT: ret i32 20 |
| // CHECK-NOFMV-LABEL: @fmv_default( |
| // CHECK-NOFMV-NEXT: entry: |
| // CHECK-NOFMV-NEXT: ret i32 111 |
| // CHECK-NOFMV-LABEL: @fmv_c( |
| // CHECK-NOFMV-NEXT: entry: |
| // CHECK-NOFMV-NEXT: ret void |
| // CHECK-NOFMV-LABEL: @goo( |
| // CHECK-NOFMV-NEXT: entry: |
| // CHECK-NOFMV-NEXT: [[CALL:%.*]] = call i32 @fmv_inline() |
| // CHECK-NOFMV-NEXT: [[CALL1:%.*]] = call i32 @fmv_e() |
| // CHECK-NOFMV-NEXT: [[CALL2:%.*]] = call i32 @fmv_d() |
| // CHECK-NOFMV-NEXT: call void @fmv_c() |
| // CHECK-NOFMV-NEXT: [[CALL3:%.*]] = call i32 @fmv_default() |
| // CHECK-NOFMV-NEXT: ret i32 [[CALL3]] |
| // CHECK-NOFMV-LABEL: define internal i32 @fmv_d( |
| // CHECK-NOFMV-NEXT: entry: |
| // CHECK-NOFMV-NEXT: ret i32 1 |
| // CHECK-NOFMV-LABEL: @recur( |
| // CHECK-NOFMV-NEXT: entry: |
| // CHECK-NOFMV-NEXT: call void @reca() |
| // CHECK-NOFMV-NEXT: ret void |
| // CHECK-NOFMV-LABEL: @main( |
| // CHECK-NOFMV-NEXT: entry: |
| // CHECK-NOFMV-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 |
| // CHECK-NOFMV-NEXT: store i32 0, ptr [[RETVAL]], align 4 |
| // CHECK-NOFMV-NEXT: call void @recur() |
| // CHECK-NOFMV-NEXT: [[CALL:%.*]] = call i32 @goo() |
| // CHECK-NOFMV-NEXT: ret i32 [[CALL]] |
| // CHECK-NOFMV-LABEL: @hoo( |
| // CHECK-NOFMV-NEXT: entry: |
| // CHECK-NOFMV-NEXT: [[FP1:%.*]] = alloca ptr, align 8 |
| // CHECK-NOFMV-NEXT: [[FP2:%.*]] = alloca ptr, align 8 |
| // CHECK-NOFMV-NEXT: call void @f(ptr noundef @fmv) |
| // CHECK-NOFMV-NEXT: store ptr @fmv, ptr [[FP1]], align 8 |
| // CHECK-NOFMV-NEXT: store ptr @fmv, ptr [[FP2]], align 8 |
| // CHECK-NOFMV-NEXT: [[TMP0:%.*]] = load ptr, ptr [[FP1]], align 8 |
| // CHECK-NOFMV-NEXT: [[CALL:%.*]] = call i32 [[TMP0]]() |
| // CHECK-NOFMV-NEXT: [[TMP1:%.*]] = load ptr, ptr [[FP2]], align 8 |
| // CHECK-NOFMV-NEXT: [[CALL1:%.*]] = call i32 [[TMP1]]() |
| // CHECK-NOFMV-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL]], [[CALL1]] |
| // CHECK-NOFMV-NEXT: ret i32 [[ADD]] |
| |
| // 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" } |
| // 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" } |
| // CHECK: attributes #2 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+ls64,+lse,+neon,+sha2" } |
| // CHECK: attributes #3 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+dotprod,+fp-armv8,+fullfp16,+ls64,+neon" } |
| // CHECK: attributes #4 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fp16fml,+fullfp16,+ls64,+neon" } |
| // CHECK: attributes #5 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+ls64,+neon" } |
| // CHECK: attributes #6 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+crc,+fullfp16,+ls64" } |
| // CHECK: attributes #7 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bti,+fullfp16,+ls64" } |
| // CHECK: attributes #8 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+fullfp16,+ls64,+sme,+sme2" } |
| // CHECK: attributes #9 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fullfp16,+ls64" } |
| // CHECK: attributes #10 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ccpp,+fullfp16,+ls64" } |
| // CHECK: attributes #11 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fullfp16,+ls64" } |
| // 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" } |
| // 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" } |
| // 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" } |
| // 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" } |
| // CHECK: attributes #16 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+ccpp,+fullfp16,+ls64,+rcpc" } |
| // 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" } |
| // CHECK: attributes #18 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fptoint,+fullfp16,+ls64,+rcpc" } |
| // CHECK: attributes #19 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+fp-armv8,+fullfp16,+ls64,+neon,+sve" } |
| // 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" } |
| // 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" } |
| // 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" } |
| // CHECK: attributes #23 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fullfp16,+ls64,+mte" } |
| // CHECK: attributes #24 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fullfp16,+ls64,+sb" } |
| |
| // CHECK-NOFMV: attributes #0 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="-fmv" } |
| // CHECK-NOFMV: attributes #1 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="-fmv" } |