Hi Raghesh,
> diff --git a/gcc/testsuite/gcc.dg/vect/vect-predicated-index-1.c
> b/gcc/testsuite/gcc.dg/vect/vect-predicated-index-1.c
> new file mode 100644
> index 00000000000..c372e06555d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/vect/vect-predicated-index-1.c
> @@ -0,0 +1,23 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target vect_int } */
> +/* { dg-additional-options "-mavx2" { target { i?86-*-* x86_64-*-* } } } */
Does that work for all vect_int targets? I.e. do we recognize the
proper shape? If not, it would be better to add a vect_compress "type"
to the testsuite and just add AVX, SVE, and RVV to it. See
target-supports.exp.
> + tree_code rhs_code = gimple_assign_rhs_code (assign);
> + if (rhs_code != NOP_EXPR
> + && rhs_code != CONVERT_EXPR
> + && rhs_code != VIEW_CONVERT_EXPR
> + && rhs_code != NON_LVALUE_EXPR)
NON_LVALUE_EXPR, where does that come from? :)
> + return false;
> +
> + tree rhs1 = gimple_assign_rhs1 (assign);
> + if (TREE_CODE (rhs1) != SSA_NAME)
> + return false;
> +
> + *cur = rhs1;
> + return true;
> +}
I would prefer vect_look_through_possible_promotion but I guess it
doesn't work for non-single-use cases like ours.
What I just found is strip_conversion. Does that help here? It's not
exported but we could.
> +/* Function vect_analyze_predicated_index_phi.
> +
> + Recognize the conditional-increment induction cycle: a loop-header PHI
> whose
> + back-edge value is the PHI incremented by one under a mask. On success
> + STMT_INFO is annotated with the mask for a follow-up pass that will pair
> + the cycle with a matching IFN_MASK_STORE. An outline of the shape
> recognized
> + here is:
> +
> + # n = PHI <0, n_2>
> + ...
> + n_1 = n + 1;
> + ...
> + n_2 = mask ? n_1 : n; */
> +static bool
> +vect_analyze_predicated_index_phi (class loop *loop, gphi *phi,
> + stmt_vec_info stmt_info)
> +{
> + /* Require a loop-header PHI. */
> + if (gimple_bb (phi) != loop->header)
> + return false;
> +
> + tree pred_phi = PHI_RESULT (phi);
> + /* PHI should be an integer. */
> + if (TREE_CODE (pred_phi) != SSA_NAME
> + || TREE_CODE (TREE_TYPE (pred_phi)) != INTEGER_TYPE)
> + return false;
> +
> + /* Restricting to zero initializatin from preheader for now. TODO: Can be
> + generalized to arbitrary integer starts. */
> + tree pre_init = PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader_edge (loop));
> + if (TREE_CODE (pre_init) != INTEGER_CST || !integer_zerop (pre_init))
> + return false;
> +
> + /* The incoming value for pred-phi must be in the if-converted form.
> + n_2 = mask ? n_1 : n; TODO: This may be generalized later for more
> + patterns. */
> + /* Get the incoming value (n_2) of pred-phi through backedge. */
> + tree pred_phi_back_edge_val
> + = PHI_ARG_DEF_FROM_EDGE (phi, loop_latch_edge (loop));
> + if (TREE_CODE (pred_phi_back_edge_val) != SSA_NAME)
> + return false;
> + /* Check if pred_phi_back_edge_val is a COND_EXPR. */
> + gimple *pred_phi_back_edge_stmt = SSA_NAME_DEF_STMT
> (pred_phi_back_edge_val);
> + if (!pred_phi_back_edge_stmt)
> + return false;
I think this is never NULL.
> + gassign *pred_phi_back_edge_asgn_stmt
> + = dyn_cast <gassign *> (pred_phi_back_edge_stmt);
> + if (!pred_phi_back_edge_asgn_stmt
> + || gimple_assign_rhs_code (pred_phi_back_edge_asgn_stmt) != COND_EXPR)
> + {
> + if (dump_enabled_p ())
> + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
> + "predicated-index PHI: backedge is not COND_EXPR.\n");
> + return false;
> + }
> +
> + /* Check that one of the arms of COND_EXPR is pred-phi (n) and the other is
> + an increment value (n_1 = n + 1). */
> + if (!vect_predicated_index_plus_one (pred_phi,
> pred_phi_back_edge_asgn_stmt))
> + {
> + if (dump_enabled_p ())
> + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
> + "predicated-index PHI: update is not +1.\n");
> + return false;
> + }
I think Richi is not a fan of too many log messages, but I don't mind
these here.
> /* True if this is only suitable for SLP vectorization. */
> bool slp_vect_only_p;
> +
> + /* On a predicated-index PHI (vect_predicated_index_def) the mask under
> which
> + the index is conditionally incremented, as recognized by
> + vect_analyze_predicated_index_phi. Reserved for a follow-up pass that
> + pairs the cycle with a matching masked store. */
> + tree predicated_index_mask;
> };
>
> /* Information about a gather/scatter call. */
> @@ -1763,6 +1770,7 @@ struct gather_scatter_info {
> #define STMT_VINFO_REDUC_DEF(S) (S)->reduc_def
> #define STMT_VINFO_SLP_VECT_ONLY(S) (S)->slp_vect_only_p
> #define STMT_VINFO_REDUC_VECTYPE_IN(S) (S)->reduc_vectype_in
> +#define STMT_VINFO_PREDICATED_INDEX_MASK(S) (S)->predicated_index_mask
I wonder if we really need to carry the mask here. Can't we get to it
later easily once we have the store as well? Maybe then we could do all
at once, get the mask, the precision etc.
I'm still thinking whether we want an explicit "bail" for the
predicated_index phi in this patch but I realized after building the
patch that it's rejected by non-single use which should be ok for now.
--
Regards
Robin