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
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.