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" } } */

Reply via email to