Hi!

On the gcc.dg/autopar/outer-4.c testcase we leak memory, because
vect_analyze_loop_form allocates vinfos for all the stmts in the loop
and when it calls vect_analyze_loop_form on the loop->inner before
the former is destroyed, we overwrite all those vinfo pointers for
stmts inside of the inner loop with newly allocated memory.

The following patch fixes that by making sure vect_analyze_loop_form
for the inner loop is only called after destroy_loop_vec_info
of the outer loop.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2017-02-03  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/79338
        * tree-parloops.c (gather_scalar_reductions): Don't call
        vect_analyze_loop_form for loop->inner before destroying loop's
        loop_vinfo.

--- gcc/tree-parloops.c.jj      2017-02-01 16:25:21.000000000 +0100
+++ gcc/tree-parloops.c 2017-02-03 15:37:13.940564625 +0100
@@ -2513,8 +2513,8 @@ gather_scalar_reductions (loop_p loop, r
 {
   gphi_iterator gsi;
   loop_vec_info simple_loop_info;
-  loop_vec_info simple_inner_loop_info = NULL;
-  bool allow_double_reduc = true;
+  auto_vec<gphi *, 4> double_reduc_phis;
+  auto_vec<gimple *, 4> double_reduc_stmts;
 
   if (!stmt_vec_info_vec.exists ())
     init_stmt_vec_info_vec ();
@@ -2544,43 +2544,55 @@ gather_scalar_reductions (loop_p loop, r
 
       if (double_reduc)
        {
-         if (!allow_double_reduc
-             || loop->inner->inner != NULL)
+         if (loop->inner->inner != NULL)
            continue;
 
-         if (!simple_inner_loop_info)
-           {
-             simple_inner_loop_info = vect_analyze_loop_form (loop->inner);
-             if (!simple_inner_loop_info)
-               {
-                 allow_double_reduc = false;
-                 continue;
-               }
-           }
-
-         use_operand_p use_p;
-         gimple *inner_stmt;
-         bool single_use_p = single_imm_use (res, &use_p, &inner_stmt);
-         gcc_assert (single_use_p);
-         if (gimple_code (inner_stmt) != GIMPLE_PHI)
-           continue;
-         gphi *inner_phi = as_a <gphi *> (inner_stmt);
-         if (simple_iv (loop->inner, loop->inner, PHI_RESULT (inner_phi),
-                        &iv, true))
-           continue;
-
-         gimple *inner_reduc_stmt
-           = vect_force_simple_reduction (simple_inner_loop_info, inner_phi,
-                                          true, &double_reduc, true);
-         gcc_assert (!double_reduc);
-         if (inner_reduc_stmt == NULL)
-           continue;
+         double_reduc_phis.safe_push (phi);
+         double_reduc_stmts.safe_push (reduc_stmt);
+         continue;
        }
 
       build_new_reduction (reduction_list, reduc_stmt, phi);
     }
   destroy_loop_vec_info (simple_loop_info, true);
-  destroy_loop_vec_info (simple_inner_loop_info, true);
+
+  if (!double_reduc_phis.is_empty ())
+    {
+      simple_loop_info = vect_analyze_loop_form (loop->inner);
+      if (simple_loop_info)
+       {
+         gphi *phi;
+         unsigned int i;
+
+         FOR_EACH_VEC_ELT (double_reduc_phis, i, phi)
+           {
+             affine_iv iv;
+             tree res = PHI_RESULT (phi);
+             bool double_reduc;
+
+             use_operand_p use_p;
+             gimple *inner_stmt;
+             bool single_use_p = single_imm_use (res, &use_p, &inner_stmt);
+             gcc_assert (single_use_p);
+             if (gimple_code (inner_stmt) != GIMPLE_PHI)
+               continue;
+             gphi *inner_phi = as_a <gphi *> (inner_stmt);
+             if (simple_iv (loop->inner, loop->inner, PHI_RESULT (inner_phi),
+                            &iv, true))
+               continue;
+
+             gimple *inner_reduc_stmt
+               = vect_force_simple_reduction (simple_loop_info, inner_phi,
+                                              true, &double_reduc, true);
+             gcc_assert (!double_reduc);
+             if (inner_reduc_stmt == NULL)
+               continue;
+
+             build_new_reduction (reduction_list, double_reduc_stmts[i], phi);
+           }
+         destroy_loop_vec_info (simple_loop_info, true);
+       }
+    }
 
  gather_done:
   /* Release the claim on gimple_uid.  */

        Jakub

Reply via email to