aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2023-11-06 14:34:07 +0100
committerRichard Biener <rguenther@suse.de>2023-11-06 15:27:47 +0100
commit9125969086bfa1bf804b246ea574a2329b06d2c5 (patch)
tree57184ad8d9bc2224b6a863b8f8f3fbe33dca66ed
parentffa0a73e152807a57fe4159a0d53ede25812fd1f (diff)
downloadgcc-9125969086bfa1bf804b246ea574a2329b06d2c5.zip
gcc-9125969086bfa1bf804b246ea574a2329b06d2c5.tar.gz
gcc-9125969086bfa1bf804b246ea574a2329b06d2c5.tar.bz2
tree-optimization/112405 - SIMD clone calls with (loop) mask
The following fixes the mask argument generation for SIMD clone calls under either loop masking or when the actual call is not masked but only a inbranch simd clone is available. The issue was that we tried to directly convert the vector mask to the call argument type but SIMD clone masks require 1 or 0 (which could be even float) values for mask elements so we have to resort to a VEC_COND_EXPR to generate them just like we do for regular passing of the mask. PR tree-optimization/112405 * tree-vect-stmts.cc (vectorizable_simd_clone_call): Properly handle invariant and/or loop mask passing.
-rw-r--r--gcc/tree-vect-stmts.cc62
1 files changed, 34 insertions, 28 deletions
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index eefb1ee..65883e0 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -4814,36 +4814,42 @@ vectorizable_simd_clone_call (vec_info *vinfo, stmt_vec_info stmt_info,
else
mask = vect_build_all_ones_mask (vinfo, stmt_info, masktype);
- if (!useless_type_conversion_p (TREE_TYPE (mask), masktype))
+ gassign *new_stmt;
+ if (SCALAR_INT_MODE_P (bestn->simdclone->mask_mode))
{
- gassign *new_stmt;
- if (bestn->simdclone->mask_mode != VOIDmode)
- {
- /* This means we are dealing with integer mask modes.
- First convert to an integer type with the same size as
- the current vector type. */
- unsigned HOST_WIDE_INT intermediate_size
- = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (mask)));
- tree mid_int_type =
- build_nonstandard_integer_type (intermediate_size, 1);
- mask = build1 (VIEW_CONVERT_EXPR, mid_int_type, mask);
- new_stmt
- = gimple_build_assign (make_ssa_name (mid_int_type),
- mask);
- gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
- /* Then zero-extend to the mask mode. */
- mask = fold_build1 (NOP_EXPR, masktype,
- gimple_get_lhs (new_stmt));
- }
- else
- mask = build1 (VIEW_CONVERT_EXPR, masktype, mask);
-
- new_stmt = gimple_build_assign (make_ssa_name (masktype),
- mask);
- vect_finish_stmt_generation (vinfo, stmt_info,
- new_stmt, gsi);
- mask = gimple_assign_lhs (new_stmt);
+ /* This means we are dealing with integer mask modes.
+ First convert to an integer type with the same size as
+ the current vector type. */
+ unsigned HOST_WIDE_INT intermediate_size
+ = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (mask)));
+ tree mid_int_type =
+ build_nonstandard_integer_type (intermediate_size, 1);
+ mask = build1 (VIEW_CONVERT_EXPR, mid_int_type, mask);
+ new_stmt
+ = gimple_build_assign (make_ssa_name (mid_int_type),
+ mask);
+ gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
+ /* Then zero-extend to the mask mode. */
+ mask = fold_build1 (NOP_EXPR, masktype,
+ gimple_get_lhs (new_stmt));
+ }
+ else if (bestn->simdclone->mask_mode == VOIDmode)
+ {
+ tree one = fold_convert (TREE_TYPE (masktype),
+ integer_one_node);
+ tree zero = fold_convert (TREE_TYPE (masktype),
+ integer_zero_node);
+ mask = build3 (VEC_COND_EXPR, masktype, mask,
+ build_vector_from_val (masktype, one),
+ build_vector_from_val (masktype, zero));
}
+ else
+ gcc_unreachable ();
+
+ new_stmt = gimple_build_assign (make_ssa_name (masktype), mask);
+ vect_finish_stmt_generation (vinfo, stmt_info,
+ new_stmt, gsi);
+ mask = gimple_assign_lhs (new_stmt);
vargs.safe_push (mask);
}
}