diff options
author | Robin Dapp <rdapp@ventanamicro.com> | 2023-09-13 22:19:35 +0200 |
---|---|---|
committer | Robin Dapp <rdapp@ventanamicro.com> | 2023-11-02 11:48:19 +0100 |
commit | 01c18f58d37865d5f3bbe93e666183b54ec608c7 (patch) | |
tree | 66434b35ac66c8ecc740e1559d249b701fbee6d8 /gcc/tree-if-conv.cc | |
parent | c05f748218a0d556972212d6aecfce0eb4c8a31c (diff) | |
download | gcc-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.cc | 49 |
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); |