https://gcc.gnu.org/g:f726857ded73f5692280a33be958ce75ffc54b18

commit r16-5557-gf726857ded73f5692280a33be958ce75ffc54b18
Author: Andrew Pinski <[email protected]>
Date:   Thu Nov 20 20:43:16 2025 -0800

    phiprop: Avoid proping loads into loops [PR116835]
    
    This is v2 which uses Richi's code.
    This amends "the post-dominance check to deal with
    SSA cycles [...]. We need to constrain the load to
    be in the same or a subloop (use
    flow_loop_nested_p, not loop depth) or in the same
    BB when either the load or the PHI is in an irreducible region."
    (as described by Richard).
    
    Bootstrapped and tested on x86_64-linux-gnu.
    
            PR tree-optimization/116835
    
    gcc/ChangeLog:
    
            * tree-ssa-phiprop.cc (propagate_with_phi): Admend the
            post-dom check to deal with ssa cycles.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.dg/torture/pr116835.c: New test.
            * gcc.dg/tree-ssa/phiprop-6.c: New test.
            * gcc.dg/tree-ssa/phiprop-7.c: New test.
    
    Signed-off-by: Andrew Pinski <[email protected]>
    Co-authored-by: Richard Biener <[email protected]>

Diff:
---
 gcc/testsuite/gcc.dg/torture/pr116835.c   | 33 +++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/phiprop-6.c | 21 ++++++++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/phiprop-7.c | 21 ++++++++++++++++++++
 gcc/tree-ssa-phiprop.cc                   | 12 +++++++++++
 4 files changed, 87 insertions(+)

diff --git a/gcc/testsuite/gcc.dg/torture/pr116835.c 
b/gcc/testsuite/gcc.dg/torture/pr116835.c
new file mode 100644
index 000000000000..31d3b59d9456
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr116835.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target { weak_undefined } } } */
+/* { dg-add-options weak_undefined } */
+
+/* PR tree-optimization/116835 */
+/* phiprop would prop into the loop the load of b
+   and also prop the load of a before the loop.
+   Which is incorrect as a is a weak symbol.  */
+
+struct s1
+{
+  int t;
+  int t1;
+};
+typedef struct s1 type;
+extern type a __attribute__((weak));
+int t;
+type b;
+type bar (int c) __attribute__((noipa, noinline));
+type 
+bar (int c)
+{
+  t = 1;
+  type *p = &a;
+  for (int j = 0; j < c; ++j)
+    p = &b;
+  return *p;
+}
+
+int main(void)
+{
+ if (bar(&a == nullptr).t)
+   __builtin_abort();
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phiprop-6.c 
b/gcc/testsuite/gcc.dg/tree-ssa/phiprop-6.c
new file mode 100644
index 000000000000..8561cd144805
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/phiprop-6.c
@@ -0,0 +1,21 @@
+/* { dg-do compile { target { weak_undefined } } } */
+/* { dg-options "-O2 -fdump-tree-phiprop-details" } */
+/* { dg-add-options weak_undefined } */
+
+/* PR tree-optimization/116835 */
+
+extern int a __attribute__((weak));
+int b;
+
+int 
+bar (int c)
+{
+  int *p = &a;
+  for (int j = 0; j < c; ++j)
+    p = &b;
+  return *p;
+}
+/* The weak load is conditional with the loop so we cannot make it 
unconditional.  */
+/* { dg-final { scan-tree-dump-not "Removing dead stmt:" "phiprop1"} } */
+/* { dg-final { scan-tree-dump-not "Inserting PHI for result of load" 
"phiprop1"} } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phiprop-7.c 
b/gcc/testsuite/gcc.dg/tree-ssa/phiprop-7.c
new file mode 100644
index 000000000000..ebce03ea6306
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/phiprop-7.c
@@ -0,0 +1,21 @@
+/* { dg-do compile { target { weak_undefined } } } */
+/* { dg-options "-O2 -fdump-tree-phiprop-details" } */
+/* { dg-add-options weak_undefined } */
+
+/* PR tree-optimization/116835 */
+
+extern int a __attribute__((weak));
+int b;
+
+int 
+bar (int c)
+{
+  int *p = &a;
+  for (int j = 0; j < *p; ++j)
+    p = &b;
+  return *p;
+}
+/* The weak load is unconditional due to the conditional so we can remove it 
unconditionally. */
+/* { dg-final { scan-tree-dump "Removing dead stmt:" "phiprop1"} } */
+/* { dg-final { scan-tree-dump "Inserting PHI for result of load" "phiprop1"} 
} */
+
diff --git a/gcc/tree-ssa-phiprop.cc b/gcc/tree-ssa-phiprop.cc
index a2e039fb72d9..d24613d58938 100644
--- a/gcc/tree-ssa-phiprop.cc
+++ b/gcc/tree-ssa-phiprop.cc
@@ -35,6 +35,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa-loop.h"
 #include "tree-cfg.h"
 #include "tree-ssa-dce.h"
+#include "cfgloop.h"
 
 /* This pass propagates indirect loads through the PHI node for its
    address to make the load source possibly non-addressable and to
@@ -348,6 +349,17 @@ propagate_with_phi (basic_block bb, gphi *vphi, gphi *phi,
                              bb, gimple_bb (use_stmt)))
        delay = true;
 
+      /* Amend the post-dominance check for SSA cycles, we need to
+        make sure each PHI result value is dereferenced.
+        We only want to delay this if we don't insert a phi.  */
+      if (!(gimple_bb (use_stmt) == bb
+           || (!(bb->flags & BB_IRREDUCIBLE_LOOP)
+               && !(gimple_bb (use_stmt)->flags & BB_IRREDUCIBLE_LOOP)
+               && (bb->loop_father == gimple_bb (use_stmt)->loop_father
+                   || flow_loop_nested_p (bb->loop_father,
+                                          gimple_bb 
(use_stmt)->loop_father)))))
+       delay = true;
+
       /* Check whether this is a load of *ptr.  */
       if (!(is_gimple_assign (use_stmt)
            && gimple_assign_rhs_code (use_stmt) == MEM_REF

Reply via email to