[patch, vectorizer] Fix bug in double reduction detection.

Ira Rosen IRAR@il.ibm.com
Mon Jul 13 13:12:00 GMT 2009


Hi,

The patch http://gcc.gnu.org/ml/gcc-patches/2009-07/msg00672.html caused an
ICE in 416.gamess in SPEC 2006
(http://gcc.gnu.org/ml/gcc-patches/2009-07/msg00707.html).
The bug is in double reduction detection checks: a statement outside the
vectorized loop scope was accessed. The attached patch improves those
checks to make sure they access only relevant statements.

Bootstrapped and tested on x86_64--suse-linux.
Committed.

Ira

ChangeLog:

      * tree-vect-loop.c (get_initial_def_for_reduction): Ensure that the
      checks access only relevant statements.
      (vectorizable_reduction): Likewise.

testsuite/ChangeLog:

      * gfortran.dg/vect/vect-6.f: New test.

Index: testsuite/gfortran.dg/vect/vect-6.f
===================================================================
--- testsuite/gfortran.dg/vect/vect-6.f (revision 0)
+++ testsuite/gfortran.dg/vect/vect-6.f (revision 0)
@@ -0,0 +1,25 @@
+! { dg-do compile }
+
+      SUBROUTINE PROPAGATE(ICI1,ICI2,I,J,J1,ELEM,NHSO,HSO
+     *                    ,MULST,IROOTS)
+      IMPLICIT DOUBLE PRECISION(A-H,O-Z)
+      COMPLEX*16 HSO,ELEM
+      DIMENSION HSO(NHSO,NHSO),MULST(*),IROOTS(*)
+      ISHIFT=MULST(ICI1)*(I-1)+1
+      JSHIFT=MULST(ICI2)*(J-1)+1
+      DO 200 ICI=1,ICI1-1
+         ISHIFT=ISHIFT+MULST(ICI)*IROOTS(ICI)
+  200 CONTINUE
+      DO 220 ICI=1,ICI2-1
+         JSHIFT=JSHIFT+MULST(ICI)*IROOTS(ICI)
+  220 CONTINUE
+         DO 150 MSS=MS,-MS,-2
+           IND1=ISHIFT+K
+           IND2=JSHIFT+K
+           HSO(IND1,IND2)=ELEM
+           HSO(IND2,IND1)=DCONJG(ELEM)
+  150    CONTINUE
+      END
+
+! { dg-final { cleanup-tree-dump "vect" } }
+
Index: tree-vect-loop.c
===================================================================
--- tree-vect-loop.c    (revision 149571)
+++ tree-vect-loop.c    (working copy)
@@ -2632,6 +2632,7 @@ get_initial_def_for_reduction (gimple st
   tree init_value;
   REAL_VALUE_TYPE real_init_val = dconst0;
   int int_init_val = 0;
+  gimple def_stmt = NULL;

   gcc_assert (vectype);
   nunits = TYPE_VECTOR_SUBPARTS (vectype);
@@ -2647,9 +2648,13 @@ get_initial_def_for_reduction (gimple st
   /* In case of double reduction we only create a vector variable to be
put
      in the reduction phi node. The actual statement creation is done in
      vect_create_epilog_for_reduction.  */
-  if (TREE_CODE (init_val) == SSA_NAME
-      && vinfo_for_stmt (SSA_NAME_DEF_STMT (init_val))
-      && STMT_VINFO_DEF_TYPE (vinfo_for_stmt (SSA_NAME_DEF_STMT
(init_val)))
+  if (adjustment_def && nested_in_vect_loop
+      && TREE_CODE (init_val) == SSA_NAME
+      && (def_stmt = SSA_NAME_DEF_STMT (init_val))
+      && gimple_code (def_stmt) == GIMPLE_PHI
+      && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt))
+      && vinfo_for_stmt (def_stmt)
+      && STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt))
           == vect_double_reduction_def)
     {
       *adjustment_def = NULL;
@@ -3418,11 +3423,13 @@ vectorizable_reduction (gimple stmt, gim
   int reduc_index = 2;
   bool double_reduc = false, dummy;
   basic_block def_bb;
-  struct loop * def_stmt_loop;
+  struct loop * def_stmt_loop, *outer_loop = NULL;
   tree def_arg;
+  gimple def_arg_stmt;

   if (nested_in_vect_loop_p (loop, stmt))
     {
+      outer_loop = loop;
       loop = loop->inner;
       nested_cycle = true;
     }
@@ -3669,15 +3676,21 @@ vectorizable_reduction (gimple stmt, gim
       epilog_reduc_code = ERROR_MARK;
     }

-  def_bb = gimple_bb (reduc_def_stmt);
-  def_stmt_loop = def_bb->loop_father;
-  def_arg = PHI_ARG_DEF_FROM_EDGE (reduc_def_stmt,
-                                   loop_preheader_edge (def_stmt_loop));
-  if (TREE_CODE (def_arg) == SSA_NAME
-      && vinfo_for_stmt (SSA_NAME_DEF_STMT (def_arg))
-      && STMT_VINFO_DEF_TYPE (vinfo_for_stmt (SSA_NAME_DEF_STMT
(def_arg)))
-          == vect_double_reduction_def)
-    double_reduc = true;
+  if (nested_cycle)
+    {
+      def_bb = gimple_bb (reduc_def_stmt);
+      def_stmt_loop = def_bb->loop_father;
+      def_arg = PHI_ARG_DEF_FROM_EDGE (reduc_def_stmt,
+                                       loop_preheader_edge
(def_stmt_loop));
+      if (TREE_CODE (def_arg) == SSA_NAME
+          && (def_arg_stmt = SSA_NAME_DEF_STMT (def_arg))
+          && gimple_code (def_arg_stmt) == GIMPLE_PHI
+          && flow_bb_inside_loop_p (outer_loop, gimple_bb (def_arg_stmt))
+          && vinfo_for_stmt (def_arg_stmt)
+          && STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_arg_stmt))
+              == vect_double_reduction_def)
+        double_reduc = true;
+    }

   if (double_reduc && ncopies > 1)
     {




More information about the Gcc-patches mailing list