Fix reduc_index==1 handling for COND_REDUCTION (PR91909)
authorRichard Sandiford <richard.sandiford@arm.com>
Fri, 27 Sep 2019 08:21:37 +0000 (08:21 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Fri, 27 Sep 2019 08:21:37 +0000 (08:21 +0000)
The then/else order of the VEC_COND_EXPRs created by
vect_create_epilog_for_reduction meeds to line up with the
main VEC_COND_EXPR.

2019-09-27  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
PR tree-optimization/91909
* tree-vect-loop.c (vect_create_epilog_for_reduction): Take a
reduc_index parameter.  When handling COND_REDUCTION, make sure
that the reduction phi operand is in the correct arm of the
VEC_COND_EXPR.
(vectorizable_reduction): Pass reduc_index to the above.

From-SVN: r276175

gcc/ChangeLog
gcc/tree-vect-loop.c

index 64cc0a95f35d8caddaa63e4020072fe968109796..fe6b333be6f054855ce5d419959b6af0ff7a561a 100644 (file)
@@ -1,3 +1,12 @@
+2019-09-27  Richard Sandiford  <richard.sandiford@arm.com>
+
+       PR tree-optimization/91909
+       * tree-vect-loop.c (vect_create_epilog_for_reduction): Take a
+       reduc_index parameter.  When handling COND_REDUCTION, make sure
+       that the reduction phi operand is in the correct arm of the
+       VEC_COND_EXPR.
+       (vectorizable_reduction): Pass reduc_index to the above.
+
 2019-09-27  Yuliang Wang  <yuliang.wang@arm.com>
 
        * config/aarch64/aarch64-sve2.md (aarch64_sve2_sra<mode>):
index 237d28b3ce3d96e7d9496207e901a85c845a0742..f5df5340e58079596a39104261b30037d3497ab2 100644 (file)
@@ -4235,6 +4235,8 @@ get_initial_defs_for_reduction (slp_tree slp_node,
    INDUC_CODE is the code for epilog reduction if INTEGER_INDUC_COND_REDUCTION.
    NEUTRAL_OP is the value given by neutral_op_for_slp_reduction; it is
      null if this is not an SLP reduction
+   REDUC_INDEX says which rhs operand of the STMT_INFO is the reduction phi
+     (counting from 0)
 
    This function:
    1. Creates the reduction def-use cycles: sets the arguments for 
@@ -4285,7 +4287,7 @@ vect_create_epilog_for_reduction (vec<tree> vect_defs,
                                   bool double_reduc, 
                                  slp_tree slp_node,
                                  slp_instance slp_node_instance,
-                                 tree neutral_op)
+                                 tree neutral_op, int reduc_index)
 {
   tree induc_val = NULL_TREE;
   stmt_vec_info prev_phi_info;
@@ -4469,11 +4471,17 @@ vect_create_epilog_for_reduction (vec<tree> vect_defs,
       tree ccompare = unshare_expr (gimple_assign_rhs1 (vec_stmt));
 
       /* Create a conditional, where the condition is taken from vec_stmt
-        (CCOMPARE), then is the induction index (INDEX_BEFORE_INCR) and
-        else is the phi (NEW_PHI_TREE).  */
-      tree index_cond_expr = build3 (VEC_COND_EXPR, cr_index_vector_type,
-                                    ccompare, indx_before_incr,
-                                    new_phi_tree);
+        (CCOMPARE).  The then and else values mirror the main VEC_COND_EXPR:
+        the reduction phi corresponds to NEW_PHI_TREE and the new values
+        correspond to INDEX_BEFORE_INCR.  */
+      gcc_assert (reduc_index >= 1);
+      tree index_cond_expr;
+      if (reduc_index == 2)
+       index_cond_expr = build3 (VEC_COND_EXPR, cr_index_vector_type,
+                                 ccompare, indx_before_incr, new_phi_tree);
+      else
+       index_cond_expr = build3 (VEC_COND_EXPR, cr_index_vector_type,
+                                 ccompare, new_phi_tree, indx_before_incr);
       induction_index = make_ssa_name (cr_index_vector_type);
       gimple *index_condition = gimple_build_assign (induction_index,
                                                     index_cond_expr);
@@ -7159,7 +7167,7 @@ vectorizable_reduction (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
   vect_create_epilog_for_reduction (vect_defs, stmt_info, reduc_def_phi,
                                    orig_code, epilog_copies, reduc_fn, phis,
                                    double_reduc, slp_node, slp_node_instance,
-                                   neutral_op);
+                                   neutral_op, reduc_index);
 
   return true;
 }