]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PHIOPT: Loop over calling factor_out_conditional_conversion
authorAndrew Pinski <apinski@marvell.com>
Thu, 27 Apr 2023 16:50:43 +0000 (09:50 -0700)
committerAndrew Pinski <apinski@marvell.com>
Mon, 8 May 2023 07:36:19 +0000 (00:36 -0700)
After adding diamond shaped bb support to factor_out_conditional_conversion,
we can get a case where we have two conversions that needs factored out
and then would have another phiopt happen.
An example is:
```
static inline unsigned long long g(int t)
{
  unsigned t1 = t;
  return t1;
}
unsigned long long f(int c, int d, int e)
{
  unsigned long long t;
  if (c > d)
    t = g(c);
  else
    t = g(d);
  return t;
}
```
In this case we should get a MAX_EXPR in phiopt1 with two casts.
Before this patch, we would just factor out the outer cast and then
wait till phiopt2 to factor out the inner cast.

OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions.

gcc/ChangeLog:

* tree-ssa-phiopt.cc (pass_phiopt::execute): Loop
over factor_out_conditional_conversion.

gcc/testsuite/ChangeLog:

* gcc.dg/tree-ssa/minmax-17.c: New test.

gcc/testsuite/gcc.dg/tree-ssa/minmax-17.c [new file with mode: 0644]
gcc/tree-ssa-phiopt.cc

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/minmax-17.c b/gcc/testsuite/gcc.dg/tree-ssa/minmax-17.c
new file mode 100644 (file)
index 0000000..bd737e6
--- /dev/null
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-phiopt1-details" } */
+
+static inline unsigned long long g(int t)
+{
+  unsigned t1 = t;
+  return t1;
+}
+unsigned long long test_max(int c, int d, int e)
+{
+  unsigned long long t;
+  if (c > d)
+    t = g(c);
+  else
+    t = g(d);
+  return t;
+}
+
+/* We should figure out that test_max has an MAX_EXPR in it. */
+/* { dg-final { scan-tree-dump " = MAX_EXPR" "phiopt1"} } */
+/* { dg-final { scan-tree-dump-times "changed to factor conversion out from" 2 "phiopt1"} } */
index 41fea78dc8defebe3995bfc6b95264ce4e57dfec..7fe088b13ff25fbb41bc6e22eb7c3fc45f8f6c98 100644 (file)
@@ -4085,20 +4085,23 @@ pass_phiopt::execute (function *)
          node.  */
       gcc_assert (arg0 != NULL_TREE && arg1 != NULL_TREE);
 
-      gphi *newphi;
       if (single_pred_p (bb1)
-         && EDGE_COUNT (merge->preds) == 2
-         && (newphi = factor_out_conditional_conversion (e1, e2, phi,
-                                                         arg0, arg1,
-                                                         cond_stmt)))
+         && EDGE_COUNT (merge->preds) == 2)
        {
-         phi = newphi;
-         /* factor_out_conditional_conversion may create a new PHI in
-            BB2 and eliminate an existing PHI in BB2.  Recompute values
-            that may be affected by that change.  */
-         arg0 = gimple_phi_arg_def (phi, e1->dest_idx);
-         arg1 = gimple_phi_arg_def (phi, e2->dest_idx);
-         gcc_assert (arg0 != NULL_TREE && arg1 != NULL_TREE);
+         gphi *newphi = phi;
+         while (newphi)
+           {
+             phi = newphi;
+             /* factor_out_conditional_conversion may create a new PHI in
+                BB2 and eliminate an existing PHI in BB2.  Recompute values
+                that may be affected by that change.  */
+             arg0 = gimple_phi_arg_def (phi, e1->dest_idx);
+             arg1 = gimple_phi_arg_def (phi, e2->dest_idx);
+             gcc_assert (arg0 != NULL_TREE && arg1 != NULL_TREE);
+             newphi = factor_out_conditional_conversion (e1, e2, phi,
+                                                         arg0, arg1,
+                                                         cond_stmt);
+           }
        }
 
       /* Do the replacement of conditional if it can be done.  */