https://gcc.gnu.org/g:7e35df8c4129c6b6b88b40d2006b926c391cc761
commit r17-2210-g7e35df8c4129c6b6b88b40d2006b926c391cc761 Author: Philipp Tomsich <[email protected]> Date: Wed Jul 8 08:46:25 2026 +0200 aarch64: populate issue_info for the ampere1 family The ampere1, ampere1a and ampere1b tunes leave the vector issue_info in cpu_vector_cost as NULL, so determine_suggested_unroll_factor bails out early and reduction loops are never multi-accumulator-unrolled on these cores. Fill it in from the ampere1 optimization guide (L1D two 128-bit loads plus one store per cycle, four general ops per cycle). gcc/ChangeLog: * config/aarch64/tuning_models/ampere1.h (ampere1_scalar_issue_info) (ampere1_advsimd_issue_info, ampere1_vec_issue_info): New. (ampere1_vector_cost): Use ampere1_vec_issue_info for issue_info. * config/aarch64/tuning_models/ampere1b.h (ampere1b_scalar_issue_info) (ampere1b_advsimd_issue_info, ampere1b_vec_issue_info): New. (ampere1b_vector_cost): Use ampere1b_vec_issue_info for issue_info. gcc/testsuite/ChangeLog: * gcc.target/aarch64/ampere1-reduction-unroll-1.c: New test. Diff: --- gcc/config/aarch64/tuning_models/ampere1.h | 32 +++++++++++++++++++++- gcc/config/aarch64/tuning_models/ampere1b.h | 32 +++++++++++++++++++++- .../aarch64/ampere1-reduction-unroll-1.c | 18 ++++++++++++ 3 files changed, 80 insertions(+), 2 deletions(-) diff --git a/gcc/config/aarch64/tuning_models/ampere1.h b/gcc/config/aarch64/tuning_models/ampere1.h index 53d45761b42f..e2a42f585dd9 100644 --- a/gcc/config/aarch64/tuning_models/ampere1.h +++ b/gcc/config/aarch64/tuning_models/ampere1.h @@ -46,6 +46,36 @@ static const advsimd_vec_cost ampere1_advsimd_vector_cost = 1 /* store_cost */ }; +static const aarch64_scalar_vec_issue_info ampere1_scalar_issue_info = +{ + 3, /* loads_stores_per_cycle */ + 1, /* stores_per_cycle */ + 4, /* general_ops_per_cycle */ + 0, /* fp_simd_load_general_ops */ + 1 /* fp_simd_store_general_ops */ +}; + +static const aarch64_advsimd_vec_issue_info ampere1_advsimd_issue_info = +{ + { + 2, /* loads_stores_per_cycle */ + 2, /* stores_per_cycle */ + 4, /* general_ops_per_cycle */ + 0, /* fp_simd_load_general_ops */ + 1 /* fp_simd_store_general_ops */ + }, + 2, /* ld2_st2_general_ops */ + 2, /* ld3_st3_general_ops */ + 3 /* ld4_st4_general_ops */ +}; + +static const aarch64_vec_issue_info ampere1_vec_issue_info = +{ + &ere1_scalar_issue_info, + &ere1_advsimd_issue_info, + nullptr /* sve */ +}; + /* Ampere-1 costs for vector insn classes. */ static const struct cpu_vector_cost ampere1_vector_cost = { @@ -57,7 +87,7 @@ static const struct cpu_vector_cost ampere1_vector_cost = 1, /* cond_not_taken_branch_cost */ &ere1_advsimd_vector_cost, /* advsimd */ nullptr, /* sve */ - nullptr /* issue_info */ + &ere1_vec_issue_info /* issue_info */ }; static const cpu_prefetch_tune ampere1_prefetch_tune = diff --git a/gcc/config/aarch64/tuning_models/ampere1b.h b/gcc/config/aarch64/tuning_models/ampere1b.h index b84713b53668..8ba434d27bbf 100644 --- a/gcc/config/aarch64/tuning_models/ampere1b.h +++ b/gcc/config/aarch64/tuning_models/ampere1b.h @@ -57,6 +57,36 @@ static const advsimd_vec_cost ampere1b_advsimd_vector_cost = 1 /* store_cost */ }; +static const aarch64_scalar_vec_issue_info ampere1b_scalar_issue_info = +{ + 3, /* loads_stores_per_cycle */ + 1, /* stores_per_cycle */ + 4, /* general_ops_per_cycle */ + 0, /* fp_simd_load_general_ops */ + 1 /* fp_simd_store_general_ops */ +}; + +static const aarch64_advsimd_vec_issue_info ampere1b_advsimd_issue_info = +{ + { + 2, /* loads_stores_per_cycle */ + 2, /* stores_per_cycle */ + 4, /* general_ops_per_cycle */ + 0, /* fp_simd_load_general_ops */ + 1 /* fp_simd_store_general_ops */ + }, + 2, /* ld2_st2_general_ops */ + 2, /* ld3_st3_general_ops */ + 3 /* ld4_st4_general_ops */ +}; + +static const aarch64_vec_issue_info ampere1b_vec_issue_info = +{ + &ere1b_scalar_issue_info, + &ere1b_advsimd_issue_info, + nullptr /* sve */ +}; + /* Ampere-1B costs for vector insn classes. */ static const struct cpu_vector_cost ampere1b_vector_cost = { @@ -68,7 +98,7 @@ static const struct cpu_vector_cost ampere1b_vector_cost = 1, /* cond_not_taken_branch_cost */ &ere1b_advsimd_vector_cost, /* advsimd */ nullptr, /* sve */ - nullptr /* issue_info */ + &ere1b_vec_issue_info /* issue_info */ }; static const struct tune_params ampere1b_tunings = diff --git a/gcc/testsuite/gcc.target/aarch64/ampere1-reduction-unroll-1.c b/gcc/testsuite/gcc.target/aarch64/ampere1-reduction-unroll-1.c new file mode 100644 index 000000000000..1bb6fa4fb0d0 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/ampere1-reduction-unroll-1.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-Ofast -mcpu=ampere1" } */ + +/* With issue_info populated for the ampere1 family, + determine_suggested_unroll_factor picks 4 for a unit-stride FP dot + product, so the inner reduction emits four independent `fmla v.4s' + accumulator chains. */ + +float +dot (const float *a, const float *b, int n) +{ + float s = 0.0f; + for (int i = 0; i < n; i++) + s += a[i] * b[i]; + return s; +} + +/* { dg-final { scan-assembler-times {\tfmla\tv[0-9]+\.4s} 4 } } */
