[gcc r17-3519] AArch64: Add POLY_INT_CST bounds for SVE.
Tamar Christina via Gcc-cvs <[email protected]>
| Newsgroups | gmane.comp.gcc.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://gcc.gnu.org/g:a3fb4bf350d6b7bea7aa04efcf9c584e6a9d93df commit r17-3519-ga3fb4bf350d6b7bea7aa04efcf9c584e6a9d93df Author: Tamar Christina <[email protected]> Date: Fri Aug 21 16:12:26 2026 +0100 AArch64: Add POLY_INT_CST bounds for SVE. This patch implements POLY_INT indeterminate bounds for AArch64. With this patch #include <arm_sve.h> int g (void) { unsigned int vl = svcntb (); return vl < 257; } int h (void) { return svcntw () <= 64; } gets folded away to g(): mov w0, #1 ret h(): mov w0, #1 ret which is right because both are always true for any SVE vector length. Instead of the previous: g(): cntb x0 cmp w0, 257 cset w0, cc ret h(): cntw x0 cmp x0, 65 cset w0, cc ret gcc/ChangeLog: * config/aarch64/aarch64.cc (aarch64_poly_int_indeterminate_bound): New. (TARGET_POLY_INT_INDETERMINATE_BOUND): Implement hook using it. gcc/testsuite/ChangeLog: * gcc.target/aarch64/sve/slp_12.c: Update testcases * gcc.target/aarch64/sve/cnt_fold_7.c: New test. * gcc.target/aarch64/sve/cnt_fold_7_run.c: New test. Diff: --- gcc/config/aarch64/aarch64.cc | 11 ++ gcc/testsuite/gcc.target/aarch64/sve/cnt_fold_7.c | 154 +++++++++++++++++++++ .../gcc.target/aarch64/sve/cnt_fold_7_run.c | 47 +++++++ gcc/testsuite/gcc.target/aarch64/sve/slp_12.c | 14 +- 4 files changed, 218 insertions(+), 8 deletions(-) diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index 4671a47d3950..8e62ab6a72e0 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -31328,6 +31328,14 @@ aarch64_estimated_poly_value (poly_int64 val, return val.coeffs[0] + val.coeffs[1] * over_128 / 128; } +/* Implement TARGET_POLY_INT_INDETERMINATE_BOUND. */ + +static poly_uint64 +aarch64_poly_int_indeterminate_bound () +{ + return poly_uint64 (0, 15); +} + /* Return true for types that could be supported as SIMD return or argument types. */ @@ -34650,6 +34658,9 @@ aarch64_libgcc_floating_mode_supported_p #undef TARGET_ESTIMATED_POLY_VALUE #define TARGET_ESTIMATED_POLY_VALUE aarch64_estimated_poly_value +#undef TARGET_POLY_INT_INDETERMINATE_BOUND +#define TARGET_POLY_INT_INDETERMINATE_BOUND aarch64_poly_int_indeterminate_bound + #undef TARGET_ATTRIBUTE_TABLE #define TARGET_ATTRIBUTE_TABLE aarch64_attribute_table diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cnt_fold_7.c b/gcc/testsuite/gcc.target/aarch64/sve/cnt_fold_7.c new file mode 100644 index 000000000000..d64933527da7 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/cnt_fold_7.c @@ -0,0 +1,154 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#include <arm_sve.h> + +/* +** b_lt_257: +** mov w0, 1 +** ret +*/ +int +b_lt_257 (void) +{ + unsigned int vl = svcntb (); + + return vl < 257; +} + +/* +** h_ge_8: +** mov w0, 1 +** ret +*/ +int +h_ge_8 (void) +{ + return svcnth () >= 8; +} + +/* +** w_le_64: +** mov w0, 1 +** ret +*/ +int +w_le_64 (void) +{ + return svcntw () <= 64; +} + +/* +** d_gt_1: +** mov w0, 1 +** ret +*/ +int +d_gt_1 (void) +{ + return svcntd () > 1; +} + +/* +** b_ne_0: +** mov w0, 1 +** ret +*/ +int +b_ne_0 (void) +{ + return svcntb () != 0; +} + +/* +** b_le_15: +** mov w0, 0 +** ret +*/ +int +b_le_15 (void) +{ + return svcntb () <= 15; +} + +/* +** h_lt_8: +** mov w0, 0 +** ret +*/ +int +h_lt_8 (void) +{ + return svcnth () < 8; +} + +/* +** w_gt_64: +** mov w0, 0 +** ret +*/ +int +w_gt_64 (void) +{ + return svcntw () > 64; +} + +/* +** d_eq_0: +** mov w0, 0 +** ret +*/ +int +d_eq_0 (void) +{ + return svcntd () == 0; +} + +/* +** b_lt_256: +** cntb x0 +** cmp x0, 256 +** cset w0, cc +** ret +*/ +int +b_lt_256 (void) +{ + return svcntb () < 256; +} + +/* +** w_gt_4: +** cntw x0 +** cmp x0, 4 +** cset w0, hi +** ret +*/ +int +w_gt_4 (void) +{ + return svcntw () > 4; +} + +/* +** b_pat_all_lt_257: +** mov w0, 1 +** ret +*/ +int +b_pat_all_lt_257 (void) +{ + return svcntb_pat (SV_ALL) < 257; +} + +/* +** w_pat_all_le_64: +** mov w0, 1 +** ret +*/ +int +w_pat_all_le_64 (void) +{ + return svcntw_pat (SV_ALL) <= 64; +} diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cnt_fold_7_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cnt_fold_7_run.c new file mode 100644 index 000000000000..59217ab343ec --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/cnt_fold_7_run.c @@ -0,0 +1,47 @@ +/* { dg-do run { target aarch64_sve_hw } } */ +/* { dg-options "-O2" } */ + +#include <arm_sve.h> + +#define CHECK(EXPR) \ + do \ + { \ + if (!(EXPR)) \ + __builtin_abort (); \ + } \ + while (0) + +int +main (void) +{ + unsigned int b = svcntb (); + unsigned int h = svcnth (); + unsigned int w = svcntw (); + unsigned int d = svcntd (); + + CHECK (b >= 16 && b <= 256); + CHECK (h >= 8 && h <= 128); + CHECK (w >= 4 && w <= 64); + CHECK (d >= 2 && d <= 32); + + CHECK (b < 257); + CHECK (h >= 8); + CHECK (w <= 64); + CHECK (d > 1); + CHECK (b != 0); + + CHECK (!(b <= 15)); + CHECK (!(h < 8)); + CHECK (!(w > 64)); + CHECK (!(d == 0)); + + CHECK ((svcntb () < 256) == (b < 256)); + CHECK ((svcntw () > 4) == (w > 4)); + + CHECK (svcntb_pat (SV_ALL) == b); + CHECK (svcntw_pat (SV_ALL) == w); + CHECK (svcntb_pat (SV_ALL) < 257); + CHECK (svcntw_pat (SV_ALL) <= 64); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/aarch64/sve/slp_12.c b/gcc/testsuite/gcc.target/aarch64/sve/slp_12.c index 6ba4c9651b67..c81845f2c87f 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/slp_12.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/slp_12.c @@ -47,14 +47,12 @@ TEST_ALL (VEC_PERM) /* We should use WHILEs for all accesses. */ /* { dg-final { scan-assembler-times {\twhilelo\tp[0-7]\.b} 20 } } */ -/* { dg-final { scan-assembler-times {\twhilelo\tp[0-7]\.h} 18 } } */ -/* { dg-final { scan-assembler-times {\twhilelo\tp[0-7]\.s} 27 } } */ -/* { dg-final { scan-assembler-times {\twhilelo\tp[0-7]\.d} 24 } } */ +/* { dg-final { scan-assembler-times {\twhilelo\tp[0-7]\.h} 16 } } */ +/* { dg-final { scan-assembler-times {\twhilelo\tp[0-7]\.s} 21 } } */ +/* { dg-final { scan-assembler-times {\twhilelo\tp[0-7]\.d} 15 } } */ /* 6 for the 8-bit types and 2 for the 16-bit types. */ /* { dg-final { scan-assembler-times {\tuqdecb\t} 8 } } */ -/* 4 for the 16-bit types and 3 for the 32-bit types. */ -/* { dg-final { scan-assembler-times {\tuqdech\t} 7 } } */ -/* 6 for the 32-bit types and 3 for the 64-bit types. */ -/* { dg-final { scan-assembler-times {\tuqdecw\t} 9 } } */ -/* { dg-final { scan-assembler-times {\tuqdecd\t} 6 } } */ +/* { dg-final { scan-assembler-times {\tuqdech\t} 2 } } */ +/* { dg-final { scan-assembler-times {\tuqdecw\t} 3 } } */ +/* { dg-final { scan-assembler-not {\tuqdecd\t} } } */