public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Richard Biener <richard.guenther@gmail.com>
To: Andrew Pinski <apinski@marvell.com>
Cc: GCC Patches <gcc-patches@gcc.gnu.org>
Subject: Re: [PATCH] move the (a-b) CMP 0 ? (a-b) : (b-a) optimization from fold_cond_expr_with_comparison to match
Date: Mon, 12 Jul 2021 13:46:32 +0200	[thread overview]
Message-ID: <CAFiYyc2rF8VgDAazqv9a9OPdpqygxOMQ8cTTr9kOCx9vt7Lskw@mail.gmail.com> (raw)
In-Reply-To: <1625969489-14344-1-git-send-email-apinski@marvell.com>

On Sun, Jul 11, 2021 at 4:12 AM apinski--- via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> From: Andrew Pinski <apinski@marvell.com>
>
> This patch moves the (a-b) CMP 0 ? (a-b) : (b-a) optimization
> from fold_cond_expr_with_comparison to match.

So I searched and I guess these transforms are produced from

  /* If we have A op 0 ? A : -A, consider applying the following
     transformations:

     A == 0? A : -A    same as -A
     A != 0? A : -A    same as A
     A >= 0? A : -A    same as abs (A)
     A > 0?  A : -A    same as abs (A)
     A <= 0? A : -A    same as -abs (A)
     A < 0?  A : -A    same as -abs (A)

     None of these transformations work for modes with signed
     zeros.  If A is +/-0, the first two transformations will
     change the sign of the result (from +0 to -0, or vice
     versa).  The last four will fix the sign of the result,
     even though the original expressions could be positive or
     negative, depending on the sign of A.

     Note that all these transformations are correct if A is
     NaN, since the two alternatives (A and -A) are also NaNs.  */
  if (!HONOR_SIGNED_ZEROS (type)
      && (FLOAT_TYPE_P (TREE_TYPE (arg01))
          ? real_zerop (arg01)
          : integer_zerop (arg01))
      && ((TREE_CODE (arg2) == NEGATE_EXPR
           && operand_equal_p (TREE_OPERAND (arg2, 0), arg1, 0))
             /* In the case that A is of the form X-Y, '-A' (arg2) may
                have already been folded to Y-X, check for that. */
          || (TREE_CODE (arg1) == MINUS_EXPR
              && TREE_CODE (arg2) == MINUS_EXPR
              && operand_equal_p (TREE_OPERAND (arg1, 0),
                                  TREE_OPERAND (arg2, 1), 0)
              && operand_equal_p (TREE_OPERAND (arg1, 1),
                                  TREE_OPERAND (arg2, 0), 0))))
...

I wonder at which point we can remove the code from fold-const.c?

Some comments inline below.

> OK? Bootstrapped and tested on x86_64-linux-gnu.
>
> gcc/ChangeLog:
>
>         * match.pd ((A-B) CMP 0 ? (A-B) : (B - A)):
>         New patterns.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.dg/tree-ssa/phi-opt-25.c: New test.
> ---
>  gcc/match.pd                               | 48 ++++++++++++++++++++--
>  gcc/testsuite/gcc.dg/tree-ssa/phi-opt-25.c | 45 ++++++++++++++++++++
>  2 files changed, 90 insertions(+), 3 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-25.c
>
> diff --git a/gcc/match.pd b/gcc/match.pd
> index 30680d488ab..aa88381fdcb 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -4040,9 +4040,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>    (cnd (logical_inverted_value truth_valued_p@0) @1 @2)
>    (cnd @0 @2 @1)))
>
> -/* abs/negative simplifications moved from fold_cond_expr_with_comparison,
> -   Need to handle (A - B) case as fold_cond_expr_with_comparison does.
> -   Need to handle UN* comparisons.
> +/* abs/negative simplifications moved from fold_cond_expr_with_comparison.
>
>     None of these transformations work for modes with signed
>     zeros.  If A is +/-0, the first two transformations will
> @@ -4098,6 +4096,50 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>         (convert (negate (absu:utype @0))))
>         (negate (abs @0)))))
>   )
> +
> + /* (A - B) == 0 ? (A - B) : (B - A)    same as (B - A) */
> + (for cmp (eq uneq)
> +  (simplify
> +   (cnd (cmp (minus@0 @1 @2) zerop) @0 (minus@3 @2 @1))
> +    (if (!HONOR_SIGNED_ZEROS (type))
> +     @3))
> +  (simplify
> +   (cnd (cmp (minus@0 @1 @2) zerop) integer_zerop (minus@3 @2 @1))

So that makes me think why integer_zerop?  'type' should then be
integer and thus never HONOR_SIGNED_ZEROS.

Don't we also need the inverted condition case for completeness?

> +    (if (!HONOR_SIGNED_ZEROS (type))
> +     @3))
> +  (simplify
> +   (cnd (cmp @1 @2) integer_zerop (minus@3 @2 @1))

I think this needs to be (cmp:c @1 @2)

> +    (if (!HONOR_SIGNED_ZEROS (type))
> +     @3))
> + )
> + /* (A - B) != 0 ? (A - B) : (B - A)    same as (A - B) */
> + (for cmp (ne ltgt)
> +  (simplify
> +   (cnd (cmp (minus@0 @1 @2) zerop) @0 (minus @2 @1))
> +    (if (!HONOR_SIGNED_ZEROS (type))
> +     @0))
> + )
> + /* (A - B) >=/> 0 ? (A - B) : (B - A)    same as abs (A - B) */
> + (for cmp (ge gt)
> +  (simplify
> +   (cnd (cmp (minus@0 @1 @2) zerop) @0 (minus @2 @1))
> +    (if (!HONOR_SIGNED_ZEROS (type)
> +        && !TYPE_UNSIGNED (type))
> +     (abs @0))))
> + /* (A - B) <=/< 0 ? (A - B) : (B - A)    same as -abs (A - B) */
> + (for cmp (le lt)
> +  (simplify
> +   (cnd (cmp (minus@0 @1 @2) zerop) @0 (minus @2 @1))
> +    (if (!HONOR_SIGNED_ZEROS (type)
> +        && !TYPE_UNSIGNED (type))
> +     (if (ANY_INTEGRAL_TYPE_P (type)
> +         && !TYPE_OVERFLOW_WRAPS (type))
> +      (with {
> +       tree utype = unsigned_type_for (type);
> +       }
> +       (convert (negate (absu:utype @0))))
> +       (negate (abs @0)))))
> + )
>  )
>
>  /* -(type)!A -> (type)A - 1.  */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-25.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-25.c
> new file mode 100644
> index 00000000000..0f0e3170f8d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-25.c
> @@ -0,0 +1,45 @@
> +/* { dg-options "-O2 -fno-signed-zeros -fdump-tree-phiopt" } */
> +int minus1(int a, int b)
> +{
> +  int c = a - b;
> +  if (c == 0) c = b - a;
> +  return c;
> +}
> +int minus2(int a, int b)
> +{
> +  int c = a - b;
> +  if (c != 0) c = b - a;
> +  return c;
> +}
> +int minus3(int a, int b)
> +{
> +  int c = a - b;
> +  if (c == 0) c = 0;
> +  else c = b - a;
> +  return c;
> +}
> +int minus4(int a, int b)
> +{
> +  int c;
> +  if (a == b) c = 0;
> +  else
> +    c = b - a;
> +  return c;
> +}
> +int abs0(int a, int b)
> +{
> +  int c = a - b;
> +  if (c <= 0) c = b - a;
> +  return c;
> +}
> +int negabs(int a, int b)
> +{
> +  int c = a - b;
> +  if (c >= 0) c = b - a;
> +  return c;
> +}
> +
> +/* The above should be optimized at phiopt1 except for negabs which has to wait
> +  until phiopt2 as -abs is not acceptable in early phiopt.  */
> +/* { dg-final { scan-tree-dump-times "if" 1  "phiopt1"  } } */
> +/* { dg-final { scan-tree-dump-not "if" "phiopt2" } } */
> --
> 2.27.0
>

  reply	other threads:[~2021-07-12 11:46 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-11  2:11 apinski
2021-07-12 11:46 ` Richard Biener [this message]
2023-10-20  5:13   ` Andrew Pinski
2023-10-21 20:14     ` Andrew Pinski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAFiYyc2rF8VgDAazqv9a9OPdpqygxOMQ8cTTr9kOCx9vt7Lskw@mail.gmail.com \
    --to=richard.guenther@gmail.com \
    --cc=apinski@marvell.com \
    --cc=gcc-patches@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).