]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Add support for vector conitional not
authorAndrew Pinski <apinski@marvell.com>
Sat, 12 Aug 2023 01:19:01 +0000 (18:19 -0700)
committerAndrew Pinski <apinski@marvell.com>
Thu, 17 Aug 2023 01:35:58 +0000 (18:35 -0700)
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.

gcc/internal-fn.def
gcc/match.pd
gcc/optabs.def
gcc/testsuite/gcc.target/aarch64/sve/cond_unary_9.c [new file with mode: 0644]

index a04d2b3631985a1ed6eaa23e4fadfc057dfd0f8f..594f7881511463d23e9840d03f3027168733799e 100644 (file)
@@ -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)
 
index 68c2fe1ae0269203cf7312c1da3b36be05c6658b..acd2a964917c9fd011dbbec678b3010dd3f05912 100644 (file)
@@ -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
index d4d7d6c53d4c21d97a73407184f5fdaa5659e33c..e216572a2d5b4d7bac316c2b5ae6caef9bdbdb27 100644 (file)
@@ -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 (file)
index 0000000..d6bc040
--- /dev/null
@@ -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" } } */