When I added the factor operations to ifcvt, I messed how handling of removing
the phi nodes. The fix is we need to remove the phi node that was factored out
as we factored out the operator because otherwise scev can go when it comes
to detecting if the new args are from a reduction.

Also the need to change the interface for is_cond_scalar_reduction as the
phi node that was being passed after the factoring no longer exists so need
to pass the parts that were being used.

        PR tree-optimization/121236

gcc/ChangeLog:

        * tree-if-conv.cc (is_cond_scalar_reduction): Instead of phi argument,
        pass bb and res of the phi.
        (factor_out_operators): Add iterator for the phi. Remove the phi
        if this is the first time. Return if we had removed the phi.
        (predicate_scalar_phi): Add the phi iterator argument.
        Update call to is_cond_scalar_reduction.
        Update call to factor_out_operators and set the return value to true
        when factor_out_operators returns true.
        (predicate_all_scalar_phis): Don't remove the phi if 
predicate_scalar_phi
        already removed it.

gcc/testsuite/ChangeLog:

        * gcc.dg/torture/pr121236-1.c: New test.

Signed-off-by: Andrew Pinski <quic_apin...@quicinc.com>
---
 gcc/testsuite/gcc.dg/torture/pr121236-1.c | 20 ++++++++
 gcc/tree-if-conv.cc                       | 60 +++++++++++++----------
 2 files changed, 55 insertions(+), 25 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr121236-1.c

diff --git a/gcc/testsuite/gcc.dg/torture/pr121236-1.c 
b/gcc/testsuite/gcc.dg/torture/pr121236-1.c
new file mode 100644
index 00000000000..2b397e34078
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr121236-1.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* PR tree-optimization/121236 */
+
+
+unsigned func_26(short *p_27, int gg, int p) {
+  unsigned l_184 = 0;
+  unsigned m = 0;
+  for (int g_59 = 0; g_59 < 10; g_59++)
+    {
+      if (gg)
+       l_184--;
+      else
+       {
+         m |= l_184 |= p;
+         (l_184)--;
+       }
+    }
+ return m;
+}
+
diff --git a/gcc/tree-if-conv.cc b/gcc/tree-if-conv.cc
index ba25c19c50c..a8b800ba09e 100644
--- a/gcc/tree-if-conv.cc
+++ b/gcc/tree-if-conv.cc
@@ -1755,7 +1755,7 @@ strip_nop_cond_scalar_reduction (bool has_nop, tree op)
    EXTENDED is true if PHI has > 2 arguments.  */
 
 static bool
-is_cond_scalar_reduction (gimple *phi, gimple **reduc, tree arg_0, tree arg_1,
+is_cond_scalar_reduction (basic_block bb, tree phi_res, gimple **reduc, tree 
arg_0, tree arg_1,
                          tree *op0, tree *op1, bool extended, bool* has_nop,
                          gimple **nop_reduc)
 {
@@ -1763,7 +1763,6 @@ is_cond_scalar_reduction (gimple *phi, gimple **reduc, 
tree arg_0, tree arg_1,
   gimple *stmt;
   gimple *header_phi = NULL;
   enum tree_code reduction_op;
-  basic_block bb = gimple_bb (phi);
   class loop *loop = bb->loop_father;
   edge latch_e = loop_latch_edge (loop);
   imm_use_iterator imm_iter;
@@ -1791,7 +1790,7 @@ is_cond_scalar_reduction (gimple *phi, gimple **reduc, 
tree arg_0, tree arg_1,
   if (gimple_bb (header_phi) != loop->header)
     return false;
 
-  if (PHI_ARG_DEF_FROM_EDGE (header_phi, latch_e) != PHI_RESULT (phi))
+  if (PHI_ARG_DEF_FROM_EDGE (header_phi, latch_e) != phi_res)
     return false;
 
   if (gimple_code (stmt) != GIMPLE_ASSIGN
@@ -1889,7 +1888,7 @@ is_cond_scalar_reduction (gimple *phi, gimple **reduc, 
tree arg_0, tree arg_1,
            continue;
          if (use_stmt == SSA_NAME_DEF_STMT (r_op1))
            continue;
-         if (use_stmt != phi)
+         if (use_stmt != SSA_NAME_DEF_STMT (phi_res))
            return false;
        }
     }
@@ -2199,8 +2198,8 @@ commutative:
    and *RES to the new values if the factoring happened.
    Loops until all of the factoring is completed.  */
 
-static void
-factor_out_operators (tree *res, gimple_stmt_iterator *gsi,
+static bool
+factor_out_operators (gimple_stmt_iterator *pgsi, tree *res, 
gimple_stmt_iterator *gsi,
                      tree *arg0, tree *arg1, gphi *phi)
 {
   gimple_match_op arg0_op, arg1_op;
@@ -2208,28 +2207,28 @@ factor_out_operators (tree *res, gimple_stmt_iterator 
*gsi,
 
 again:
   if (TREE_CODE (*arg0) != SSA_NAME || TREE_CODE (*arg1) != SSA_NAME)
-    return;
+    return repeated;
 
   if (operand_equal_p (*arg0, *arg1))
-    return;
+    return repeated;
 
   /* If either args have > 1 use, then this transformation actually
      increases the number of expressions evaluated at runtime.  */
   if (repeated
       ? (!has_zero_uses (*arg0) || !has_zero_uses (*arg1))
       : (!has_single_use (*arg0) || !has_single_use (*arg1)))
-    return;
+    return repeated;
 
   gimple *arg0_def_stmt = SSA_NAME_DEF_STMT (*arg0);
   if (!gimple_extract_op (arg0_def_stmt, &arg0_op))
-    return;
+    return repeated;
 
   /* At this point there should be no ssa names occuring in abnormals.  */
   gcc_assert (!arg0_op.operands_occurs_in_abnormal_phi ());
 
   gimple *arg1_def_stmt = SSA_NAME_DEF_STMT (*arg1);
   if (!gimple_extract_op (arg1_def_stmt, &arg1_op))
-    return;
+    return repeated;
 
   /* At this point there should be no ssa names occuring in abnormals.  */
   gcc_assert (!arg1_op.operands_occurs_in_abnormal_phi ());
@@ -2238,15 +2237,15 @@ again:
      or the number operands.  */
   if (arg1_op.code != arg0_op.code
       || arg1_op.num_ops != arg0_op.num_ops)
-    return;
+    return repeated;
 
   tree new_arg0, new_arg1;
   int opnum = find_different_opnum (arg0_op, arg1_op, &new_arg0, &new_arg1);
   if (opnum == -1)
-    return;
+    return repeated;
 
   if (!types_compatible_p (TREE_TYPE (new_arg0), TREE_TYPE (new_arg1)))
-    return;
+    return repeated;
   tree new_res = make_ssa_name (TREE_TYPE (new_arg0), NULL);
 
   /* Create the operation stmt if possible and insert it.  */
@@ -2262,7 +2261,7 @@ again:
   if (!result)
     {
       release_ssa_name (new_res);
-      return;
+      return repeated;
     }
   gsi_insert_seq_before (gsi, seq, GSI_CONTINUE_LINKING);
 
@@ -2277,6 +2276,10 @@ again:
       fprintf (dump_file, ".\n");
     }
 
+  /* Remove the phi and move to the next phi arg if needed. */
+  if (!repeated)
+    remove_phi_node (pgsi, false);
+
   /* Remove the old operation(s) that has single use.  */
   gimple_stmt_iterator gsi_for_def;
 
@@ -2400,8 +2403,9 @@ cmp_arg_entry (const void *p1, const void *p2, void * /* 
data.  */)
    vectorization. */
 
 
-static void
-predicate_scalar_phi (gphi *phi, gimple_stmt_iterator *gsi, bool 
loop_versioned)
+static bool
+predicate_scalar_phi (gimple_stmt_iterator *phi_gsi, gphi *phi,
+                     gimple_stmt_iterator *gsi, bool loop_versioned)
 {
   gimple *new_stmt = NULL, *reduc, *nop_reduc;
   tree rhs, res, arg0, arg1, op0, op1, scev;
@@ -2411,10 +2415,11 @@ predicate_scalar_phi (gphi *phi, gimple_stmt_iterator 
*gsi, bool loop_versioned)
   basic_block bb;
   unsigned int i;
   bool has_nop;
+  bool removed_phi = false;
 
   res = gimple_phi_result (phi);
   if (virtual_operand_p (res))
-    return;
+    return removed_phi;
 
   if ((rhs = degenerate_phi_result (phi))
       || ((scev = analyze_scalar_evolution (gimple_bb (phi)->loop_father,
@@ -2431,7 +2436,7 @@ predicate_scalar_phi (gphi *phi, gimple_stmt_iterator 
*gsi, bool loop_versioned)
       new_stmt = gimple_build_assign (res, rhs);
       gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
       update_stmt (new_stmt);
-      return;
+      return removed_phi;
     }
 
   bb = gimple_bb (phi);
@@ -2477,9 +2482,13 @@ predicate_scalar_phi (gphi *phi, gimple_stmt_iterator 
*gsi, bool loop_versioned)
 
       /* Factor out operand if possible. This can only be done easily
         for PHI with 2 elements.  */
-      factor_out_operators (&res, gsi, &arg0, &arg1, phi);
+      if (factor_out_operators (phi_gsi, &res, gsi, &arg0, &arg1, phi))
+       {
+         phi = nullptr;
+         removed_phi = true;
+       }
 
-      if (is_cond_scalar_reduction (phi, &reduc, arg0, arg1,
+      if (is_cond_scalar_reduction (bb, res, &reduc, arg0, arg1,
                                    &op0, &op1, false, &has_nop,
                                    &nop_reduc))
        {
@@ -2508,7 +2517,7 @@ predicate_scalar_phi (gphi *phi, gimple_stmt_iterator 
*gsi, bool loop_versioned)
          fprintf (dump_file, "new phi replacement stmt\n");
          print_gimple_stmt (dump_file, new_stmt, 0, TDF_SLIM);
        }
-      return;
+      return removed_phi;
     }
 
   /* Create hashmap for PHI node which contain vector of argument indexes
@@ -2576,7 +2585,7 @@ predicate_scalar_phi (gphi *phi, gimple_stmt_iterator 
*gsi, bool loop_versioned)
       /* Gimplify the condition to a valid cond-expr conditonal operand.  */
       cond = force_gimple_operand_gsi (gsi, unshare_expr (cond), true,
                                       NULL_TREE, true, GSI_SAME_STMT);
-      if (!(is_cond_scalar_reduction (phi, &reduc, arg0 , arg1,
+      if (!(is_cond_scalar_reduction (bb, res, &reduc, arg0 , arg1,
                                      &op0, &op1, true, &has_nop, &nop_reduc)))
        rhs = fold_build_cond_expr (TREE_TYPE (res), unshare_expr (cond),
                                    swap ? arg1 : arg0,
@@ -2606,6 +2615,7 @@ predicate_scalar_phi (gphi *phi, gimple_stmt_iterator 
*gsi, bool loop_versioned)
       fprintf (dump_file, "new extended phi replacement stmt\n");
       print_gimple_stmt (dump_file, new_stmt, 0, TDF_SLIM);
     }
+  return removed_phi;
 }
 
 /* Replaces in LOOP all the scalar phi nodes other than those in the
@@ -2642,8 +2652,8 @@ predicate_all_scalar_phis (class loop *loop, bool 
loop_versioned)
            gsi_next (&phi_gsi);
          else
            {
-             predicate_scalar_phi (phi, &gsi, loop_versioned);
-             remove_phi_node (&phi_gsi, false);
+             if (!predicate_scalar_phi (&phi_gsi, phi, &gsi, loop_versioned))
+               remove_phi_node (&phi_gsi, false);
            }
        }
     }
-- 
2.43.0

Reply via email to