]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
phi-opt: Do limited form of cselim from phiopt [PR120533]
authorAndrew Pinski <quic_apinski@quicinc.com>
Fri, 6 Jun 2025 18:34:48 +0000 (11:34 -0700)
committerAndrew Pinski <quic_apinski@quicinc.com>
Sun, 8 Jun 2025 19:34:34 +0000 (12:34 -0700)
So currently cselim is limited to targets which have conditional move
and also happens later in the pipeline. This adds the limited form of cselim;
where there is only one store in the two sides and no loads after the store.

This fixes phiprop-2.c for gcn target and now can match the MIN in phiopt1
so it moves the matching of MIN to phiopt1.

The other testcases already disable cselim so they need to disable phiopt too.

Bootstrapped and tested on x86_64-linux-gnu.

PR tree-optimization/120533
gcc/ChangeLog:

* tree-ssa-phiopt.cc (cond_if_else_store_replacement_limited): New function.
(pass_phiopt::execute): Call cond_if_else_store_replacement_limited
for diamand case.

gcc/testsuite/ChangeLog:

* gcc.dg/tree-ssa/pr35286.c: Add -fno-ssa-phiopt.
* gcc.dg/tree-ssa/split-path-6.c: Likewise.
* gcc.dg/tree-ssa/split-path-7.c: Likewise.
* gcc.dg/tree-ssa/phiprop-2.c: Move the check for MIN_EXPR to phiopt1.

Signed-off-by: Andrew Pinski <quic_apinski@quicinc.com>
gcc/testsuite/gcc.dg/tree-ssa/phiprop-2.c
gcc/testsuite/gcc.dg/tree-ssa/pr35286.c
gcc/testsuite/gcc.dg/tree-ssa/split-path-6.c
gcc/testsuite/gcc.dg/tree-ssa/split-path-7.c
gcc/tree-ssa-phiopt.cc

index 7181787db5ebaab09106677dee99318b46d67edc..ae0d181a43ac51adf1dc70acb1afb9c7dbe28f67 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O1 -fdump-tree-phiopt2 -fdump-tree-phiprop1-details" } */
+/* { dg-options "-O1 -fdump-tree-phiopt1 -fdump-tree-phiprop1-details" } */
 
 /* PR tree-optimization/116824 */
 
@@ -24,5 +24,4 @@ int g(int i, int *tt)
 
 /* Check that phiprop1 can do the insert of the loads. */
 /* { dg-final { scan-tree-dump-times "Inserting PHI for result of load" 1 "phiprop1"} } */
-/* Should be able to get MIN_EXPR in phiopt2 after cselim and phiprop. */
-/* { dg-final { scan-tree-dump-times "MIN_EXPR " 1 "phiopt2" } } */
+/* { dg-final { scan-tree-dump-times "MIN_EXPR " 1 "phiopt1" } } */
index 4429cc857bf69a80a3d62991f920f2d8fb13dc82..b4f8c7ce4fce88798278b0740a27fe972c00083a 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */ 
-/* { dg-options "-O2 -fno-code-hoisting -fno-tree-cselim -fdump-tree-pre-stats" } */
+/* { dg-options "-O2 -fno-code-hoisting -fno-tree-cselim -fno-ssa-phiopt -fdump-tree-pre-stats" } */
 int g2;
 struct A {
     int a; int b;
index 71e6362b10c8d84816e92de827da696155f37c80..e2b0a9571f0d22bd5547a4ebc8bce05b7891b17c 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fsplit-paths -fno-tree-cselim -fdump-tree-split-paths-details -fno-finite-loops -fno-tree-dominator-opts -fno-tree-vrp -w" } */
+/* { dg-options "-O2 -fsplit-paths -fno-tree-cselim -fno-ssa-phiopt -fdump-tree-split-paths-details -fno-finite-loops -fno-tree-dominator-opts -fno-tree-vrp -w" } */
 
 struct __sFILE
 {
index 252fe06c666ae4fa0c5271b3ade8a571abed0cfd..35634ab3bd863344b1917b7e32736cdcf4291847 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fsplit-paths -fno-tree-cselim -fno-tree-sink -fdump-tree-split-paths-details -w" } */
+/* { dg-options "-O2 -fsplit-paths -fno-tree-cselim -fno-ssa-phiopt -fno-tree-sink -fdump-tree-split-paths-details -w" } */
 
 
 struct _reent
index 1e770cb0e805c42ef20bbac74c66f05ebe5e41f1..c4e05966924f2909fd72b637e42a76448ed9e3ad 100644 (file)
@@ -3739,6 +3739,50 @@ single_trailing_store_in_bb (basic_block bb, tree vdef, gphi *vphi)
   return store;
 }
 
+/* Limited Conditional store replacement.  We already know
+   that the recognized pattern looks like so:
+
+   split:
+     if (cond) goto THEN_BB; else goto ELSE_BB (edge E1)
+   THEN_BB:
+     ...
+     ONLY_STORE = Y;
+     ...
+     goto JOIN_BB;
+   ELSE_BB:
+     ...
+     ONLY_STORE = Z;
+     ...
+     fallthrough (edge E0)
+   JOIN_BB:
+     some more
+
+   Handles only the case with single store in THEN_BB and ELSE_BB.  That is
+   cheap enough due to in phiopt and not worry about heurstics.  Moving the store
+   out might provide an opportunity for a phiopt to happen.  */
+
+static bool
+cond_if_else_store_replacement_limited (basic_block then_bb, basic_block else_bb,
+                                       basic_block join_bb)
+{
+  gphi *vphi = get_virtual_phi (join_bb);
+  if (!vphi)
+    return false;
+
+  tree then_vdef = PHI_ARG_DEF_FROM_EDGE (vphi, single_succ_edge (then_bb));
+  gimple *then_assign = single_trailing_store_in_bb (then_bb, then_vdef, vphi);
+  if (!then_assign)
+    return false;
+
+  tree else_vdef = PHI_ARG_DEF_FROM_EDGE (vphi, single_succ_edge (else_bb));
+  gimple *else_assign = single_trailing_store_in_bb (else_bb, else_vdef, vphi);
+  if (!else_assign)
+    return false;
+
+  return cond_if_else_store_replacement_1 (then_bb, else_bb, join_bb,
+                                          then_assign, else_assign, vphi);
+}
+
 /* Conditional store replacement.  We already know
    that the recognized pattern looks like so:
 
@@ -4460,6 +4504,11 @@ pass_phiopt::execute (function *)
              && !predictable_edge_p (EDGE_SUCC (bb, 0))
              && !predictable_edge_p (EDGE_SUCC (bb, 1)))
            hoist_adjacent_loads (bb, bb1, bb2, bb3);
+
+         /* Try to see if there are only one store in each side of the if
+            and try to remove that.  */
+         if (EDGE_COUNT (bb3->preds) == 2)
+           cond_if_else_store_replacement_limited (bb1, bb2, bb3);
        }
 
       gimple_stmt_iterator gsi;