re PR tree-optimization/52678 (internal compiler error: in vect_update_ivs_after_vect...
authorRichard Guenther <rguenther@suse.de>
Fri, 23 Mar 2012 11:34:32 +0000 (11:34 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 23 Mar 2012 11:34:32 +0000 (11:34 +0000)
2012-03-23  Richard Guenther  <rguenther@suse.de>

PR tree-optimization/52678
* tree-vectorizer.h (struct _stmt_vec_info): Add
loop_phi_evolution_part member.
(STMT_VINFO_LOOP_PHI_EVOLUTION_PART): New define.
* tree-vect-loop.c (vect_analyze_scalar_cycles_1): Initialize
STMT_VINFO_LOOP_PHI_EVOLUTION_PART.
* tree-vect-loop-manip.c (vect_update_ivs_after_vectorizer):
Use the cached evolution part and the PHI nodes value from
the loop preheader edge instead of re-analyzing the evolution.

* gfortran.dg/pr52678.f: New testcase.

From-SVN: r185734

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/pr52678.f [new file with mode: 0644]
gcc/tree-vect-loop-manip.c
gcc/tree-vect-loop.c
gcc/tree-vectorizer.h

index 45c1bd46b8e1c32e30454393c45777adf8bde798..d1ed37a8953c6033822fa6bc535fd6b90aaf0e22 100644 (file)
@@ -1,3 +1,15 @@
+2012-03-23  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/52678
+       * tree-vectorizer.h (struct _stmt_vec_info): Add
+       loop_phi_evolution_part member.
+       (STMT_VINFO_LOOP_PHI_EVOLUTION_PART): New define.
+       * tree-vect-loop.c (vect_analyze_scalar_cycles_1): Initialize
+       STMT_VINFO_LOOP_PHI_EVOLUTION_PART.
+       * tree-vect-loop-manip.c (vect_update_ivs_after_vectorizer):
+       Use the cached evolution part and the PHI nodes value from
+       the loop preheader edge instead of re-analyzing the evolution.
+
 2012-03-22  Maxim Kuvyrkov  <maxim@codesourcery.com>
 
        * config/mips/mips-tables.opt: Update.
index 549cf5b544e75421ca3b9db09fa4c8ed65813c8d..a6b64242baef8c0e5b3229d3dfe132f2262b0afb 100644 (file)
@@ -1,3 +1,8 @@
+2012-03-23  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/52678
+       * gfortran.dg/pr52678.f: New testcase.
+
 2012-03-23  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/52638
diff --git a/gcc/testsuite/gfortran.dg/pr52678.f b/gcc/testsuite/gfortran.dg/pr52678.f
new file mode 100644 (file)
index 0000000..8d0cd47
--- /dev/null
@@ -0,0 +1,18 @@
+! { dg-do compile }
+! { dg-options "-O -ftree-vectorize" }
+      SUBROUTINE OpenAD_set_ref_state(DRF, RHOFACF, RHOFACC)
+      real(8) DRF(1 : 15)
+      real(8) RHOFACF(1 : 16)
+      real(8) RHOFACC(1 : 15)
+      integer, dimension(:), allocatable :: oad_it
+      integer :: oad_it_ptr
+      INTEGER(8) OpenAD_Symbol_188
+      INTEGER(4) K
+          OpenAD_Symbol_188 = 0
+          DO K = 2, 15, 1
+            RHOFACF(INT(K)) = ((RHOFACC(K) * DRF(K + (-1)) + RHOFACC(K +
+     + (-1)) * DRF(K)) /(DRF(K) + DRF(K + (-1))))
+            OpenAD_Symbol_188 = (INT(OpenAD_Symbol_188) + INT(1))
+          END DO
+          oad_it(oad_it_ptr) = OpenAD_Symbol_188
+      end subroutine OpenAD_set_ref_state
index 8cf18250bf17b252b16f620f9a080362211528b4..499dece1dbf216a98a3a69ddf1833ce6b6e34c32 100644 (file)
@@ -1797,13 +1797,12 @@ vect_update_ivs_after_vectorizer (loop_vec_info loop_vinfo, tree niters,
        !gsi_end_p (gsi) && !gsi_end_p (gsi1);
        gsi_next (&gsi), gsi_next (&gsi1))
     {
-      tree access_fn = NULL;
-      tree evolution_part;
       tree init_expr;
       tree step_expr, off;
       tree type;
       tree var, ni, ni_name;
       gimple_stmt_iterator last_gsi;
+      stmt_vec_info stmt_info;
 
       phi = gsi_stmt (gsi);
       phi1 = gsi_stmt (gsi1);
@@ -1822,45 +1821,34 @@ vect_update_ivs_after_vectorizer (loop_vec_info loop_vinfo, tree niters,
        }
 
       /* Skip reduction phis.  */
-      if (STMT_VINFO_DEF_TYPE (vinfo_for_stmt (phi)) == vect_reduction_def)
+      stmt_info = vinfo_for_stmt (phi);
+      if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_reduction_def)
         {
           if (vect_print_dump_info (REPORT_DETAILS))
             fprintf (vect_dump, "reduc phi. skip.");
           continue;
         }
 
-      access_fn = analyze_scalar_evolution (loop, PHI_RESULT (phi));
-      gcc_assert (access_fn);
-      /* We can end up with an access_fn like
-           (short int) {(short unsigned int) i_49, +, 1}_1
-        for further analysis we need to strip the outer cast but we
-        need to preserve the original type.  */
-      type = TREE_TYPE (access_fn);
-      STRIP_NOPS (access_fn);
-      evolution_part =
-        unshare_expr (evolution_part_in_loop_num (access_fn, loop->num));
-      gcc_assert (evolution_part != NULL_TREE);
+      type = TREE_TYPE (gimple_phi_result (phi));
+      step_expr = STMT_VINFO_LOOP_PHI_EVOLUTION_PART (stmt_info);
+      step_expr = unshare_expr (step_expr);
 
       /* FORNOW: We do not support IVs whose evolution function is a polynomial
          of degree >= 2 or exponential.  */
-      gcc_assert (!tree_is_chrec (evolution_part));
+      gcc_assert (!tree_is_chrec (step_expr));
 
-      step_expr = evolution_part;
-      init_expr = unshare_expr (initial_condition_in_loop_num (access_fn,
-                                                              loop->num));
-      init_expr = fold_convert (type, init_expr);
+      init_expr = PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader_edge (loop));
 
       off = fold_build2 (MULT_EXPR, TREE_TYPE (step_expr),
                         fold_convert (TREE_TYPE (step_expr), niters),
                         step_expr);
-      if (POINTER_TYPE_P (TREE_TYPE (init_expr)))
+      if (POINTER_TYPE_P (type))
        ni = fold_build_pointer_plus (init_expr, off);
       else
-       ni = fold_build2 (PLUS_EXPR, TREE_TYPE (init_expr),
-                         init_expr,
-                         fold_convert (TREE_TYPE (init_expr), off));
+       ni = fold_build2 (PLUS_EXPR, type,
+                         init_expr, fold_convert (type, off));
 
-      var = create_tmp_var (TREE_TYPE (init_expr), "tmp");
+      var = create_tmp_var (type, "tmp");
       add_referenced_var (var);
 
       last_gsi = gsi_last_bb (exit_bb);
index abf131e3c26e89be8f0fed46e588736d90f2c02d..1b4ed883e44110ddf5a8851304995b102d7d4ab0 100644 (file)
@@ -579,6 +579,10 @@ vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop)
          continue;
        }
 
+      STMT_VINFO_LOOP_PHI_EVOLUTION_PART (stmt_vinfo)
+       = evolution_part_in_loop_num (access_fn, loop->num);
+      gcc_assert (STMT_VINFO_LOOP_PHI_EVOLUTION_PART (stmt_vinfo) != NULL_TREE);
+
       if (vect_print_dump_info (REPORT_DETAILS))
        fprintf (vect_dump, "Detected induction.");
       STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_induction_def;
index 14eb201733303f4b5695c7a89d0960fff8086543..5f031b52f2ee585f87eb1be734c3defbb42db026 100644 (file)
@@ -476,6 +476,13 @@ typedef struct _stmt_vec_info {
   tree dr_step;
   tree dr_aligned_to;
 
+  /* For loop PHI nodes, the evolution part of it.  This makes sure
+     this information is still available in vect_update_ivs_after_vectorizer
+     where we may not be able to re-analyze the PHI nodes evolution as
+     peeling for the prologue loop can make it unanalyzable.  The evolution
+     part is still correct though.  */
+  tree loop_phi_evolution_part;
+
   /* Used for various bookkeeping purposes, generally holding a pointer to
      some other stmt S that is in some way "related" to this stmt.
      Current use of this field is:
@@ -572,6 +579,7 @@ typedef struct _stmt_vec_info {
 #define STMT_VINFO_GROUP_SAME_DR_STMT(S)   (S)->same_dr_stmt
 #define STMT_VINFO_GROUP_READ_WRITE_DEPENDENCE(S)  (S)->read_write_dep
 #define STMT_VINFO_STRIDED_ACCESS(S)      ((S)->first_element != NULL && (S)->data_ref_info)
+#define STMT_VINFO_LOOP_PHI_EVOLUTION_PART(S) (S)->loop_phi_evolution_part
 
 #define GROUP_FIRST_ELEMENT(S)          (S)->first_element
 #define GROUP_NEXT_ELEMENT(S)           (S)->next_element