From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1922) id CB9F9385801D; Mon, 18 Oct 2021 10:15:20 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org CB9F9385801D MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Prathamesh Kulkarni To: gcc-cvs@gcc.gnu.org Subject: [gcc r12-4470] [sve] PR93183 - Add support for conditional neg. X-Act-Checkin: gcc X-Git-Author: prathamesh.kulkarni X-Git-Refname: refs/heads/master X-Git-Oldrev: 85ce673378e7091ce603b033fac213a9d0d1f83a X-Git-Newrev: 20dcda98ed376cb61c74b2c71656f99c671ec9ce Message-Id: <20211018101520.CB9F9385801D@sourceware.org> Date: Mon, 18 Oct 2021 10:15:20 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 18 Oct 2021 10:15:20 -0000 https://gcc.gnu.org/g:20dcda98ed376cb61c74b2c71656f99c671ec9ce commit r12-4470-g20dcda98ed376cb61c74b2c71656f99c671ec9ce Author: prathamesh.kulkarni Date: Mon Oct 18 15:44:06 2021 +0530 [sve] PR93183 - Add support for conditional neg. gcc/ChangeLog: PR target/93183 * gimple-match-head.c (try_conditional_simplification): Add case for single operand. * internal-fn.def: Add entry for COND_NEG internal function. * internal-fn.c (FOR_EACH_CODE_MAPPING): Add entry for NEGATE_EXPR, COND_NEG mapping. * optabs.def: Add entry for cond_neg_optab. * match.pd (UNCOND_UNARY, COND_UNARY): New operator lists. (vec_cond COND (foo A) B) -> (IFN_COND_FOO COND A B): New pattern. (vec_cond COND B (foo A)) -> (IFN_COND_FOO ~COND A B): Likewise. gcc/testsuite/ChangeLog: PR target/93183 * gcc.target/aarch64/sve/cond_unary_4.c: Adjust. * gcc.target/aarch64/sve/pr93183.c: New test. Diff: --- gcc/gimple-match-head.c | 4 +++ gcc/internal-fn.c | 3 +- gcc/internal-fn.def | 2 ++ gcc/match.pd | 33 +++++++++++++++++++++- gcc/optabs.def | 1 + .../gcc.target/aarch64/sve/cond_unary_4.c | 6 +++- gcc/testsuite/gcc.target/aarch64/sve/pr93183.c | 21 ++++++++++++++ 7 files changed, 67 insertions(+), 3 deletions(-) diff --git a/gcc/gimple-match-head.c b/gcc/gimple-match-head.c index 7112c116835..9d88b2f8551 100644 --- a/gcc/gimple-match-head.c +++ b/gcc/gimple-match-head.c @@ -870,6 +870,10 @@ try_conditional_simplification (internal_fn ifn, gimple_match_op *res_op, memcpy (cond_op.ops, res_op->ops + 1, (num_ops - 1) * sizeof *cond_op.ops); switch (num_ops - 2) { + case 1: + if (!gimple_resimplify1 (seq, &cond_op, valueize)) + return false; + break; case 2: if (!gimple_resimplify2 (seq, &cond_op, valueize)) return false; diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c index b3638192fb9..9e10da0ad5c 100644 --- a/gcc/internal-fn.c +++ b/gcc/internal-fn.c @@ -3909,7 +3909,8 @@ static void (*const internal_fn_expanders[]) (internal_fn, gcall *) = { T (BIT_IOR_EXPR, IFN_COND_IOR) \ T (BIT_XOR_EXPR, IFN_COND_XOR) \ T (LSHIFT_EXPR, IFN_COND_SHL) \ - T (RSHIFT_EXPR, IFN_COND_SHR) + T (RSHIFT_EXPR, IFN_COND_SHR) \ + T (NEGATE_EXPR, IFN_COND_NEG) /* Return a function that only performs CODE when a certain condition is met and that uses a given fallback value otherwise. For example, if CODE is diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def index 01f60a6cf26..bb13c6cce1b 100644 --- a/gcc/internal-fn.def +++ b/gcc/internal-fn.def @@ -204,6 +204,8 @@ DEF_INTERNAL_OPTAB_FN (COND_FMS, ECF_CONST, cond_fms, cond_ternary) DEF_INTERNAL_OPTAB_FN (COND_FNMA, ECF_CONST, cond_fnma, cond_ternary) DEF_INTERNAL_OPTAB_FN (COND_FNMS, ECF_CONST, cond_fnms, cond_ternary) +DEF_INTERNAL_OPTAB_FN (COND_NEG, ECF_CONST, cond_neg, cond_unary) + DEF_INTERNAL_OPTAB_FN (RSQRT, ECF_CONST, rsqrt, unary) DEF_INTERNAL_OPTAB_FN (REDUC_PLUS, ECF_CONST | ECF_NOTHROW, diff --git a/gcc/match.pd b/gcc/match.pd index 038a7981c0e..3ff15bc0de5 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -78,6 +78,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (CEIL) DEFINE_INT_AND_FLOAT_ROUND_FN (ROUND) DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) +/* Unary operations and their associated IFN_COND_* function. */ +(define_operator_list UNCOND_UNARY + negate) +(define_operator_list COND_UNARY + IFN_COND_NEG) + /* Binary operations and their associated IFN_COND_* function. */ (define_operator_list UNCOND_BINARY plus minus @@ -7075,6 +7081,32 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) false, prec)); }) { build_zero_cst (TREE_TYPE (@0)); })))))))) +#if GIMPLE + +/* Simplify: + a = op a1 + r = cond ? a : b + --> r = .COND_FN (cond, a, b) +and, + a = op a1 + r = cond ? b : a + --> r = .COND_FN (~cond, b, a). */ + +(for uncond_op (UNCOND_UNARY) + cond_op (COND_UNARY) + (simplify + (vec_cond @0 (view_convert? (uncond_op@3 @1)) @2) + (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)))) + (simplify + (vec_cond @0 @1 (view_convert? (uncond_op@3 @2))) + (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))))) + /* Simplify: a = a1 op a2 @@ -7093,7 +7125,6 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) conditional internal functions must support the same comparisons inside and outside a VEC_COND_EXPR. */ -#if GIMPLE (for uncond_op (UNCOND_BINARY) cond_op (COND_BINARY) (simplify diff --git a/gcc/optabs.def b/gcc/optabs.def index f02c7b729a5..b889ad2e5a0 100644 --- a/gcc/optabs.def +++ b/gcc/optabs.def @@ -245,6 +245,7 @@ OPTAB_D (cond_fma_optab, "cond_fma$a") 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 (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_4.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_4.c index 4604365fbef..a491f899088 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_4.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_4.c @@ -56,7 +56,11 @@ TEST_ALL (DEF_LOOP) we're relying on combine to merge a SEL and an arithmetic operation, and the SEL doesn't allow the "false" value to be zero when the "true" value is a register. */ -/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+, z[0-9]+\n} 14 } } */ +/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+, z[0-9]+\n} 7 } } */ +/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.b, p[0-7]/z, z[0-9]+\.b} 1 } } */ +/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.h, p[0-7]/z, z[0-9]+\.h} 2 } } */ +/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.s, p[0-7]/z, z[0-9]+\.s} 2 } } */ +/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.d, p[0-7]/z, z[0-9]+\.d} 2 } } */ /* { dg-final { scan-assembler-not {\tmov\tz[^\n]*z} } } */ /* { dg-final { scan-assembler-not {\tsel\t} } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pr93183.c b/gcc/testsuite/gcc.target/aarch64/sve/pr93183.c new file mode 100644 index 00000000000..2f92224cecb --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/pr93183.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -mcpu=generic+sve" } */ + +typedef unsigned char uint8_t; + +static inline uint8_t +x264_clip_uint8(uint8_t x) +{ + uint8_t t = -x; + uint8_t t1 = x & ~63; + return (t1 != 0) ? t : x; +} + +void +mc_weight(uint8_t *restrict dst, uint8_t *restrict src, int n) +{ + for (int x = 0; x < n*16; x++) + dst[x] = x264_clip_uint8(src[x]); +} + +/* { dg-final { scan-assembler-not {\tsel} } } */