Re: [PATCH] RISC-V: Reject table-based CRC optabs for size
Kito Cheng <[email protected]>
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <CA+yXCZAJWffZKVTC5vtL5y69NK=Kwbh1-GU4BmXCVwuYn7O6fA@mail.gmail.com> |
LGTM :) Jojo R <[email protected]> 於 2026年8月19日週三 下午3:02寫道: > > The profitability check added for PR middle-end/124900 asks the target > whether a CRC optab is suitable for both speed and size. The RISC-V > reversed CRC optab is always present, however, and falls back to a > 256-entry lookup table when CLMUL expansion is unavailable. This > allows the transformation under -Os and -Oz even though it > significantly increases code size. > > Implement TARGET_OPTAB_SUPPORTED_P for crc_rev_optab. Keep the table > fallback available when optimizing for speed, but report the optab as > suitable for both speed and size only when Zbc, Zbkc, or Zvbc can > provide the CLMUL expansion and the result mode is narrower than > word_mode. > > Add an RV32/RV64 regression test for the no-CLMUL -Os and -Oz paths. > > gcc/ChangeLog: > > * config/riscv/riscv.cc (riscv_optab_supported_p): New function. > (TARGET_OPTAB_SUPPORTED_P): Define. > > gcc/testsuite/ChangeLog: > > * gcc.target/riscv/crc-size-no-table.c: New test. > --- > gcc/config/riscv/riscv.cc | 18 +++++++++++ > .../gcc.target/riscv/crc-size-no-table.c | 31 +++++++++++++++++++ > 2 files changed, 49 insertions(+) > create mode 100644 gcc/testsuite/gcc.target/riscv/crc-size-no-table.c > > diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc > index a2a51c019ec..5557cf1476d 100644 > --- a/gcc/config/riscv/riscv.cc > +++ b/gcc/config/riscv/riscv.cc > @@ -13197,6 +13197,21 @@ riscv_scalar_mode_supported_p (scalar_mode mode) > return default_scalar_mode_supported_p (mode); > } > > +/* Implement TARGET_OPTAB_SUPPORTED_P. */ > + > +static bool > +riscv_optab_supported_p (int op, machine_mode, machine_mode result_mode, > + optimization_type opt_type) > +{ > + /* The second CRC optab mode is the result mode. The CLMUL expansion > + requires room for a quotient wider than the CRC value itself. */ > + if (op == crc_rev_optab && opt_type != OPTIMIZE_FOR_SPEED) > + return ((TARGET_ZBKC || TARGET_ZBC || TARGET_ZVBC) > + && result_mode < word_mode); > + > + return true; > +} > + > /* Implement TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P - return TRUE > if MODE is HFmode or BFmode, and punt to the generic implementation > otherwise. */ > @@ -16859,6 +16874,9 @@ riscv_memtag_tag_bitsize () > #undef TARGET_SCALAR_MODE_SUPPORTED_P > #define TARGET_SCALAR_MODE_SUPPORTED_P riscv_scalar_mode_supported_p > > +#undef TARGET_OPTAB_SUPPORTED_P > +#define TARGET_OPTAB_SUPPORTED_P riscv_optab_supported_p > + > #undef TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P > #define TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P \ > riscv_libgcc_floating_mode_supported_p > diff --git a/gcc/testsuite/gcc.target/riscv/crc-size-no-table.c b/gcc/testsuite/gcc.target/riscv/crc-size-no-table.c > new file mode 100644 > index 00000000000..1e6d8c45529 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/crc-size-no-table.c > @@ -0,0 +1,31 @@ > +/* { dg-do compile } */ > +/* { dg-options "-march=rv32gc -mabi=ilp32 -fdump-tree-crc-details -fdisable-tree-phiopt2 -fdisable-tree-phiopt3" { target { rv32 } } } */ > +/* { dg-options "-march=rv64gc -mabi=lp64 -fdump-tree-crc-details -fdisable-tree-phiopt2 -fdisable-tree-phiopt3" { target { rv64 } } } */ > +/* { dg-skip-if "" { *-*-* } { "*" } { "-Os" "-Oz" } } */ > + > +typedef unsigned char uint8_t; > +typedef unsigned int uint32_t; > + > +uint32_t > +crc32r (const uint8_t *data, uint32_t size) > +{ > + uint32_t crc = 0xffffffff; > + > + for (uint32_t i = 0; i != size; i++) > + { > + crc ^= data[i]; > + for (int j = 0; j < 8; j++) > + if (crc & 1) > + crc = (crc >> 1) ^ 0xedb88320; > + else > + crc >>= 1; > + } > + > + return ~crc; > +} > + > +/* The CRC loop must be recognized, but retained because rv32gc/rv64gc has no > + CRC optab that is smaller than the original loop. */ > +/* { dg-final { scan-tree-dump "calculates CRC!" "crc" } } */ > +/* { dg-final { scan-tree-dump "Couldn't generate faster CRC code." "crc" } } */ > +/* { dg-final { scan-tree-dump-not {\.CRC_REV} "crc" } } */ > -- > 2.47.1 >