aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-if-conv.cc
diff options
context:
space:
mode:
authorRobin Dapp <rdapp@ventanamicro.com>2023-09-13 22:19:35 +0200
committerRobin Dapp <rdapp@ventanamicro.com>2023-11-02 11:48:19 +0100
commit01c18f58d37865d5f3bbe93e666183b54ec608c7 (patch)
tree66434b35ac66c8ecc740e1559d249b701fbee6d8 /gcc/tree-if-conv.cc
parentc05f748218a0d556972212d6aecfce0eb4c8a31c (diff)
downloadgcc-01c18f58d37865d5f3bbe93e666183b54ec608c7.zip
gcc-01c18f58d37865d5f3bbe93e666183b54ec608c7.tar.gz
gcc-01c18f58d37865d5f3bbe93e666183b54ec608c7.tar.bz2
ifcvt/vect: Emit COND_OP for conditional scalar reduction.
As described in PR111401 we currently emit a COND and a PLUS expression for conditional reductions. This makes it difficult to combine both into a masked reduction statement later. This patch improves that by directly emitting a COND_ADD/COND_OP during ifcvt and adjusting some vectorizer code to handle it. It also makes neutral_op_for_reduction return -0 if HONOR_SIGNED_ZEROS is true. gcc/ChangeLog: PR middle-end/111401 * internal-fn.cc (internal_fn_else_index): New function. * internal-fn.h (internal_fn_else_index): Define. * tree-if-conv.cc (convert_scalar_cond_reduction): Emit COND_OP if supported. (predicate_scalar_phi): Add whitespace. * tree-vect-loop.cc (fold_left_reduction_fn): Add IFN_COND_OP. (neutral_op_for_reduction): Return -0 for PLUS. (check_reduction_path): Don't count else operand in COND_OP. (vect_is_simple_reduction): Ditto. (vect_create_epilog_for_reduction): Fix whitespace. (vectorize_fold_left_reduction): Add COND_OP handling. (vectorizable_reduction): Don't count else operand in COND_OP. (vect_transform_reduction): Add COND_OP handling. * tree-vectorizer.h (neutral_op_for_reduction): Add default parameter. gcc/testsuite/ChangeLog: * gcc.dg/vect/vect-cond-reduc-in-order-2-signed-zero.c: New test. * gcc.target/riscv/rvv/autovec/cond/pr111401.c: New test. * gcc.target/riscv/rvv/autovec/reduc/reduc_call-2.c: Adjust. * gcc.target/riscv/rvv/autovec/reduc/reduc_call-4.c: Ditto.
Diffstat (limited to 'gcc/tree-if-conv.cc')
-rw-r--r--gcc/tree-if-conv.cc49
1 files changed, 34 insertions, 15 deletions
diff --git a/gcc/tree-if-conv.cc b/gcc/tree-if-conv.cc
index 16e06d8..a7a751b 100644
--- a/gcc/tree-if-conv.cc
+++ b/gcc/tree-if-conv.cc
@@ -1856,10 +1856,12 @@ convert_scalar_cond_reduction (gimple *reduc, gimple_stmt_iterator *gsi,
gimple *new_assign;
tree rhs;
tree rhs1 = gimple_assign_rhs1 (reduc);
+ tree lhs = gimple_assign_lhs (reduc);
tree tmp = make_temp_ssa_name (TREE_TYPE (rhs1), NULL, "_ifc_");
tree c;
enum tree_code reduction_op = gimple_assign_rhs_code (reduc);
- tree op_nochange = neutral_op_for_reduction (TREE_TYPE (rhs1), reduction_op, NULL);
+ tree op_nochange = neutral_op_for_reduction (TREE_TYPE (rhs1), reduction_op,
+ NULL, false);
gimple_seq stmts = NULL;
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -1868,19 +1870,36 @@ convert_scalar_cond_reduction (gimple *reduc, gimple_stmt_iterator *gsi,
print_gimple_stmt (dump_file, reduc, 0, TDF_SLIM);
}
- /* Build cond expression using COND and constant operand
- of reduction rhs. */
- c = fold_build_cond_expr (TREE_TYPE (rhs1),
- unshare_expr (cond),
- swap ? op_nochange : op1,
- swap ? op1 : op_nochange);
-
- /* Create assignment stmt and insert it at GSI. */
- new_assign = gimple_build_assign (tmp, c);
- gsi_insert_before (gsi, new_assign, GSI_SAME_STMT);
- /* Build rhs for unconditional increment/decrement/logic_operation. */
- rhs = gimple_build (&stmts, reduction_op,
- TREE_TYPE (rhs1), op0, tmp);
+ /* If possible create a COND_OP instead of a COND_EXPR and an OP_EXPR.
+ The COND_OP will have a neutral_op else value. */
+ internal_fn ifn;
+ ifn = get_conditional_internal_fn (reduction_op);
+ if (ifn != IFN_LAST
+ && vectorized_internal_fn_supported_p (ifn, TREE_TYPE (lhs))
+ && !swap)
+ {
+ gcall *cond_call = gimple_build_call_internal (ifn, 4,
+ unshare_expr (cond),
+ op0, op1, op0);
+ gsi_insert_before (gsi, cond_call, GSI_SAME_STMT);
+ gimple_call_set_lhs (cond_call, tmp);
+ rhs = tmp;
+ }
+ else
+ {
+ /* Build cond expression using COND and constant operand
+ of reduction rhs. */
+ c = fold_build_cond_expr (TREE_TYPE (rhs1),
+ unshare_expr (cond),
+ swap ? op_nochange : op1,
+ swap ? op1 : op_nochange);
+ /* Create assignment stmt and insert it at GSI. */
+ new_assign = gimple_build_assign (tmp, c);
+ gsi_insert_before (gsi, new_assign, GSI_SAME_STMT);
+ /* Build rhs for unconditional increment/decrement/logic_operation. */
+ rhs = gimple_build (&stmts, reduction_op,
+ TREE_TYPE (rhs1), op0, tmp);
+ }
if (has_nop)
{
@@ -2292,7 +2311,7 @@ predicate_scalar_phi (gphi *phi, gimple_stmt_iterator *gsi)
{
/* Convert reduction stmt into vectorizable form. */
rhs = convert_scalar_cond_reduction (reduc, gsi, cond, op0, op1,
- swap,has_nop, nop_reduc);
+ swap, has_nop, nop_reduc);
redundant_ssa_names.safe_push (std::make_pair (res, rhs));
}
new_stmt = gimple_build_assign (res, rhs);