https://gcc.gnu.org/g:135fe58ec9a989fc301d762547325fd90ea37397

commit r16-6233-g135fe58ec9a989fc301d762547325fd90ea37397
Author: Andrew Pinski <[email protected]>
Date:   Mon Dec 15 12:36:44 2025 -0800

    ch: Fix detection of non-executed loop exit
    
    After r16-6104-gb5c64db0a49d46, we try to duplicate bb's
    that contain loop exit that have "never exit" but we check
    against the propability of the exit to very_unlikely. If we
    have PGO, then a loop exit might be very unlikely to be taken
    if we interate the loop more than 2000 times.
    The problem is the check for very_unlikely is just wrong. It should
    just be never. So let's remove that.
    
    Also adds a testcase for __builtin_abort instead of __builtin_unreachable
    since there are slightly different pathes to get the probilities.
    
    Bootstrapped and tested on x86_64-linux-gnu.
    
            PR tree-optimization/122734
    gcc/ChangeLog:
    
            * tree-ssa-loop-ch.cc (should_duplicate_loop_header_p): Remove
            check on very_unlikely probability.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.dg/tree-ssa/copy-headers-13.c: New test.
    
    Signed-off-by: Andrew Pinski <[email protected]>

Diff:
---
 gcc/testsuite/gcc.dg/tree-ssa/copy-headers-13.c | 25 +++++++++++++++++++++++++
 gcc/tree-ssa-loop-ch.cc                         |  8 +-------
 2 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-13.c 
b/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-13.c
new file mode 100644
index 000000000000..cc1b76ccceeb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/copy-headers-13.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-ch-details -fdump-tree-ldist-details" } */
+
+/* PR tree-optimization/122734 */
+/* We want to duplicate the block after the one containing the condition going 
to abort as
+   it is unlikely.
+/* So in the end ldist can generate a memset. */
+
+static inline int size(int *a)
+{
+  int t = *a;
+  if (t < 0)  __builtin_abort();
+  return t;
+}
+
+void f(int *l, short *d)
+{
+  for(int i = 0; i < size(l); i++)
+    d[i] = 0;
+}
+
+/* { dg-final { scan-tree-dump-times "Duplicating bb . is a win" 1 "ch2" } } */
+/* { dg-final { scan-tree-dump-times "Will duplicate bb" 2 "ch2" } } */
+/* { dg-final { scan-tree-dump "is now do-while loop" "ch2" } } */
+/* { dg-final { scan-tree-dump "generated memset zero" "ldist" } } */
diff --git a/gcc/tree-ssa-loop-ch.cc b/gcc/tree-ssa-loop-ch.cc
index feecf91cf700..e6e2b330b458 100644
--- a/gcc/tree-ssa-loop-ch.cc
+++ b/gcc/tree-ssa-loop-ch.cc
@@ -474,13 +474,7 @@ should_duplicate_loop_header_p (basic_block header, class 
loop *loop,
       bool hasone = false;
       FOR_EACH_EDGE (e, ei, header->succs)
        if (loop_exit_edge_p (loop, e)
-           && (probably_never_executed_edge_p (cfun, e)
-               /* We want to rule out paths to noreturns but not
-                  low probabilities resulting from adjustments
-                  or combining.
-                  FIXME: once we have better quality tracking,
-                  make this more robust.  */
-               || e->probability <= profile_probability::very_unlikely ()))
+           && probably_never_executed_edge_p (cfun, e))
          {
            hasone = true;
            if (dump_file && (dump_flags & TDF_DETAILS))

Reply via email to