Hi Alfie, > Adds tests that check the aarch64 version features are supported, that they > have the correct priority ordering, and that the generated resolver is > correct.
Minor spelling (Ok to fix in commit): Adds -> Add LGTM - that final check looks a bit more manageable now! Reviewed-by: Wilco Dijkstra <[email protected]> Cheers, Wilco gcc/testsuite/ChangeLog: * gcc.target/aarch64/fmv_priority1.c: New test. * gcc.target/aarch64/fmv_priority2.c: New test. * gcc.target/aarch64/fmv_priority.in: Support file. --- .../gcc.target/aarch64/fmv_priority.in | 92 +++++++++ .../gcc.target/aarch64/fmv_priority1.c | 175 ++++++++++++++++++ .../gcc.target/aarch64/fmv_priority2.c | 29 +++ 3 files changed, 296 insertions(+) create mode 100644 gcc/testsuite/gcc.target/aarch64/fmv_priority.in create mode 100644 gcc/testsuite/gcc.target/aarch64/fmv_priority1.c create mode 100644 gcc/testsuite/gcc.target/aarch64/fmv_priority2.c diff --git a/gcc/testsuite/gcc.target/aarch64/fmv_priority.in b/gcc/testsuite/gcc.target/aarch64/fmv_priority.in new file mode 100644 index 00000000000..93209bce0f2 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/fmv_priority.in @@ -0,0 +1,92 @@ +int fn [[gnu::target_version("default")]] (int) { return 1; } +int fn_default (int) asm("fn.default"); +int fn [[gnu::target_version("rng")]] (int) { return 1; } +int fn_rng(int) asm("fn._Mrng"); +int fn [[gnu::target_version("flagm")]] (int) { return 1; } +int fn_flagm(int) asm("fn._Mflagm"); +int fn [[gnu::target_version("flagm2")]] (int) { return 1; } +int fn_flagm2(int) asm("fn._Mflagm2"); +int fn [[gnu::target_version("lse")]] (int) { return 1; } +int fn_lse(int) asm("fn._Mlse"); +int fn [[gnu::target_version("fp")]] (int) { return 1; } +int fn_fp(int) asm("fn._Mfp"); +int fn [[gnu::target_version("simd")]] (int) { return 1; } +int fn_simd(int) asm("fn._Msimd"); +int fn [[gnu::target_version("dotprod")]] (int) { return 1; } +int fn_dotprod(int) asm("fn._Mdotprod"); +int fn [[gnu::target_version("sm4")]] (int) { return 1; } +int fn_sm4(int) asm("fn._Msm4"); +int fn [[gnu::target_version("rdm")]] (int) { return 1; } +int fn_rdm(int) asm("fn._MrdmaMrdm"); +int fn [[gnu::target_version("crc")]] (int) { return 1; } +int fn_crc(int) asm("fn._Mcrc"); +int fn [[gnu::target_version("sha2")]] (int) { return 1; } +int fn_sha2(int) asm("fn._Msha2"); +int fn [[gnu::target_version("sha3")]] (int) { return 1; } +int fn_sha3(int) asm("fn._Msha3"); +int fn [[gnu::target_version("aes")]] (int) { return 1; } +int fn_aes(int) asm("fn._Maes"); +int fn [[gnu::target_version("fp16")]] (int) { return 1; } +int fn_fp16(int) asm("fn._Mfp16"); +int fn [[gnu::target_version("fp16fml")]] (int) { return 1; } +int fn_fp16fml(int) asm("fn._Mfp16fml"); +/* TODO: These FMV features are not yet supported in GCC. */ +// int fn [[gnu::target_version("dit")]] (int) { return 1; } +// int fn [[gnu::target_version("dpb")]] (int) { return 1; } +// int fn [[gnu::target_version("dpb2")]] (int) { return 1; } +int fn [[gnu::target_version("jscvt")]] (int) { return 1; } +int fn_jscvt(int) asm("fn._Mjscvt"); +int fn [[gnu::target_version("fcma")]] (int) { return 1; } +int fn_fcma(int) asm("fn._Mfcma"); +int fn [[gnu::target_version("rcpc")]] (int) { return 1; } +int fn_rcpc(int) asm("fn._Mrcpc"); +int fn [[gnu::target_version("rcpc2")]] (int) { return 1; } +int fn_rcpc2(int) asm("fn._Mrcpc2"); +int fn [[gnu::target_version("rcpc3")]] (int) { return 1; } +int fn_rcpc3(int) asm("fn._Mrcpc3"); +int fn [[gnu::target_version("frintts")]] (int) { return 1; } +int fn_frintts(int) asm("fn._Mfrintts"); +int fn [[gnu::target_version("i8mm")]] (int) { return 1; } +int fn_i8mm(int) asm("fn._Mi8mm"); +int fn [[gnu::target_version("bf16")]] (int) { return 1; } +int fn_bf16(int) asm("fn._Mbf16"); +int fn [[gnu::target_version("sve")]] (int) { return 1; } +int fn_sve(int) asm("fn._Msve"); +int fn [[gnu::target_version("f32mm")]] (int) { return 1; } +int fn_f32mm(int) asm("fn._Mf32mm"); +int fn [[gnu::target_version("f64mm")]] (int) { return 1; } +int fn_f64mm(int) asm("fn._Mf64mm"); +int fn [[gnu::target_version("sve2")]] (int) { return 1; } +int fn_sve2(int) asm("fn._Msve2"); +int fn [[gnu::target_version("sve2-aes")]] (int) { return 1; } +int fn_sve2_aes(int) asm("fn._Msve2_aes"); +int fn [[gnu::target_version("sve2-bitperm")]] (int) { return 1; } +int fn_sve2_bitperm(int) asm("fn._Msve2_bitperm"); +int fn [[gnu::target_version("sve2-sha3")]] (int) { return 1; } +int fn_sve2_sha3(int) asm("fn._Msve2_sha3"); +int fn [[gnu::target_version("sve2-sm4")]] (int) { return 1; } +int fn_sve2_sm4(int) asm("fn._Msve2_sm4"); +int fn [[gnu::target_version("sve2+sme")]] (int) { return 1; } +int fn_sve2_sme(int) asm("fn._Msve2Msme"); +/* TODO: This FMV features is not yet supported in GCC. */ +// int fn [[gnu::target_version("memtag")]] (int) { return 1; } +int fn [[gnu::target_version("sb")]] (int) { return 1; } +int fn_sb(int) asm("fn._Msb"); +/* TODO: This FMV feature is not yet supported in GCC. */ +// int fn [[gnu::target_version("ssbs")]] (int) { return 1; } +// int fn_ssbs(int) asm("fn._Mssbs"); +/* TODO: This FMV feature is not yet supported in GCC. */ +// int fn [[gnu::target_version("bti")]] (int) { return 1; } +int fn [[gnu::target_version("wfxt")]] (int) { return 1; } +int fn_wfxt(int) asm("fn._Mwfxt"); +int fn [[gnu::target_version("sve2+sme-f64f64")]] (int) { return 1; } +int fn_sve2_sme_f64f64(int) asm("fn._Msve2Msme_f64f64"); +int fn [[gnu::target_version("sve2+sme-i16i64")]] (int) { return 1; } +int fn_sve2_sme_i16i64(int) asm("fn._Msve2Msme_i16i64"); +int fn [[gnu::target_version("sve2+sme2")]] (int) { return 1; } +int fn_sve2_sme2(int) asm("fn._Msve2Msme2"); +int fn [[gnu::target_version("mops")]] (int) { return 1; } +int fn_mops(int) asm("fn._Mmops"); +int fn [[gnu::target_version("cssc")]] (int) { return 1; } +int fn_cssc(int) asm("fn._Mcssc"); + diff --git a/gcc/testsuite/gcc.target/aarch64/fmv_priority1.c b/gcc/testsuite/gcc.target/aarch64/fmv_priority1.c new file mode 100644 index 00000000000..942b7a71c3a --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/fmv_priority1.c @@ -0,0 +1,175 @@ +/* { dg-do run { target { aarch64_asm_sme2_ok } } } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0 -march=armv8-a" } */ + +#include <sys/auxv.h> +#include "../../../common/config/aarch64/cpuinfo.h" + +/* This test has a FMV function set with one version per feature we support. + Each version is turned on incrementally and the generated resolver is + checked to show the correct version is chosen. */ + +/* The resolver does actually take arguments, but ignores them and uses + __aarch64_cpu_features global instead to establish what features are + present. */ +int (*(resolver)(void)) (int) asm("fn.resolver"); + +extern struct { + unsigned long long features; +} aarch64_cpu_features asm("__aarch64_cpu_features"); + +#include "fmv_priority.in" + +#define setCPUFeature(F) aarch64_cpu_features.features |= 1UL << F + +int main () { + aarch64_cpu_features.features = 0; + + /* Initialize the CPU features, so the resolver doesn't try fetch it. */ + setCPUFeature(FEAT_INIT); + + /* Go through features in order and assure the priorities are correct. + By checking the correct versions are resolved. */ + + /* Some are missing as they are defined in the ACLE but are not yet + implemented. */ + if (resolver() != &fn_default) return 1; + + setCPUFeature(FEAT_RNG); + if (resolver() != &fn_rng) return 1; + + setCPUFeature(FEAT_FLAGM); + if (resolver() != &fn_flagm) return 1; + + setCPUFeature(FEAT_FLAGM2); + if (resolver() != &fn_flagm2) return 1; + + setCPUFeature (FEAT_LSE); + if (resolver () != &fn_lse) return 1; + + setCPUFeature (FEAT_FP); + if (resolver () != &fn_fp) return 1; + + setCPUFeature (FEAT_SIMD); + if (resolver () != &fn_simd) return 1; + + setCPUFeature (FEAT_DOTPROD); + if (resolver () != &fn_dotprod) return 1; + + setCPUFeature (FEAT_SM4); + if(resolver() != &fn_sm4) return 1; + + setCPUFeature (FEAT_RDM); + if(resolver() != &fn_rdm) return 1; + + setCPUFeature (FEAT_CRC); + if (resolver () != &fn_crc) return 1; + + setCPUFeature (FEAT_SHA2); + if (resolver () != &fn_sha2) return 1; + + setCPUFeature (FEAT_SHA3); + if (resolver () != &fn_sha3) return 1; + + setCPUFeature(FEAT_PMULL); + if(resolver() != &fn_aes) return 1; + + setCPUFeature (FEAT_FP16); + if (resolver () != &fn_fp16) return 1; + + setCPUFeature (FEAT_FP16FML); + if(resolver() != &fn_fp16fml) return 1; + + setCPUFeature (FEAT_DIT); + // if(resolver() != &fn_dit) return 1; + // + setCPUFeature (FEAT_DPB); + // if(resolver() != &fn_dpb) return 1; + // + setCPUFeature (FEAT_DPB2); + // if(resolver() != &fn_dpb2) return 1; + // + setCPUFeature (FEAT_JSCVT); + if (resolver () != &fn_jscvt) return 1; + + setCPUFeature (FEAT_FCMA); + if (resolver () != &fn_fcma) return 1; + + setCPUFeature (FEAT_RCPC); + if (resolver () != &fn_rcpc) return 1; + + setCPUFeature (FEAT_RCPC2); + if (resolver () != &fn_rcpc2) return 1; + + setCPUFeature (FEAT_RCPC3); + // if(resolver() != &fn_rcpc3) return 1; + // + setCPUFeature (FEAT_FRINTTS); + if (resolver () != &fn_frintts) return 1; + + setCPUFeature (FEAT_I8MM); + if (resolver () != &fn_i8mm) return 1; + + setCPUFeature (FEAT_BF16); + if (resolver () != &fn_bf16) return 1; + + setCPUFeature (FEAT_SVE); + if (resolver () != &fn_sve) return 1; + + setCPUFeature (FEAT_SVE_F32MM); + if(resolver() != &fn_f32mm) return 1; + + setCPUFeature (FEAT_SVE_F64MM); + if(resolver() != &fn_f64mm) return 1; + + setCPUFeature (FEAT_SVE2); + if (resolver () != &fn_sve2) return 1; + + setCPUFeature(FEAT_SVE_PMULL128); + if(resolver() != &fn_sve2_aes) return 1; + + setCPUFeature (FEAT_SVE_BITPERM); + if (resolver () != &fn_sve2_bitperm) return 1; + + setCPUFeature (FEAT_SVE_SHA3); + if (resolver () != &fn_sve2_sha3) return 1; + + setCPUFeature (FEAT_SVE_SM4); + if (resolver () != &fn_sve2_sm4) return 1; + + setCPUFeature (FEAT_SME); + if (resolver () != &fn_sve2_sme) return 1; + + setCPUFeature(FEAT_MEMTAG2); + // if(resolver() != &fn_memtag) return 1; + + setCPUFeature (FEAT_SB); + if (resolver () != &fn_sb) return 1; + + setCPUFeature(FEAT_SSBS2); + // if(resolver() != &fn_ssbs) return 1; + + setCPUFeature(FEAT_BTI); + // if(resolver() != &fn_bti) return 1; + + setCPUFeature (FEAT_WFXT); + if (resolver () != &fn_wfxt) return 1; + + setCPUFeature (FEAT_SME_F64); + if (resolver () != &fn_sve2_sme_f64f64) return 1; + + setCPUFeature (FEAT_SME_I64); + if (resolver () != &fn_sve2_sme_i16i64) return 1; + + setCPUFeature (FEAT_SME2); + if (resolver () != &fn_sve2_sme2) return 1; + + setCPUFeature (FEAT_MOPS); + if (resolver () != &fn_mops) return 1; + + setCPUFeature (FEAT_CSSC); + if (resolver () != &fn_cssc) return 1; + + return 0; +} + diff --git a/gcc/testsuite/gcc.target/aarch64/fmv_priority2.c b/gcc/testsuite/gcc.target/aarch64/fmv_priority2.c new file mode 100644 index 00000000000..dbeb15e4f62 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/fmv_priority2.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O0 -march=armv8-a -fdump-ipa-targetclone1-details" } */ + +#include "fmv_priority.in" + +// Checks that the versions are in the correct order +// Each of these lines checks 3 consecutive versions in the list with one overlap +/* { dg-final { scan-ipa-dump-times "Version order for fn/\[0-9\]+:\\nfn\.default/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\.default/\[0-9\]+\\nfn\._Mrng/\[0-9\]+\\nfn\._Mflagm/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Mflagm/\[0-9\]+\\nfn\._Mflagm2/\[0-9\]+\\nfn\._Mlse/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Mlse/\[0-9\]+\\nfn\._Mfp/\[0-9\]+\\nfn\._Msimd/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Msimd/\[0-9\]+\\nfn\._Mdotprod/\[0-9\]+\\nfn\._Msm4/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Msm4/\[0-9\]+\\nfn\._MrdmaMrdm/\[0-9\]+\\nfn\._Mcrc/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Mcrc/\[0-9\]+\\nfn\._Msha2/\[0-9\]+\\nfn\._Msha3/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Msha3/\[0-9\]+\\nfn\._Maes/\[0-9\]+\\nfn\._Mfp16/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Mfp16/\[0-9\]+\\nfn\._Mfp16fml/\[0-9\]+\\nfn\._Mjscvt/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Mjscvt/\[0-9\]+\\nfn\._Mfcma/\[0-9\]+\\nfn\._Mrcpc/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Mrcpc/\[0-9\]+\\nfn\._Mrcpc2/\[0-9\]+\\nfn\._Mrcpc3/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Mrcpc3/\[0-9\]+\\nfn\._Mfrintts/\[0-9\]+\\nfn\._Mi8mm/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Mi8mm/\[0-9\]+\\nfn\._Mbf16/\[0-9\]+\\nfn\._Msve/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Msve/\[0-9\]+\\nfn\._Mf32mm/\[0-9\]+\\nfn\._Mf64mm/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Mf64mm/\[0-9\]+\\nfn\._Msve2/\[0-9\]+\\nfn\._Msve2_aes/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Msve2_aes/\[0-9\]+\\nfn\._Msve2_bitperm/\[0-9\]+\\nfn\._Msve2_sha3/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Msve2_sha3/\[0-9\]+\\nfn\._Msve2_sm4/\[0-9\]+\\nfn\._Msve2Msme/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Msve2Msme/\[0-9\]+\\nfn\._Msb/\[0-9\]+\\nfn\._Mwfxt/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Mwfxt/\[0-9\]+\\nfn\._Msve2Msme_f64f64/\[0-9\]+\\nfn\._Msve2Msme_i16i64/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Msve2Msme_i16i64/\[0-9\]+\\nfn\._Msve2Msme2/\[0-9\]+\\nfn\._Mmops/\[0-9\]+\\n" 1 "targetclone1" } } */ +/* { dg-final { scan-ipa-dump-times "fn\._Mmops/\[0-9\]+\\nfn\._Mcssc/\[0-9\]+\\n" 1 "targetclone1" } } */ -- 2.34.1
