@@ -507,6 +507,7 @@ static const int cond_expr_maps[3][5] = {
{ 4, -2, -1, 1, 2 },
{ 4, -1, -2, 2, 1 }
};
+static const int no_arg_map[] = { 0 };
static const int arg0_map[] = { 1, 0 };
static const int arg1_map[] = { 1, 1 };
static const int arg2_map[] = { 1, 2 };
@@ -587,6 +588,9 @@ vect_get_operand_map (const gimple *stmt, bool gather_scatter_p = false,
case IFN_CTZ:
return arg0_map;
+ case IFN_GOMP_SIMD_LANE:
+ return no_arg_map;
+
default:
break;
}
@@ -1175,6 +1179,8 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap,
ldst_p = true;
rhs_code = CFN_MASK_STORE;
}
+ else if (cfn == CFN_GOMP_SIMD_LANE)
+ ;
else if ((cfn != CFN_LAST
&& cfn != CFN_MASK_CALL
&& internal_fn_p (cfn)
@@ -1273,6 +1279,11 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap,
need_same_oprnds = true;
first_op1 = gimple_call_arg (call_stmt, 1);
}
+ else if (rhs_code == CFN_GOMP_SIMD_LANE)
+ {
+ need_same_oprnds = true;
+ first_op1 = gimple_call_arg (call_stmt, 1);
+ }
}
else
{
@@ -3392,7 +3392,7 @@ vectorizable_call (vec_info *vinfo,
if (ifn == IFN_LAST && !fndecl)
{
if (cfn == CFN_GOMP_SIMD_LANE
- && !slp_node
+ && (!slp_node || SLP_TREE_LANES (slp_node) == 1)
&& loop_vinfo
&& LOOP_VINFO_LOOP (loop_vinfo)->simduid
&& TREE_CODE (gimple_call_arg (stmt, 0)) == SSA_NAME
@@ -3538,8 +3538,30 @@ vectorizable_call (vec_info *vinfo,
/* Build argument list for the vectorized call. */
if (slp_node)
{
- vec<tree> vec_oprnds0;
+ if (cfn == CFN_GOMP_SIMD_LANE)
+ {
+ for (i = 0; i < SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); ++i)
+ {
+ /* ??? For multi-lane SLP we'd need to build
+ { 0, 0, .., 1, 1, ... }. */
+ tree cst = build_index_vector (vectype_out,
+ i * nunits_out, 1);
+ tree new_var
+ = vect_get_new_ssa_name (vectype_out, vect_simple_var,
+ "cst_");
+ gimple *init_stmt = gimple_build_assign (new_var, cst);
+ vect_init_vector_1 (vinfo, stmt_info, init_stmt, NULL);
+ new_temp = make_ssa_name (vec_dest);
+ gimple *new_stmt
+ = gimple_build_assign (new_temp, new_var);
+ vect_finish_stmt_generation (vinfo, stmt_info, new_stmt,
+ gsi);
+ slp_node->push_vec_def (new_stmt);
+ }
+ continue;
+ }
+ vec<tree> vec_oprnds0;
vect_get_slp_defs (vinfo, slp_node, &vec_defs);
vec_oprnds0 = vec_defs[0];