Hi,

The testcase in the PR fails when the vectorizer tries to create a
reduction init statement for a non-reduction use. This patch adds a check
that if operand's def stmt is a double reduction phi node, the use should
be a phi node too.

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

Ira

ChangeLog:

        PR tree-optimization/52091
        * tree-vectorizer.h (vect_is_simple_use): Add an argument.
        (vect_is_simple_use_1): Likewise.
        * tree-vect-loop.c (vectorizable_reduction): Update calls
        to vect_is_simple_use_1 and vect_is_simple_use.
        (vectorizable_live_operation): Likewise.
        * tree-vect-patterns.c (widened_name_p,
        vect_recog_vector_vector_shift_pattern, check_bool_pattern):
        Likewise.
        * tree-vect-stmts.c (process_use, vect_get_vec_def_for_operand,
        vectorizable_call, vectorizable_conversion,
        vectorizable_assignment, vectorizable_shift,
        vectorizable_operation, vectorizable_store, vectorizable_load):
        Likewise.
        (vect_is_simple_cond): Add an argument, pass it to
        vect_is_simple_use_1.
        (vectorizable_condition): Update calls to vect_is_simple_cond,
        vect_is_simple_use.
        (vect_is_simple_use): Add an argument, the statement in which
        OPERAND is used.  Check that if OPERAND's def stmt is a double
        reduction phi node, the use is a phi node too.
        (vect_is_simple_use_1): Add an argument, pass it to
        vect_is_simple_use.
        * tree-vect-slp.c (vect_get_and_check_slp_defs): Update a call
        to vect_is_simple_use.

testsuite/ChangeLog:

        PR tree-optimization/52091
        * gcc.dg/vect/pr52091.c: New test.

(See attached file: patch.txt)
Index: ChangeLog
===================================================================
--- ChangeLog   (revision 183901)
+++ ChangeLog   (working copy)
@@ -1,3 +1,31 @@
+2012-02-05  Ira Rosen  <i...@il.ibm.com>
+
+       PR tree-optimization/52091
+       * tree-vectorizer.h (vect_is_simple_use): Add an argument.
+       (vect_is_simple_use_1): Likewise.
+       * tree-vect-loop.c (vectorizable_reduction): Update calls
+       to vect_is_simple_use_1 and vect_is_simple_use.
+       (vectorizable_live_operation): Likewise.
+       * tree-vect-patterns.c (widened_name_p,
+       vect_recog_vector_vector_shift_pattern, check_bool_pattern):
+       Likewise.
+       * tree-vect-stmts.c (process_use, vect_get_vec_def_for_operand,
+       vectorizable_call, vectorizable_conversion,
+       vectorizable_assignment, vectorizable_shift,
+       vectorizable_operation, vectorizable_store, vectorizable_load):
+       Likewise.
+       (vect_is_simple_cond): Add an argument, pass it to
+       vect_is_simple_use_1.
+       (vectorizable_condition): Update calls to vect_is_simple_cond,
+       vect_is_simple_use.
+       (vect_is_simple_use): Add an argument, the statement in which
+       OPERAND is used.  Check that if OPERAND's def stmt is a double
+       reduction phi node, the use is a phi node too.
+       (vect_is_simple_use_1): Add an argument, pass it to
+       vect_is_simple_use.
+       * tree-vect-slp.c (vect_get_and_check_slp_defs): Update a call
+       to vect_is_simple_use.
+
 2012-02-04  Jakub Jelinek  <ja...@redhat.com>
 
        PR rtl-optimization/52095
Index: testsuite/gcc.dg/vect/pr52091.c
===================================================================
--- testsuite/gcc.dg/vect/pr52091.c     (revision 0)
+++ testsuite/gcc.dg/vect/pr52091.c     (revision 0)
@@ -0,0 +1,31 @@
+/* { dg-require-effective-target vect_int } */
+
+/* PR tree-optimization/52091 */
+
+int b, c, d, f;
+unsigned h;
+extern void abort (void);
+
+int
+main ()
+{
+  d = -1;
+  h = 65;
+  asm volatile ("" : : : "memory");
+  for (f = 0; f < 4; f++)
+    {
+      h &= (unsigned short) d;
+      for (b = 0; b <= 1; b++)
+    {
+      c = 0;
+      d &= 1;
+    }
+    }
+  asm volatile ("" : : : "memory");
+  if (b != 2 || c != 0 || d != 1 || f != 4 || h != 1)
+    abort ();
+  return 0;
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
+
Index: testsuite/ChangeLog
===================================================================
--- testsuite/ChangeLog (revision 183901)
+++ testsuite/ChangeLog (working copy)
@@ -1,3 +1,8 @@
+2012-02-05  Ira Rosen  <i...@il.ibm.com>
+
+       PR tree-optimization/52091
+       * gcc.dg/vect/pr52091.c: New test.
+
 2012-02-04  Jakub Jelinek  <ja...@redhat.com>
 
        PR rtl-optimization/52113
Index: tree-vectorizer.h
===================================================================
--- tree-vectorizer.h   (revision 183901)
+++ tree-vectorizer.h   (working copy)
@@ -1,5 +1,5 @@
 /* Vectorizer
-   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
    Free Software Foundation, Inc.
    Contributed by Dorit Naishlos <do...@il.ibm.com>
 
@@ -808,9 +808,11 @@ extern bool vect_can_advance_ivs_p (loop_vec_info)
 extern unsigned int current_vector_size;
 extern tree get_vectype_for_scalar_type (tree);
 extern tree get_same_sized_vectype (tree, tree);
-extern bool vect_is_simple_use (tree, loop_vec_info, bb_vec_info, gimple *,
+extern bool vect_is_simple_use (tree, gimple, loop_vec_info,
+                               bb_vec_info, gimple *,
                                 tree *,  enum vect_def_type *);
-extern bool vect_is_simple_use_1 (tree, loop_vec_info, bb_vec_info, gimple *,
+extern bool vect_is_simple_use_1 (tree, gimple, loop_vec_info,
+                                 bb_vec_info, gimple *,
                                  tree *,  enum vect_def_type *, tree *);
 extern bool supportable_widening_operation (enum tree_code, gimple, tree, tree,
                                             tree *, tree *, enum tree_code *,
Index: tree-vect-loop.c
===================================================================
--- tree-vect-loop.c    (revision 183901)
+++ tree-vect-loop.c    (working copy)
@@ -1,5 +1,5 @@
 /* Loop Vectorization
-   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
    Free Software Foundation, Inc.
    Contributed by Dorit Naishlos <do...@il.ibm.com> and
    Ira Rosen <i...@il.ibm.com>
@@ -4486,7 +4486,7 @@ vectorizable_reduction (gimple stmt, gimple_stmt_i
       if (i == 0 && code == COND_EXPR)
         continue;
 
-      is_simple_use = vect_is_simple_use_1 (ops[i], loop_vinfo, NULL,
+      is_simple_use = vect_is_simple_use_1 (ops[i], stmt, loop_vinfo, NULL,
                                            &def_stmt, &def, &dt, &tem);
       if (!vectype_in)
        vectype_in = tem;
@@ -4507,8 +4507,8 @@ vectorizable_reduction (gimple stmt, gimple_stmt_i
         }
     }
 
-  is_simple_use = vect_is_simple_use_1 (ops[i], loop_vinfo, NULL, &def_stmt,
-                                       &def, &dt, &tem);
+  is_simple_use = vect_is_simple_use_1 (ops[i], stmt, loop_vinfo, NULL,
+                                       &def_stmt, &def, &dt, &tem);
   if (!vectype_in)
     vectype_in = tem;
   gcc_assert (is_simple_use);
@@ -4864,14 +4864,14 @@ vectorizable_reduction (gimple stmt, gimple_stmt_i
               gimple dummy_stmt;
               tree dummy;
 
-              vect_is_simple_use (ops[!reduc_index], loop_vinfo, NULL,
+              vect_is_simple_use (ops[!reduc_index], stmt, loop_vinfo, NULL,
                                   &dummy_stmt, &dummy, &dt);
               loop_vec_def0 = vect_get_vec_def_for_stmt_copy (dt,
                                                               loop_vec_def0);
               VEC_replace (tree, vec_oprnds0, 0, loop_vec_def0);
               if (op_type == ternary_op)
                 {
-                  vect_is_simple_use (op1, loop_vinfo, NULL, &dummy_stmt,
+                  vect_is_simple_use (op1, stmt, loop_vinfo, NULL, &dummy_stmt,
                                       &dummy, &dt);
                   loop_vec_def1 = vect_get_vec_def_for_stmt_copy (dt,
                                                                 loop_vec_def1);
@@ -5103,7 +5103,8 @@ vectorizable_live_operation (gimple stmt,
       else
        op = gimple_op (stmt, i + 1);
       if (op
-          && !vect_is_simple_use (op, loop_vinfo, NULL, &def_stmt, &def, &dt))
+          && !vect_is_simple_use (op, stmt, loop_vinfo, NULL, &def_stmt, &def,
+                                 &dt))
         {
           if (vect_print_dump_info (REPORT_DETAILS))
             fprintf (vect_dump, "use not simple.");
Index: tree-vect-patterns.c
===================================================================
--- tree-vect-patterns.c        (revision 183901)
+++ tree-vect-patterns.c        (working copy)
@@ -109,7 +109,8 @@ widened_name_p (tree name, gimple use_stmt, tree *
   stmt_vinfo = vinfo_for_stmt (use_stmt);
   loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
 
-  if (!vect_is_simple_use (name, loop_vinfo, NULL, def_stmt, &def, &dt))
+  if (!vect_is_simple_use (name, use_stmt, loop_vinfo, NULL, def_stmt, &def,
+                          &dt))
     return false;
 
   if (dt != vect_internal_def
@@ -133,8 +134,8 @@ widened_name_p (tree name, gimple use_stmt, tree *
       || (TYPE_PRECISION (type) < (TYPE_PRECISION (*half_type) * 2)))
     return false;
 
-  if (!vect_is_simple_use (oprnd0, loop_vinfo, NULL, &dummy_gimple, &dummy,
-                           &dt))
+  if (!vect_is_simple_use (oprnd0, *def_stmt, loop_vinfo,
+                          NULL, &dummy_gimple, &dummy, &dt))
     return false;
 
   return true;
@@ -1550,7 +1551,8 @@ vect_recog_vector_vector_shift_pattern (VEC (gimpl
         != TYPE_PRECISION (TREE_TYPE (oprnd0)))
     return NULL;
 
-  if (!vect_is_simple_use (oprnd1, loop_vinfo, NULL, &def_stmt, &def, &dt))
+  if (!vect_is_simple_use (oprnd1, last_stmt, loop_vinfo, NULL, &def_stmt,
+                          &def, &dt))
     return NULL;
 
   if (dt != vect_internal_def)
@@ -1926,7 +1928,7 @@ check_bool_pattern (tree var, loop_vec_info loop_v
   tree def, rhs1;
   enum tree_code rhs_code;
 
-  if (!vect_is_simple_use (var, loop_vinfo, NULL, &def_stmt, &def, &dt))
+  if (!vect_is_simple_use (var, NULL, loop_vinfo, NULL, &def_stmt, &def, &dt))
     return false;
 
   if (dt != vect_internal_def)
Index: tree-vect-stmts.c
===================================================================
--- tree-vect-stmts.c   (revision 183901)
+++ tree-vect-stmts.c   (working copy)
@@ -374,7 +374,7 @@ process_use (gimple stmt, tree use, loop_vec_info
   if (!force && !exist_non_indexing_operands_for_use_p (use, stmt))
      return true;
 
-  if (!vect_is_simple_use (use, loop_vinfo, NULL, &def_stmt, &def, &dt))
+  if (!vect_is_simple_use (use, stmt, loop_vinfo, NULL, &def_stmt, &def, &dt))
     {
       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
         fprintf (vect_dump, "not vectorized: unsupported use in stmt.");
@@ -1193,8 +1193,8 @@ vect_get_vec_def_for_operand (tree op, gimple stmt
       print_generic_expr (vect_dump, op, TDF_SLIM);
     }
 
-  is_simple_use = vect_is_simple_use (op, loop_vinfo, NULL, &def_stmt, &def,
-                                      &dt);
+  is_simple_use = vect_is_simple_use (op, stmt, loop_vinfo, NULL,
+                                     &def_stmt, &def, &dt);
   gcc_assert (is_simple_use);
   if (vect_print_dump_info (REPORT_DETAILS))
     {
@@ -1596,7 +1596,7 @@ vectorizable_call (gimple stmt, gimple_stmt_iterat
       if (!rhs_type)
        rhs_type = TREE_TYPE (op);
 
-      if (!vect_is_simple_use_1 (op, loop_vinfo, bb_vinfo,
+      if (!vect_is_simple_use_1 (op, stmt, loop_vinfo, bb_vinfo,
                                 &def_stmt, &def, &dt[i], &opvectype))
        {
          if (vect_print_dump_info (REPORT_DETAILS))
@@ -2208,7 +2208,7 @@ vectorizable_conversion (gimple stmt, gimple_stmt_
     }
 
   /* Check the operands of the operation.  */
-  if (!vect_is_simple_use_1 (op0, loop_vinfo, bb_vinfo,
+  if (!vect_is_simple_use_1 (op0, stmt, loop_vinfo, bb_vinfo,
                             &def_stmt, &def, &dt[0], &vectype_in))
     {
       if (vect_print_dump_info (REPORT_DETAILS))
@@ -2224,11 +2224,11 @@ vectorizable_conversion (gimple stmt, gimple_stmt_
       /* For WIDEN_MULT_EXPR, if OP0 is a constant, use the type of
         OP1.  */
       if (CONSTANT_CLASS_P (op0))
-       ok = vect_is_simple_use_1 (op1, loop_vinfo, NULL,
+       ok = vect_is_simple_use_1 (op1, stmt, loop_vinfo, NULL,
                                   &def_stmt, &def, &dt[1], &vectype_in);
       else
-       ok = vect_is_simple_use (op1, loop_vinfo, NULL, &def_stmt, &def,
-                                &dt[1]);
+       ok = vect_is_simple_use (op1, stmt, loop_vinfo, NULL, &def_stmt,
+                                &def, &dt[1]);
 
       if (!ok)
        {
@@ -2757,7 +2757,7 @@ vectorizable_assignment (gimple stmt, gimple_stmt_
   if (code == VIEW_CONVERT_EXPR)
     op = TREE_OPERAND (op, 0);
 
-  if (!vect_is_simple_use_1 (op, loop_vinfo, bb_vinfo,
+  if (!vect_is_simple_use_1 (op, stmt, loop_vinfo, bb_vinfo,
                             &def_stmt, &def, &dt[0], &vectype_in))
     {
       if (vect_print_dump_info (REPORT_DETAILS))
@@ -2957,7 +2957,7 @@ vectorizable_shift (gimple stmt, gimple_stmt_itera
     }
 
   op0 = gimple_assign_rhs1 (stmt);
-  if (!vect_is_simple_use_1 (op0, loop_vinfo, bb_vinfo,
+  if (!vect_is_simple_use_1 (op0, stmt, loop_vinfo, bb_vinfo,
                              &def_stmt, &def, &dt[0], &vectype))
     {
       if (vect_print_dump_info (REPORT_DETAILS))
@@ -2987,8 +2987,8 @@ vectorizable_shift (gimple stmt, gimple_stmt_itera
     return false;
 
   op1 = gimple_assign_rhs2 (stmt);
-  if (!vect_is_simple_use_1 (op1, loop_vinfo, bb_vinfo, &def_stmt, &def,
-                            &dt[1], &op1_vectype))
+  if (!vect_is_simple_use_1 (op1, stmt, loop_vinfo, bb_vinfo, &def_stmt,
+                            &def, &dt[1], &op1_vectype))
     {
       if (vect_print_dump_info (REPORT_DETAILS))
         fprintf (vect_dump, "use not simple.");
@@ -3334,7 +3334,7 @@ vectorizable_operation (gimple stmt, gimple_stmt_i
     }
 
   op0 = gimple_assign_rhs1 (stmt);
-  if (!vect_is_simple_use_1 (op0, loop_vinfo, bb_vinfo,
+  if (!vect_is_simple_use_1 (op0, stmt, loop_vinfo, bb_vinfo,
                             &def_stmt, &def, &dt[0], &vectype))
     {
       if (vect_print_dump_info (REPORT_DETAILS))
@@ -3366,8 +3366,8 @@ vectorizable_operation (gimple stmt, gimple_stmt_i
   if (op_type == binary_op || op_type == ternary_op)
     {
       op1 = gimple_assign_rhs2 (stmt);
-      if (!vect_is_simple_use (op1, loop_vinfo, bb_vinfo, &def_stmt, &def,
-                               &dt[1]))
+      if (!vect_is_simple_use (op1, stmt, loop_vinfo, bb_vinfo, &def_stmt,
+                              &def, &dt[1]))
        {
          if (vect_print_dump_info (REPORT_DETAILS))
            fprintf (vect_dump, "use not simple.");
@@ -3377,8 +3377,8 @@ vectorizable_operation (gimple stmt, gimple_stmt_i
   if (op_type == ternary_op)
     {
       op2 = gimple_assign_rhs3 (stmt);
-      if (!vect_is_simple_use (op2, loop_vinfo, bb_vinfo, &def_stmt, &def,
-                               &dt[2]))
+      if (!vect_is_simple_use (op2, stmt, loop_vinfo, bb_vinfo, &def_stmt,
+                              &def, &dt[2]))
        {
          if (vect_print_dump_info (REPORT_DETAILS))
            fprintf (vect_dump, "use not simple.");
@@ -3684,7 +3684,8 @@ vectorizable_store (gimple stmt, gimple_stmt_itera
 
   gcc_assert (gimple_assign_single_p (stmt));
   op = gimple_assign_rhs1 (stmt);
-  if (!vect_is_simple_use (op, loop_vinfo, bb_vinfo, &def_stmt, &def, &dt))
+  if (!vect_is_simple_use (op, stmt, loop_vinfo, bb_vinfo, &def_stmt,
+                          &def, &dt))
     {
       if (vect_print_dump_info (REPORT_DETAILS))
         fprintf (vect_dump, "use not simple.");
@@ -3731,8 +3732,8 @@ vectorizable_store (gimple stmt, gimple_stmt_itera
             {
              gcc_assert (gimple_assign_single_p (next_stmt));
              op = gimple_assign_rhs1 (next_stmt);
-              if (!vect_is_simple_use (op, loop_vinfo, bb_vinfo, &def_stmt,
-                                       &def, &dt))
+              if (!vect_is_simple_use (op, next_stmt, loop_vinfo, bb_vinfo,
+                                      &def_stmt, &def, &dt))
                 {
                   if (vect_print_dump_info (REPORT_DETAILS))
                     fprintf (vect_dump, "use not simple.");
@@ -3917,8 +3918,8 @@ vectorizable_store (gimple stmt, gimple_stmt_itera
          for (i = 0; i < group_size; i++)
            {
              op = VEC_index (tree, oprnds, i);
-             vect_is_simple_use (op, loop_vinfo, bb_vinfo, &def_stmt, &def,
-                                 &dt);
+             vect_is_simple_use (op, NULL, loop_vinfo, bb_vinfo, &def_stmt,
+                                 &def, &dt);
              vec_oprnd = vect_get_vec_def_for_stmt_copy (dt, op);
              VEC_replace(tree, dr_chain, i, vec_oprnd);
              VEC_replace(tree, oprnds, i, vec_oprnd);
@@ -4279,7 +4280,7 @@ vectorizable_load (gimple stmt, gimple_stmt_iterat
       gather_decl = vect_check_gather (stmt, loop_vinfo, &gather_base,
                                       &gather_off, &gather_scale);
       gcc_assert (gather_decl);
-      if (!vect_is_simple_use_1 (gather_off, loop_vinfo, bb_vinfo,
+      if (!vect_is_simple_use_1 (gather_off, NULL, loop_vinfo, bb_vinfo,
                                 &def_stmt, &def, &gather_dt,
                                 &gather_off_vectype))
        {
@@ -4914,8 +4915,8 @@ vectorizable_load (gimple stmt, gimple_stmt_iterat
    condition operands are supportable using vec_is_simple_use.  */
 
 static bool
-vect_is_simple_cond (tree cond, loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
-                    tree *comp_vectype)
+vect_is_simple_cond (tree cond, gimple stmt, loop_vec_info loop_vinfo,
+                    bb_vec_info bb_vinfo, tree *comp_vectype)
 {
   tree lhs, rhs;
   tree def;
@@ -4931,8 +4932,8 @@ static bool
   if (TREE_CODE (lhs) == SSA_NAME)
     {
       gimple lhs_def_stmt = SSA_NAME_DEF_STMT (lhs);
-      if (!vect_is_simple_use_1 (lhs, loop_vinfo, bb_vinfo, &lhs_def_stmt, 
&def,
-                                &dt, &vectype1))
+      if (!vect_is_simple_use_1 (lhs, stmt, loop_vinfo, bb_vinfo,
+                                &lhs_def_stmt, &def, &dt, &vectype1))
        return false;
     }
   else if (TREE_CODE (lhs) != INTEGER_CST && TREE_CODE (lhs) != REAL_CST
@@ -4942,8 +4943,8 @@ static bool
   if (TREE_CODE (rhs) == SSA_NAME)
     {
       gimple rhs_def_stmt = SSA_NAME_DEF_STMT (rhs);
-      if (!vect_is_simple_use_1 (rhs, loop_vinfo, bb_vinfo, &rhs_def_stmt, 
&def,
-                                &dt, &vectype2))
+      if (!vect_is_simple_use_1 (rhs, stmt, loop_vinfo, bb_vinfo,
+                                &rhs_def_stmt, &def, &dt, &vectype2))
        return false;
     }
   else if (TREE_CODE (rhs) != INTEGER_CST && TREE_CODE (rhs) != REAL_CST
@@ -5035,14 +5036,15 @@ vectorizable_condition (gimple stmt, gimple_stmt_i
   then_clause = gimple_assign_rhs2 (stmt);
   else_clause = gimple_assign_rhs3 (stmt);
 
-  if (!vect_is_simple_cond (cond_expr, loop_vinfo, bb_vinfo, &comp_vectype)
+  if (!vect_is_simple_cond (cond_expr, stmt, loop_vinfo, bb_vinfo,
+                           &comp_vectype)
       || !comp_vectype)
     return false;
 
   if (TREE_CODE (then_clause) == SSA_NAME)
     {
       gimple then_def_stmt = SSA_NAME_DEF_STMT (then_clause);
-      if (!vect_is_simple_use (then_clause, loop_vinfo, bb_vinfo,
+      if (!vect_is_simple_use (then_clause, stmt, loop_vinfo, bb_vinfo,
                               &then_def_stmt, &def, &dt))
        return false;
     }
@@ -5054,7 +5056,7 @@ vectorizable_condition (gimple stmt, gimple_stmt_i
   if (TREE_CODE (else_clause) == SSA_NAME)
     {
       gimple else_def_stmt = SSA_NAME_DEF_STMT (else_clause);
-      if (!vect_is_simple_use (else_clause, loop_vinfo, bb_vinfo,
+      if (!vect_is_simple_use (else_clause, stmt, loop_vinfo, bb_vinfo,
                               &else_def_stmt, &def, &dt))
        return false;
     }
@@ -5114,21 +5116,21 @@ vectorizable_condition (gimple stmt, gimple_stmt_i
              vec_cond_lhs =
              vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 0),
                                            stmt, NULL);
-             vect_is_simple_use (TREE_OPERAND (cond_expr, 0), loop_vinfo,
-                             NULL, &gtemp, &def, &dts[0]);
+             vect_is_simple_use (TREE_OPERAND (cond_expr, 0), stmt,
+                                 loop_vinfo, NULL, &gtemp, &def, &dts[0]);
 
              vec_cond_rhs =
                vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 1),
                                                stmt, NULL);
-             vect_is_simple_use (TREE_OPERAND (cond_expr, 1), loop_vinfo,
-                                       NULL, &gtemp, &def, &dts[1]);
+             vect_is_simple_use (TREE_OPERAND (cond_expr, 1), stmt,
+                                 loop_vinfo, NULL, &gtemp, &def, &dts[1]);
              if (reduc_index == 1)
                vec_then_clause = reduc_def;
              else
                {
                  vec_then_clause = vect_get_vec_def_for_operand (then_clause,
                                                              stmt, NULL);
-                 vect_is_simple_use (then_clause, loop_vinfo,
+                 vect_is_simple_use (then_clause, stmt, loop_vinfo,
                                          NULL, &gtemp, &def, &dts[2]);
                }
              if (reduc_index == 2)
@@ -5137,7 +5139,7 @@ vectorizable_condition (gimple stmt, gimple_stmt_i
                {
                  vec_else_clause = vect_get_vec_def_for_operand (else_clause,
                                                              stmt, NULL);
-                 vect_is_simple_use (else_clause, loop_vinfo,
+                 vect_is_simple_use (else_clause, stmt, loop_vinfo,
                                  NULL, &gtemp, &def, &dts[3]);
                }
            }
@@ -5831,7 +5833,7 @@ get_same_sized_vectype (tree scalar_type, tree vec
    Input:
    LOOP_VINFO - the vect info of the loop that is being vectorized.
    BB_VINFO - the vect info of the basic block that is being vectorized.
-   OPERAND - operand of a stmt in the loop or bb.
+   OPERAND - operand of STMT in the loop or bb.
    DEF - the defining stmt in case OPERAND is an SSA_NAME.
 
    Returns whether a stmt with OPERAND can be vectorized.
@@ -5843,7 +5845,7 @@ get_same_sized_vectype (tree scalar_type, tree vec
    For now, operands defined outside the basic block are not supported.  */
 
 bool
-vect_is_simple_use (tree operand, loop_vec_info loop_vinfo,
+vect_is_simple_use (tree operand, gimple stmt, loop_vec_info loop_vinfo,
                     bb_vec_info bb_vinfo, gimple *def_stmt,
                    tree *def, enum vect_def_type *dt)
 {
@@ -5925,7 +5927,10 @@ bool
       *dt = STMT_VINFO_DEF_TYPE (stmt_vinfo);
     }
 
-  if (*dt == vect_unknown_def_type)
+  if (*dt == vect_unknown_def_type
+      || (stmt
+         && *dt == vect_double_reduction_def
+         && gimple_code (stmt) != GIMPLE_PHI))
     {
       if (vect_print_dump_info (REPORT_DETAILS))
         fprintf (vect_dump, "Unsupported pattern.");
@@ -5969,11 +5974,12 @@ bool
    scalar operand.  */
 
 bool
-vect_is_simple_use_1 (tree operand, loop_vec_info loop_vinfo,
+vect_is_simple_use_1 (tree operand, gimple stmt, loop_vec_info loop_vinfo,
                      bb_vec_info bb_vinfo, gimple *def_stmt,
                      tree *def, enum vect_def_type *dt, tree *vectype)
 {
-  if (!vect_is_simple_use (operand, loop_vinfo, bb_vinfo, def_stmt, def, dt))
+  if (!vect_is_simple_use (operand, stmt, loop_vinfo, bb_vinfo, def_stmt,
+                          def, dt))
     return false;
 
   /* Now get a vector type if the def is internal, otherwise supply
Index: tree-vect-slp.c
===================================================================
--- tree-vect-slp.c     (revision 183901)
+++ tree-vect-slp.c     (working copy)
@@ -233,8 +233,8 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vi
           oprnd = TREE_OPERAND (oprnd, 0);
        }
 
-      if (!vect_is_simple_use (oprnd, loop_vinfo, bb_vinfo, &def_stmt, &def,
-                               &dt)
+      if (!vect_is_simple_use (oprnd, NULL, loop_vinfo, bb_vinfo, &def_stmt,
+                              &def, &dt)
          || (!def_stmt && dt != vect_constant_def))
        {
          if (vect_print_dump_info (REPORT_SLP))

Reply via email to