[gcc r17-2513] [PATCH] RISC-V: Do not grow complete unrolling at -O2

Jeff Law via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
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" } } */
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.