aboutsummaryrefslogtreecommitdiff
path: root/gcc/match.pd
diff options
context:
space:
mode:
authorRobin Dapp <rdapp@ventanamicro.com>2023-10-25 22:19:43 +0200
committerRobin Dapp <rdapp@ventanamicro.com>2023-11-06 12:21:57 +0100
commit0c42741ad95af3a1e3ac07350da4c3a94865ed63 (patch)
tree4dd137b298c08345aded697acd25d6c43006d32a /gcc/match.pd
parent89abbaa5fb3823601710394683cf2e2101aba66a (diff)
downloadgcc-0c42741ad95af3a1e3ac07350da4c3a94865ed63.zip
gcc-0c42741ad95af3a1e3ac07350da4c3a94865ed63.tar.gz
gcc-0c42741ad95af3a1e3ac07350da4c3a94865ed63.tar.bz2
internal-fn: Add VCOND_MASK_LEN.
In order to prevent simplification of a COND_OP with degenerate mask (CONSTM1_RTX) into just an OP in the presence of length masking this patch introduces a length-masked analog to VEC_COND_EXPR: IFN_VCOND_MASK_LEN. It also adds new match patterns that allow the combination of unconditional unary, binary and ternay operations with the VCOND_MASK_LEN into a conditional operation if the target supports it. gcc/ChangeLog: PR tree-optimization/111760 * config/riscv/autovec.md (vcond_mask_len_<mode><vm>): Add expander. * config/riscv/riscv-protos.h (enum insn_type): Add. * config/riscv/riscv-v.cc (needs_fp_rounding): Add !pred_mov. * doc/md.texi: Add vcond_mask_len. * gimple-match-exports.cc (maybe_resimplify_conditional_op): Create VCOND_MASK_LEN when length masking. * gimple-match.h (gimple_match_op::gimple_match_op): Always initialize len and bias. * internal-fn.cc (vec_cond_mask_len_direct): Add. (direct_vec_cond_mask_len_optab_supported_p): Add. (internal_fn_len_index): Add VCOND_MASK_LEN. (internal_fn_mask_index): Ditto. * internal-fn.def (VCOND_MASK_LEN): New internal function. * match.pd: Combine unconditional unary, binary and ternary operations into the respective COND_LEN operations. * optabs.def (OPTAB_D): Add vcond_mask_len optab. gcc/testsuite/ChangeLog: * gcc.dg/vect/vect-cond-arith-2.c: No vect cost model for riscv_v.
Diffstat (limited to 'gcc/match.pd')
-rw-r--r--gcc/match.pd51
1 files changed, 51 insertions, 0 deletions
diff --git a/gcc/match.pd b/gcc/match.pd
index 424bbd0..dbc811b 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -87,6 +87,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
negate bit_not)
(define_operator_list COND_UNARY
IFN_COND_NEG IFN_COND_NOT)
+(define_operator_list COND_LEN_UNARY
+ IFN_COND_LEN_NEG IFN_COND_LEN_NOT)
/* Binary operations and their associated IFN_COND_* function. */
(define_operator_list UNCOND_BINARY
@@ -8961,6 +8963,21 @@ and,
&& is_truth_type_for (op_type, TREE_TYPE (@0)))
(cond_op (bit_not @0) @2 @1)))))
+(for uncond_op (UNCOND_UNARY)
+ cond_op (COND_LEN_UNARY)
+ (simplify
+ (IFN_VCOND_MASK_LEN @0 (view_convert? (uncond_op@3 @1)) @2 @4 @5)
+ (with { tree op_type = TREE_TYPE (@3); }
+ (if (vectorized_internal_fn_supported_p (as_internal_fn (cond_op), op_type)
+ && is_truth_type_for (op_type, TREE_TYPE (@0)))
+ (cond_op @0 @1 @2 @4 @5))))
+ (simplify
+ (IFN_VCOND_MASK_LEN @0 @1 (view_convert? (uncond_op@3 @2)) @4 @5)
+ (with { tree op_type = TREE_TYPE (@3); }
+ (if (vectorized_internal_fn_supported_p (as_internal_fn (cond_op), op_type)
+ && is_truth_type_for (op_type, TREE_TYPE (@0)))
+ (cond_op (bit_not @0) @2 @1 @4 @5)))))
+
/* `(a ? -1 : 0) ^ b` can be converted into a conditional not. */
(simplify
(bit_xor:c (vec_cond @0 uniform_integer_cst_p@1 uniform_integer_cst_p@2) @3)
@@ -9007,6 +9024,23 @@ and,
&& single_use (@4))
(view_convert (cond_op (bit_not @0) @2 @3 (view_convert:op_type @1)))))))
+(for uncond_op (UNCOND_BINARY)
+ cond_op (COND_LEN_BINARY)
+ (simplify
+ (IFN_VCOND_MASK_LEN @0 (view_convert? (uncond_op@4 @1 @2)) @3 @5 @6)
+ (with { tree op_type = TREE_TYPE (@4); }
+ (if (vectorized_internal_fn_supported_p (as_internal_fn (cond_op), op_type)
+ && is_truth_type_for (op_type, TREE_TYPE (@0))
+ && single_use (@4))
+ (view_convert (cond_op @0 @1 @2 (view_convert:op_type @3) @5 @6)))))
+ (simplify
+ (IFN_VCOND_MASK_LEN @0 @1 (view_convert? (uncond_op@4 @2 @3)) @5 @6)
+ (with { tree op_type = TREE_TYPE (@4); }
+ (if (vectorized_internal_fn_supported_p (as_internal_fn (cond_op), op_type)
+ && is_truth_type_for (op_type, TREE_TYPE (@0))
+ && single_use (@4))
+ (view_convert (cond_op (bit_not @0) @2 @3 (view_convert:op_type @1) @5 @6))))))
+
/* Same for ternary operations. */
(for uncond_op (UNCOND_TERNARY)
cond_op (COND_TERNARY)
@@ -9025,6 +9059,23 @@ and,
&& single_use (@5))
(view_convert (cond_op (bit_not @0) @2 @3 @4
(view_convert:op_type @1)))))))
+
+(for uncond_op (UNCOND_TERNARY)
+ cond_op (COND_LEN_TERNARY)
+ (simplify
+ (IFN_VCOND_MASK_LEN @0 (view_convert? (uncond_op@5 @1 @2 @3)) @4 @6 @7)
+ (with { tree op_type = TREE_TYPE (@5); }
+ (if (vectorized_internal_fn_supported_p (as_internal_fn (cond_op), op_type)
+ && is_truth_type_for (op_type, TREE_TYPE (@0))
+ && single_use (@5))
+ (view_convert (cond_op @0 @1 @2 @3 (view_convert:op_type @4) @6 @7)))))
+ (simplify
+ (IFN_VCOND_MASK_LEN @0 @1 (view_convert? (uncond_op@5 @2 @3 @4 @6 @7)))
+ (with { tree op_type = TREE_TYPE (@5); }
+ (if (vectorized_internal_fn_supported_p (as_internal_fn (cond_op), op_type)
+ && is_truth_type_for (op_type, TREE_TYPE (@0))
+ && single_use (@5))
+ (view_convert (cond_op (bit_not @0) @2 @3 @4 (view_convert:op_type @1) @6 @7))))))
#endif
/* Detect cases in which a VEC_COND_EXPR effectively replaces the