]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
forwprop: Improve simple dse slightly more for eh but multiple incoming edges (phi...
authorAndrew Pinski <andrew.pinski@oss.qualcomm.com>
Wed, 29 Oct 2025 03:29:45 +0000 (20:29 -0700)
committerAndrew Pinski <andrew.pinski@oss.qualcomm.com>
Thu, 30 Oct 2025 15:10:12 +0000 (08:10 -0700)
In this case we have a phi node for the use so we need to see if
the result of the phi is a single usage with the clobber.

That is the following IR:
```
  # .MEM_6 = VDEF <.MEM_5(D)>
  inner = outer;
  # .MEM_7 = VDEF <.MEM_6>
  p (outer);

  <bb 3> :
...
  # .MEM_8 = VDEF <.MEM_7>
  g (_3, _2, _1);

  <bb 4> :
  # .MEM_9 = VDEF <.MEM_8>
  inner ={v} {CLOBBER(eos)};
...

  <bb 5> :
  # .MEM_4 = PHI <.MEM_7(2), .MEM_8(3)>
<L0>:
  # .MEM_10 = VDEF <.MEM_4>
  inner ={v} {CLOBBER(eos)};
```

The two two clobber can be considered the same.
So starting at `bb 4`'s. Bofore we walk back to the call of g statement
and would notice that the use in the phi node of `bb5` and that would cause
the walk to stop. But in this case since he phi node has a single use of the
clobber and the clobber matches the original clobber it can be considered the
same "one". So with the patch now, we walk back one more statement and allow it.
Similar to the at the call to p statement.

Bootstrapped and tested on x86_64-linux-gnu.

PR tree-optimization/122247

gcc/ChangeLog:

* tree-ssa-forwprop.cc (do_simple_agr_dse): Allow phi node for the usage
if the usage of the phi result is just the "same" as the original clobber.

gcc/testsuite/ChangeLog:

* g++.dg/tree-ssa/copy-prop-aggregate-sra-2.C: New test.

Signed-off-by: Andrew Pinski <andrew.pinski@oss.qualcomm.com>
gcc/testsuite/g++.dg/tree-ssa/copy-prop-aggregate-sra-2.C [new file with mode: 0644]
gcc/tree-ssa-forwprop.cc

diff --git a/gcc/testsuite/g++.dg/tree-ssa/copy-prop-aggregate-sra-2.C b/gcc/testsuite/g++.dg/tree-ssa/copy-prop-aggregate-sra-2.C
new file mode 100644 (file)
index 0000000..0b05d5d
--- /dev/null
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-forwprop1-details  -fdump-tree-esra-details -fexceptions" } */
+
+/* PR tree-optimization/122247 */
+
+struct s1
+{
+  int t[1024];
+};
+
+struct s1 f(void);
+
+void g(int a, int b, int );
+void p(struct s1);
+void h(struct s1 outer)
+{
+  struct s1 inner = outer;
+  p(inner);
+  g(outer.t[0], outer.t[1], outer.t[2]);
+}
+/* Forwprop should be able to copy prop the copy of `inner = outer` to the call of p.
+   Also remove this copy. */
+
+/* { dg-final { scan-tree-dump-times "after previous" 1 "forwprop1" } } */
+/* { dg-final { scan-tree-dump-times "Removing dead store stmt inner = outer" 1 "forwprop1" } } */
+
+/* The extra copy that was done by inlining is removed so SRA should not decide to cause
+   inner nor outer to be scalarized even for the 3 elements accessed afterwards.  */
+/* { dg-final { scan-tree-dump-times "Disqualifying inner" 1 "esra" } } */
+/* { dg-final { scan-tree-dump-times "Disqualifying outer" 1 "esra" } } */
+
index 4e273b9053a0ef2a840130a56b37f91fee99473a..9a993ab04de3dc700e2deacd0a760ca292123e04 100644 (file)
@@ -1821,6 +1821,19 @@ do_simple_agr_dse (gassign *stmt, bool full_walk)
          if (gimple_clobber_p (use_stmt, kind)
              && lhs == gimple_assign_lhs (use_stmt))
            continue;
+         /* If the use is a phi and it is single use then check if that single use
+            is a clobber of the same kind and lhs is the same.  */
+         if (gphi *use_phi = dyn_cast<gphi*>(use_stmt))
+           {
+             use_operand_p ou;
+             gimple *ostmt;
+             if (single_imm_use (gimple_phi_result (use_phi), &ou, &ostmt)
+                 && gimple_clobber_p (ostmt, kind)
+                 && lhs == gimple_assign_lhs (ostmt))
+               continue;
+             /* A phi node will never be dominating the clobber.  */
+             return;
+           }
          /* The use needs to be dominating the clobber. */
          if ((ubb != bb && !dominated_by_p (CDI_DOMINATORS, bb, ubb))
              || ref_maybe_used_by_stmt_p (use_stmt, &read, false))