https://gcc.gnu.org/g:913ff90691dbd1a94bb5b205415955dd053279dd
commit r17-2513-g913ff90691dbd1a94bb5b205415955dd053279dd Author: wangjue <[email protected]> Date: Sat Jul 18 10:52:23 2026 -0600 [PATCH] RISC-V: Do not grow complete unrolling at -O2 RISC-V enables -funroll-loops at -O2 for small-loop unrolling. Keep size-growing complete unrolling disabled unless unrolling is explicitly requested. gcc/ChangeLog: * config/riscv/riscv.cc (riscv_override_options_after_change): New function. (riscv_option_override): Call it. (TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE): Define. gcc/testsuite/ChangeLog: * gcc.target/riscv/unroll-explicit-attr-cunroll.c: New test. * gcc.target/riscv/unroll-small-loop-cunroll.c: New test. Diff: --- gcc/config/riscv/riscv.cc | 31 +++++++++++++++------- .../riscv/unroll-explicit-attr-cunroll.c | 22 +++++++++++++++ .../gcc.target/riscv/unroll-small-loop-cunroll.c | 22 +++++++++++++++ 3 files changed, 66 insertions(+), 9 deletions(-) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 57e798556d04..a401c0c7c93e 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -12142,6 +12142,24 @@ riscv_override_options_internal (struct gcc_options *opts) } } +/* Implement TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE. */ + +static void +riscv_override_options_after_change (void) +{ + /* Explicit unrolling is not restricted to small loops. */ + if ((OPTION_SET_P (flag_unroll_loops) && flag_unroll_loops) + || (OPTION_SET_P (flag_unroll_all_loops) && flag_unroll_all_loops)) + { + if (!OPTION_SET_P (riscv_unroll_only_small_loops)) + riscv_unroll_only_small_loops = 0; + if (!OPTION_SET_P (flag_cunroll_grow_size)) + flag_cunroll_grow_size = 1; + } + else if (!OPTION_SET_P (flag_cunroll_grow_size)) + flag_cunroll_grow_size = flag_peel_loops || optimize >= 3; +} + /* Implement TARGET_OPTION_OVERRIDE. */ void @@ -12153,15 +12171,7 @@ riscv_option_override (void) flag_pcc_struct_return = 0; - /* Explicit -funroll-loops or -funroll-all-loops turns - -munroll-only-small-loops off, allowing the unroller to handle - all loops without the conservative small-loop restriction. */ - if ((OPTION_SET_P (flag_unroll_loops) && flag_unroll_loops) - || (OPTION_SET_P (flag_unroll_all_loops) && flag_unroll_all_loops)) - { - if (!OPTION_SET_P (riscv_unroll_only_small_loops)) - riscv_unroll_only_small_loops = 0; - } + riscv_override_options_after_change (); if (flag_pic) g_switch_value = 0; @@ -16523,6 +16533,9 @@ riscv_memtag_tag_bitsize () #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE riscv_option_override +#undef TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE +#define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE riscv_override_options_after_change + #undef TARGET_OPTION_SAVE #define TARGET_OPTION_SAVE riscv_option_save diff --git a/gcc/testsuite/gcc.target/riscv/unroll-explicit-attr-cunroll.c b/gcc/testsuite/gcc.target/riscv/unroll-explicit-attr-cunroll.c new file mode 100644 index 000000000000..e9628cf8ffbc --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/unroll-explicit-attr-cunroll.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-cunroll-details" } */ + +unsigned short data; + +__attribute__ ((optimize ("unroll-loops"))) +void +explicit_attr_cunroll (void) +{ + unsigned char x; + + for (unsigned int i = 0; i < 8; ++i) + { + x = data & 1; + data >>= 1; + if (x == 1) + data ^= 0x4; + data >>= 1; + } +} + +/* { dg-final { scan-tree-dump "loop with 7 iterations completely unrolled" "cunroll" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/unroll-small-loop-cunroll.c b/gcc/testsuite/gcc.target/riscv/unroll-small-loop-cunroll.c new file mode 100644 index 000000000000..87aec5988fa4 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/unroll-small-loop-cunroll.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-cunroll-details" } */ + +unsigned short data; + +void +small_loop_cunroll (void) +{ + unsigned char x; + + for (unsigned int i = 0; i < 8; ++i) + { + x = data & 1; + data >>= 1; + if (x == 1) + data ^= 0x4; + data >>= 1; + } +} + +/* { dg-final { scan-tree-dump "Not unrolling loop \[0-9\]\+: size would grow" "cunroll" } } */ +/* { dg-final { scan-tree-dump-not "completely unrolled" "cunroll" } } */
