diff options
author | Andrew Pinski <apinski@marvell.com> | 2023-08-11 18:19:01 -0700 |
---|---|---|
committer | Andrew Pinski <apinski@marvell.com> | 2023-08-16 18:35:58 -0700 |
commit | a32de58c9e6394e4e6aef0ac95b52d1c774ac8bc (patch) | |
tree | c83cdfffa1faebb21d0cdfa669b0da4ecb61b923 | |
parent | 8e71ad9e782195d1285b85b2eb8f127572d5be2d (diff) | |
download | gcc-a32de58c9e6394e4e6aef0ac95b52d1c774ac8bc.zip gcc-a32de58c9e6394e4e6aef0ac95b52d1c774ac8bc.tar.gz gcc-a32de58c9e6394e4e6aef0ac95b52d1c774ac8bc.tar.bz2 |
Add support for vector conitional not
Like the support conditional neg (r12-4470-g20dcda98ed376cb61c74b2c71),
this just adds conditional not too.
Also we should be able to turn `(a ? -1 : 0) ^ b` into a conditional
not.
OK? Bootstrapped and tested on x86_64-linux-gnu and aarch64-linux-gnu.
gcc/ChangeLog:
* internal-fn.def (COND_NOT): New internal function.
* match.pd (UNCOND_UNARY, COND_UNARY): Add bit_not/not
to the lists.
(`vec (a ? -1 : 0) ^ b`): New pattern to convert
into conditional not.
* optabs.def (cond_one_cmpl): New optab.
(cond_len_one_cmpl): Likewise.
gcc/testsuite/ChangeLog:
PR target/110986
* gcc.target/aarch64/sve/cond_unary_9.c: New test.
-rw-r--r-- | gcc/internal-fn.def | 2 | ||||
-rw-r--r-- | gcc/match.pd | 15 | ||||
-rw-r--r-- | gcc/optabs.def | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/sve/cond_unary_9.c | 20 |
4 files changed, 37 insertions, 2 deletions
diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def index a04d2b3..594f788 100644 --- a/gcc/internal-fn.def +++ b/gcc/internal-fn.def @@ -71,6 +71,7 @@ along with GCC; see the file COPYING3. If not see lround<srcmode><dstmode>2. - cond_binary: a conditional binary optab, such as cond_add<mode> + - cond_unary: a conditional unary optab, such as cond_neg<mode> - cond_ternary: a conditional ternary optab, such as cond_fma_rev<mode> - fold_left: for scalar = FN (scalar, vector), keyed off the vector mode @@ -282,6 +283,7 @@ DEF_INTERNAL_COND_FN (FNMA, ECF_CONST, fnma, ternary) DEF_INTERNAL_COND_FN (FNMS, ECF_CONST, fnms, ternary) DEF_INTERNAL_COND_FN (NEG, ECF_CONST, neg, unary) +DEF_INTERNAL_COND_FN (NOT, ECF_CONST, one_cmpl, unary) DEF_INTERNAL_OPTAB_FN (RSQRT, ECF_CONST, rsqrt, unary) diff --git a/gcc/match.pd b/gcc/match.pd index 68c2fe1..acd2a96 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -84,9 +84,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* Unary operations and their associated IFN_COND_* function. */ (define_operator_list UNCOND_UNARY - negate) + negate bit_not) (define_operator_list COND_UNARY - IFN_COND_NEG) + IFN_COND_NEG IFN_COND_NOT) /* Binary operations and their associated IFN_COND_* function. */ (define_operator_list UNCOND_BINARY @@ -8486,6 +8486,17 @@ and, && is_truth_type_for (op_type, TREE_TYPE (@0))) (cond_op (bit_not @0) @2 @1))))) +/* `(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) + (if (canonicalize_math_after_vectorization_p () + && vectorized_internal_fn_supported_p (IFN_COND_NOT, type) + && is_truth_type_for (type, TREE_TYPE (@0))) + (if (integer_all_onesp (@1) && integer_zerop (@2)) + (IFN_COND_NOT @0 @3 @3)) + (if (integer_all_onesp (@2) && integer_zerop (@1)) + (IFN_COND_NOT (bit_not @0) @3 @3)))) + /* Simplify: a = a1 op a2 diff --git a/gcc/optabs.def b/gcc/optabs.def index d4d7d6c..e216572 100644 --- a/gcc/optabs.def +++ b/gcc/optabs.def @@ -256,6 +256,7 @@ OPTAB_D (cond_fms_optab, "cond_fms$a") OPTAB_D (cond_fnma_optab, "cond_fnma$a") OPTAB_D (cond_fnms_optab, "cond_fnms$a") OPTAB_D (cond_neg_optab, "cond_neg$a") +OPTAB_D (cond_one_cmpl_optab, "cond_one_cmpl$a") OPTAB_D (cond_len_add_optab, "cond_len_add$a") OPTAB_D (cond_len_sub_optab, "cond_len_sub$a") OPTAB_D (cond_len_smul_optab, "cond_len_mul$a") @@ -280,6 +281,7 @@ OPTAB_D (cond_len_fms_optab, "cond_len_fms$a") OPTAB_D (cond_len_fnma_optab, "cond_len_fnma$a") OPTAB_D (cond_len_fnms_optab, "cond_len_fnms$a") OPTAB_D (cond_len_neg_optab, "cond_len_neg$a") +OPTAB_D (cond_len_one_cmpl_optab, "cond_len_one_cmpl$a") OPTAB_D (cmov_optab, "cmov$a6") OPTAB_D (cstore_optab, "cstore$a4") OPTAB_D (ctrap_optab, "ctrap$a4") diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_9.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_9.c new file mode 100644 index 0000000..d6bc040 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_9.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-vectorize -moverride=sve_width=256 -fdump-tree-optimized" } */ + +/* This is a reduced version of cond_unary_5.c */ + +void __attribute__ ((noipa)) +f (short *__restrict r, + short *__restrict a, + short *__restrict pred) +{ + for (int i = 0; i < 1024; ++i) + r[i] = pred[i] != 0 ? ~(a[i]) : a[i]; +} + +/* { dg-final { scan-assembler-times {\tnot\tz[0-9]+\.h, p[0-7]/m,} 1 } } */ + +/* { dg-final { scan-assembler-not {\teor\tz} } } */ +/* { dg-final { scan-assembler-not {\tmov\tz[0-9]+\.h, p[0-7]/m, #-1} } } */ + +/* { dg-final { scan-tree-dump-times ".COND_NOT " 1 "optimized" } } */ |