match.pd: Add new abs pattern [PR94290]

Message ID 20220713192420.3126654-1-sfeifer@redhat.com
State New, archived
Headers
Series match.pd: Add new abs pattern [PR94290] |

Commit Message

Sam Feifer July 13, 2022, 7:24 p.m. UTC
  This patch is intended to fix a missed optimization in match.pd. It optimizes (x >= 0 ? x : 0) + (x <= 0 ? -x : 0) to just abs(x). I had to write a second simplification in match.pd to handle the commutative property as the match was not ocurring otherwise. Additionally, the pattern (x <= 0 ? -x : 0) now gets optimized to max(-x, 0), which helps with the other simplification rule.

Tests are also included to be added to the testsuite.

Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

	PR tree-optimization/94290

gcc/ChangeLog:

	* match.pd (x >= 0 ? x : 0) + (x <= 0 ? -x : 0): New simplification.
	* match.pd (x <= 0 ? -x : 0): New Simplification.

gcc/testsuite/ChangeLog:

	* gcc.c-torture/execute/pr94290-1.c: New test.
	* gcc.dg/pr94290-2.c: New test.
	* gcc.dg/pr94290.c: New test.
---
 gcc/match.pd                                  | 15 ++++++
 .../gcc.c-torture/execute/pr94290-1.c         | 16 +++++++
 gcc/testsuite/gcc.dg/pr94290-2.c              | 15 ++++++
 gcc/testsuite/gcc.dg/pr94290.c                | 46 +++++++++++++++++++
 4 files changed, 92 insertions(+)
 create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
 create mode 100644 gcc/testsuite/gcc.dg/pr94290-2.c
 create mode 100644 gcc/testsuite/gcc.dg/pr94290.c


base-commit: 6af530f914801f5e561057da55c41480f28751f7
  

Comments

Andrew Pinski July 13, 2022, 7:35 p.m. UTC | #1
On Wed, Jul 13, 2022 at 12:26 PM Sam Feifer via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> This patch is intended to fix a missed optimization in match.pd. It optimizes (x >= 0 ? x : 0) + (x <= 0 ? -x : 0) to just abs(x). I had to write a second simplification in match.pd to handle the commutative property as the match was not ocurring otherwise. Additionally, the pattern (x <= 0 ? -x : 0) now gets optimized to max(-x, 0), which helps with the other simplification rule.

You could use :c for the commutative property instead and that should
simplify things.
That is:

(simplify
  (plus:c (max @0 integer_zerop) (max (negate @0) integer_zerop))
  (abs @0))

Also since integer_zerop works on vectors, it seems like you should
add a testcase or two for the vector case.
Also would be useful if you write a testcase that uses different
statements rather than one big one so it gets exercised in the
forwprop case.
Note also if either of the max are used more than just in this
simplification, it could increase the lifetime of @0, maybe you need
to add :s to the max expressions.

Thanks,
Andrew

>
> Tests are also included to be added to the testsuite.
>
> Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
>
>         PR tree-optimization/94290
>
> gcc/ChangeLog:
>
>         * match.pd (x >= 0 ? x : 0) + (x <= 0 ? -x : 0): New simplification.
>         * match.pd (x <= 0 ? -x : 0): New Simplification.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.c-torture/execute/pr94290-1.c: New test.
>         * gcc.dg/pr94290-2.c: New test.
>         * gcc.dg/pr94290.c: New test.
> ---
>  gcc/match.pd                                  | 15 ++++++
>  .../gcc.c-torture/execute/pr94290-1.c         | 16 +++++++
>  gcc/testsuite/gcc.dg/pr94290-2.c              | 15 ++++++
>  gcc/testsuite/gcc.dg/pr94290.c                | 46 +++++++++++++++++++
>  4 files changed, 92 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
>  create mode 100644 gcc/testsuite/gcc.dg/pr94290-2.c
>  create mode 100644 gcc/testsuite/gcc.dg/pr94290.c
>
> diff --git a/gcc/match.pd b/gcc/match.pd
> index 45aefd96688..55ca79d7ac9 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -7848,3 +7848,18 @@ and,
>        (if (TYPE_UNSIGNED (TREE_TYPE (@0)))
>          (bit_and @0 @1)
>        (cond (le @0 @1) @0 (bit_and @0 @1))))))
> +
> +/* (x >= 0 ? x : 0) + (x <= 0 ? -x : 0) -> abs x.  */
> +(simplify
> +  (plus (max @0 integer_zerop) (max (negate @0) integer_zerop))
> +  (abs @0))
> +
> +/* (x <= 0 ? -x : 0) + (x >= 0 ? x : 0) -> abs x.  */
> +(simplify
> +  (plus (max (negate @0) integer_zerop) (max @0 integer_zerop) )
> +  (abs @0))
> +
> +/* (x <= 0 ? -x : 0) -> max(-x, 0).  */
> +(simplify
> + (cond (le @0 integer_zerop@1) (negate @0) integer_zerop@1)
> + (max (negate @0) @1))
> diff --git a/gcc/testsuite/gcc.c-torture/execute/pr94290-1.c b/gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
> new file mode 100644
> index 00000000000..93b80d569aa
> --- /dev/null
> +++ b/gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
> @@ -0,0 +1,16 @@
> +/* PR tree-optimization/94290 */
> +
> +#include "../../gcc.dg/pr94290.c"
> +
> +int main() {
> +
> +    if (foo(0) != 0
> +        || foo(-42) != 42
> +        || foo(42) != 42
> +        || baz(-10) != 10
> +        || baz(-10) != 10) {
> +            __builtin_abort();
> +        }
> +
> +    return 0;
> +}
> diff --git a/gcc/testsuite/gcc.dg/pr94290-2.c b/gcc/testsuite/gcc.dg/pr94290-2.c
> new file mode 100644
> index 00000000000..ea6e55755f5
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/pr94290-2.c
> @@ -0,0 +1,15 @@
> +/* PR tree-optimization/94290 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +
> +/* Form from PR.  */
> +__attribute__((noipa)) unsigned int foo(int x) {
> +    return x <= 0 ? -x : 0;
> +}
> +
> +/* Changed order.  */
> +__attribute__((noipa)) unsigned int bar(int x) {
> +    return 0 >= x ? -x : 0;
> +}
> +
> +/* { dg-final {scan-tree-dump-times " MAX_EXPR " 2 "optimized" } } */
> diff --git a/gcc/testsuite/gcc.dg/pr94290.c b/gcc/testsuite/gcc.dg/pr94290.c
> new file mode 100644
> index 00000000000..47617c36c02
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/pr94290.c
> @@ -0,0 +1,46 @@
> +/* PR tree-optimization/94290 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +
> +
> +/* Same form as PR.  */
> +__attribute__((noipa)) unsigned int foo(int x) {
> +    return (x >= 0 ? x : 0) + (x <= 0 ? -x : 0);
> +}
> +
> +/* Signed function.  */
> +__attribute__((noipa)) int bar(int x) {
> +    return (x >= 0 ? x : 0) + (x <= 0 ? -x : 0);
> +}
> +
> +/* Commutative property.  */
> +__attribute__((noipa)) unsigned int baz(int x) {
> +    return (x <= 0 ? -x : 0) + (x >= 0 ? x : 0);
> +}
> +
> +/* Flipped order for max expressions.  */
> +__attribute__((noipa)) unsigned int quux(int x) {
> +    return (0 <= x ? x : 0) + (0 >= x ? -x : 0);
> +}
> +
> +/* Not zero so should not optimize.  */
> +__attribute__((noipa)) unsigned int waldo(int x) {
> +    return (x >= 4 ? x : 4) + (x <= 4 ? -x : 4);
> +}
> +
> +/* Not zero so should not optimize.  */
> +__attribute__((noipa)) unsigned int fred(int x) {
> +    return (x >= -4 ? x : -4) + (x <= -4 ? -x : -4);
> +}
> +
> +/* Incorrect pattern.  */
> +__attribute__((noipa)) unsigned int goo(int x) {
> +    return (x <= 0 ? x : 0) + (x >= 0 ? -x : 0);
> +}
> +
> +/* Incorrect pattern.  */
> +__attribute__((noipa)) int qux(int x) {
> +    return (x >= 0 ? x : 0) + (x >= 0 ? x : 0);
> +}
> +
> +/* { dg-final {scan-tree-dump-times " ABS_EXPR " 4 "optimized" } } */
>
> base-commit: 6af530f914801f5e561057da55c41480f28751f7
> --
> 2.31.1
>
  
Richard Biener July 14, 2022, 6:52 a.m. UTC | #2
On Wed, Jul 13, 2022 at 9:36 PM Andrew Pinski via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> On Wed, Jul 13, 2022 at 12:26 PM Sam Feifer via Gcc-patches
> <gcc-patches@gcc.gnu.org> wrote:
> >
> > This patch is intended to fix a missed optimization in match.pd. It optimizes (x >= 0 ? x : 0) + (x <= 0 ? -x : 0) to just abs(x). I had to write a second simplification in match.pd to handle the commutative property as the match was not ocurring otherwise. Additionally, the pattern (x <= 0 ? -x : 0) now gets optimized to max(-x, 0), which helps with the other simplification rule.
>
> You could use :c for the commutative property instead and that should
> simplify things.
> That is:
>
> (simplify
>   (plus:c (max @0 integer_zerop) (max (negate @0) integer_zerop))
>   (abs @0))
>
> Also since integer_zerop works on vectors, it seems like you should
> add a testcase or two for the vector case.
> Also would be useful if you write a testcase that uses different
> statements rather than one big one so it gets exercised in the
> forwprop case.
> Note also if either of the max are used more than just in this
> simplification, it could increase the lifetime of @0, maybe you need
> to add :s to the max expressions.

Note :s will be ineffective since the result is "simple", I think it
is OK to do this simplification even when the max are not dead
after the transform.

>
> Thanks,
> Andrew
>
> >
> > Tests are also included to be added to the testsuite.
> >
> > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> >
> >         PR tree-optimization/94290
> >
> > gcc/ChangeLog:
> >
> >         * match.pd (x >= 0 ? x : 0) + (x <= 0 ? -x : 0): New simplification.
> >         * match.pd (x <= 0 ? -x : 0): New Simplification.
> >
> > gcc/testsuite/ChangeLog:
> >
> >         * gcc.c-torture/execute/pr94290-1.c: New test.
> >         * gcc.dg/pr94290-2.c: New test.
> >         * gcc.dg/pr94290.c: New test.
> > ---
> >  gcc/match.pd                                  | 15 ++++++
> >  .../gcc.c-torture/execute/pr94290-1.c         | 16 +++++++
> >  gcc/testsuite/gcc.dg/pr94290-2.c              | 15 ++++++
> >  gcc/testsuite/gcc.dg/pr94290.c                | 46 +++++++++++++++++++
> >  4 files changed, 92 insertions(+)
> >  create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
> >  create mode 100644 gcc/testsuite/gcc.dg/pr94290-2.c
> >  create mode 100644 gcc/testsuite/gcc.dg/pr94290.c
> >
> > diff --git a/gcc/match.pd b/gcc/match.pd
> > index 45aefd96688..55ca79d7ac9 100644
> > --- a/gcc/match.pd
> > +++ b/gcc/match.pd
> > @@ -7848,3 +7848,18 @@ and,
> >        (if (TYPE_UNSIGNED (TREE_TYPE (@0)))
> >          (bit_and @0 @1)
> >        (cond (le @0 @1) @0 (bit_and @0 @1))))))
> > +
> > +/* (x >= 0 ? x : 0) + (x <= 0 ? -x : 0) -> abs x.  */
> > +(simplify
> > +  (plus (max @0 integer_zerop) (max (negate @0) integer_zerop))
> > +  (abs @0))
> > +
> > +/* (x <= 0 ? -x : 0) + (x >= 0 ? x : 0) -> abs x.  */
> > +(simplify
> > +  (plus (max (negate @0) integer_zerop) (max @0 integer_zerop) )
> > +  (abs @0))
> > +
> > +/* (x <= 0 ? -x : 0) -> max(-x, 0).  */
> > +(simplify
> > + (cond (le @0 integer_zerop@1) (negate @0) integer_zerop@1)
> > + (max (negate @0) @1))
> > diff --git a/gcc/testsuite/gcc.c-torture/execute/pr94290-1.c b/gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
> > new file mode 100644
> > index 00000000000..93b80d569aa
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
> > @@ -0,0 +1,16 @@
> > +/* PR tree-optimization/94290 */
> > +
> > +#include "../../gcc.dg/pr94290.c"
> > +
> > +int main() {
> > +
> > +    if (foo(0) != 0
> > +        || foo(-42) != 42
> > +        || foo(42) != 42
> > +        || baz(-10) != 10
> > +        || baz(-10) != 10) {
> > +            __builtin_abort();
> > +        }
> > +
> > +    return 0;
> > +}
> > diff --git a/gcc/testsuite/gcc.dg/pr94290-2.c b/gcc/testsuite/gcc.dg/pr94290-2.c
> > new file mode 100644
> > index 00000000000..ea6e55755f5
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/pr94290-2.c
> > @@ -0,0 +1,15 @@
> > +/* PR tree-optimization/94290 */
> > +/* { dg-do compile } */
> > +/* { dg-options "-O2 -fdump-tree-optimized" } */
> > +
> > +/* Form from PR.  */
> > +__attribute__((noipa)) unsigned int foo(int x) {
> > +    return x <= 0 ? -x : 0;
> > +}
> > +
> > +/* Changed order.  */
> > +__attribute__((noipa)) unsigned int bar(int x) {
> > +    return 0 >= x ? -x : 0;
> > +}
> > +
> > +/* { dg-final {scan-tree-dump-times " MAX_EXPR " 2 "optimized" } } */
> > diff --git a/gcc/testsuite/gcc.dg/pr94290.c b/gcc/testsuite/gcc.dg/pr94290.c
> > new file mode 100644
> > index 00000000000..47617c36c02
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/pr94290.c
> > @@ -0,0 +1,46 @@
> > +/* PR tree-optimization/94290 */
> > +/* { dg-do compile } */
> > +/* { dg-options "-O2 -fdump-tree-optimized" } */
> > +
> > +
> > +/* Same form as PR.  */
> > +__attribute__((noipa)) unsigned int foo(int x) {
> > +    return (x >= 0 ? x : 0) + (x <= 0 ? -x : 0);
> > +}
> > +
> > +/* Signed function.  */
> > +__attribute__((noipa)) int bar(int x) {
> > +    return (x >= 0 ? x : 0) + (x <= 0 ? -x : 0);
> > +}
> > +
> > +/* Commutative property.  */
> > +__attribute__((noipa)) unsigned int baz(int x) {
> > +    return (x <= 0 ? -x : 0) + (x >= 0 ? x : 0);
> > +}
> > +
> > +/* Flipped order for max expressions.  */
> > +__attribute__((noipa)) unsigned int quux(int x) {
> > +    return (0 <= x ? x : 0) + (0 >= x ? -x : 0);
> > +}
> > +
> > +/* Not zero so should not optimize.  */
> > +__attribute__((noipa)) unsigned int waldo(int x) {
> > +    return (x >= 4 ? x : 4) + (x <= 4 ? -x : 4);
> > +}
> > +
> > +/* Not zero so should not optimize.  */
> > +__attribute__((noipa)) unsigned int fred(int x) {
> > +    return (x >= -4 ? x : -4) + (x <= -4 ? -x : -4);
> > +}
> > +
> > +/* Incorrect pattern.  */
> > +__attribute__((noipa)) unsigned int goo(int x) {
> > +    return (x <= 0 ? x : 0) + (x >= 0 ? -x : 0);
> > +}
> > +
> > +/* Incorrect pattern.  */
> > +__attribute__((noipa)) int qux(int x) {
> > +    return (x >= 0 ? x : 0) + (x >= 0 ? x : 0);
> > +}
> > +
> > +/* { dg-final {scan-tree-dump-times " ABS_EXPR " 4 "optimized" } } */
> >
> > base-commit: 6af530f914801f5e561057da55c41480f28751f7
> > --
> > 2.31.1
> >
  
Sam Feifer July 14, 2022, 2:09 p.m. UTC | #3
On Wed, Jul 13, 2022 at 3:36 PM Andrew Pinski <pinskia@gmail.com> wrote:

> On Wed, Jul 13, 2022 at 12:26 PM Sam Feifer via Gcc-patches
> <gcc-patches@gcc.gnu.org> wrote:
> >
> > This patch is intended to fix a missed optimization in match.pd. It
> optimizes (x >= 0 ? x : 0) + (x <= 0 ? -x : 0) to just abs(x). I had to
> write a second simplification in match.pd to handle the commutative
> property as the match was not ocurring otherwise. Additionally, the pattern
> (x <= 0 ? -x : 0) now gets optimized to max(-x, 0), which helps with the
> other simplification rule.
>
> You could use :c for the commutative property instead and that should
> simplify things.
> That is:
>
> (simplify
>   (plus:c (max @0 integer_zerop) (max (negate @0) integer_zerop))
>   (abs @0))
>
> Also since integer_zerop works on vectors, it seems like you should
> add a testcase or two for the vector case.
> Also would be useful if you write a testcase that uses different
> statements rather than one big one so it gets exercised in the
> forwprop case.
> Note also if either of the max are used more than just in this
> simplification, it could increase the lifetime of @0, maybe you need
> to add :s to the max expressions.
>
>
Thanks for the feedback. I'm not quite sure what a vector test case would
look like for this. Could I get some guidance on that?

Thanks
-Sam


> Thanks,
> Andrew
>
> >
> > Tests are also included to be added to the testsuite.
> >
> > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> >
> >         PR tree-optimization/94290
> >
> > gcc/ChangeLog:
> >
> >         * match.pd (x >= 0 ? x : 0) + (x <= 0 ? -x : 0): New
> simplification.
> >         * match.pd (x <= 0 ? -x : 0): New Simplification.
> >
> > gcc/testsuite/ChangeLog:
> >
> >         * gcc.c-torture/execute/pr94290-1.c: New test.
> >         * gcc.dg/pr94290-2.c: New test.
> >         * gcc.dg/pr94290.c: New test.
> > ---
> >  gcc/match.pd                                  | 15 ++++++
> >  .../gcc.c-torture/execute/pr94290-1.c         | 16 +++++++
> >  gcc/testsuite/gcc.dg/pr94290-2.c              | 15 ++++++
> >  gcc/testsuite/gcc.dg/pr94290.c                | 46 +++++++++++++++++++
> >  4 files changed, 92 insertions(+)
> >  create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
> >  create mode 100644 gcc/testsuite/gcc.dg/pr94290-2.c
> >  create mode 100644 gcc/testsuite/gcc.dg/pr94290.c
> >
> > diff --git a/gcc/match.pd b/gcc/match.pd
> > index 45aefd96688..55ca79d7ac9 100644
> > --- a/gcc/match.pd
> > +++ b/gcc/match.pd
> > @@ -7848,3 +7848,18 @@ and,
> >        (if (TYPE_UNSIGNED (TREE_TYPE (@0)))
> >          (bit_and @0 @1)
> >        (cond (le @0 @1) @0 (bit_and @0 @1))))))
> > +
> > +/* (x >= 0 ? x : 0) + (x <= 0 ? -x : 0) -> abs x.  */
> > +(simplify
> > +  (plus (max @0 integer_zerop) (max (negate @0) integer_zerop))
> > +  (abs @0))
> > +
> > +/* (x <= 0 ? -x : 0) + (x >= 0 ? x : 0) -> abs x.  */
> > +(simplify
> > +  (plus (max (negate @0) integer_zerop) (max @0 integer_zerop) )
> > +  (abs @0))
> > +
> > +/* (x <= 0 ? -x : 0) -> max(-x, 0).  */
> > +(simplify
> > + (cond (le @0 integer_zerop@1) (negate @0) integer_zerop@1)
> > + (max (negate @0) @1))
> > diff --git a/gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
> b/gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
> > new file mode 100644
> > index 00000000000..93b80d569aa
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
> > @@ -0,0 +1,16 @@
> > +/* PR tree-optimization/94290 */
> > +
> > +#include "../../gcc.dg/pr94290.c"
> > +
> > +int main() {
> > +
> > +    if (foo(0) != 0
> > +        || foo(-42) != 42
> > +        || foo(42) != 42
> > +        || baz(-10) != 10
> > +        || baz(-10) != 10) {
> > +            __builtin_abort();
> > +        }
> > +
> > +    return 0;
> > +}
> > diff --git a/gcc/testsuite/gcc.dg/pr94290-2.c
> b/gcc/testsuite/gcc.dg/pr94290-2.c
> > new file mode 100644
> > index 00000000000..ea6e55755f5
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/pr94290-2.c
> > @@ -0,0 +1,15 @@
> > +/* PR tree-optimization/94290 */
> > +/* { dg-do compile } */
> > +/* { dg-options "-O2 -fdump-tree-optimized" } */
> > +
> > +/* Form from PR.  */
> > +__attribute__((noipa)) unsigned int foo(int x) {
> > +    return x <= 0 ? -x : 0;
> > +}
> > +
> > +/* Changed order.  */
> > +__attribute__((noipa)) unsigned int bar(int x) {
> > +    return 0 >= x ? -x : 0;
> > +}
> > +
> > +/* { dg-final {scan-tree-dump-times " MAX_EXPR " 2 "optimized" } } */
> > diff --git a/gcc/testsuite/gcc.dg/pr94290.c
> b/gcc/testsuite/gcc.dg/pr94290.c
> > new file mode 100644
> > index 00000000000..47617c36c02
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/pr94290.c
> > @@ -0,0 +1,46 @@
> > +/* PR tree-optimization/94290 */
> > +/* { dg-do compile } */
> > +/* { dg-options "-O2 -fdump-tree-optimized" } */
> > +
> > +
> > +/* Same form as PR.  */
> > +__attribute__((noipa)) unsigned int foo(int x) {
> > +    return (x >= 0 ? x : 0) + (x <= 0 ? -x : 0);
> > +}
> > +
> > +/* Signed function.  */
> > +__attribute__((noipa)) int bar(int x) {
> > +    return (x >= 0 ? x : 0) + (x <= 0 ? -x : 0);
> > +}
> > +
> > +/* Commutative property.  */
> > +__attribute__((noipa)) unsigned int baz(int x) {
> > +    return (x <= 0 ? -x : 0) + (x >= 0 ? x : 0);
> > +}
> > +
> > +/* Flipped order for max expressions.  */
> > +__attribute__((noipa)) unsigned int quux(int x) {
> > +    return (0 <= x ? x : 0) + (0 >= x ? -x : 0);
> > +}
> > +
> > +/* Not zero so should not optimize.  */
> > +__attribute__((noipa)) unsigned int waldo(int x) {
> > +    return (x >= 4 ? x : 4) + (x <= 4 ? -x : 4);
> > +}
> > +
> > +/* Not zero so should not optimize.  */
> > +__attribute__((noipa)) unsigned int fred(int x) {
> > +    return (x >= -4 ? x : -4) + (x <= -4 ? -x : -4);
> > +}
> > +
> > +/* Incorrect pattern.  */
> > +__attribute__((noipa)) unsigned int goo(int x) {
> > +    return (x <= 0 ? x : 0) + (x >= 0 ? -x : 0);
> > +}
> > +
> > +/* Incorrect pattern.  */
> > +__attribute__((noipa)) int qux(int x) {
> > +    return (x >= 0 ? x : 0) + (x >= 0 ? x : 0);
> > +}
> > +
> > +/* { dg-final {scan-tree-dump-times " ABS_EXPR " 4 "optimized" } } */
> >
> > base-commit: 6af530f914801f5e561057da55c41480f28751f7
> > --
> > 2.31.1
> >
>
>
  
Andrew Pinski July 14, 2022, 5:24 p.m. UTC | #4
On Thu, Jul 14, 2022 at 7:09 AM Sam Feifer <sfeifer@redhat.com> wrote:
>
>
> On Wed, Jul 13, 2022 at 3:36 PM Andrew Pinski <pinskia@gmail.com> wrote:
>>
>> On Wed, Jul 13, 2022 at 12:26 PM Sam Feifer via Gcc-patches
>> <gcc-patches@gcc.gnu.org> wrote:
>> >
>> > This patch is intended to fix a missed optimization in match.pd. It optimizes (x >= 0 ? x : 0) + (x <= 0 ? -x : 0) to just abs(x). I had to write a second simplification in match.pd to handle the commutative property as the match was not ocurring otherwise. Additionally, the pattern (x <= 0 ? -x : 0) now gets optimized to max(-x, 0), which helps with the other simplification rule.
>>
>> You could use :c for the commutative property instead and that should
>> simplify things.
>> That is:
>>
>> (simplify
>>   (plus:c (max @0 integer_zerop) (max (negate @0) integer_zerop))
>>   (abs @0))
>>
>> Also since integer_zerop works on vectors, it seems like you should
>> add a testcase or two for the vector case.
>> Also would be useful if you write a testcase that uses different
>> statements rather than one big one so it gets exercised in the
>> forwprop case.
>> Note also if either of the max are used more than just in this
>> simplification, it could increase the lifetime of @0, maybe you need
>> to add :s to the max expressions.
>>
>
> Thanks for the feedback. I'm not quite sure what a vector test case would look like for this. Could I get some guidance on that?

Yes this should produce the pattern at forwprop1 time (with the C++
front-end, the C front-end does not support vector selects):
typedef int __attribute__((vector_size(4*sizeof(int)))) vint;

vint foo(vint x) {
    vint t = (x >= 0 ? x : 0) ;
    vint xx = -x;
    vint t1 =  (xx >= 0 ? xx : 0);
    return t + t1;
}

int foo(int x) {
    int t = (x >= 0 ? x : 0) ;
    int xx = -x;
    int t1 =  (xx >= 0 ? xx : 0);
    return t + t1;
}

Thanks,
Andrew Pinski


>
> Thanks
> -Sam
>
>>
>> Thanks,
>> Andrew
>>
>> >
>> > Tests are also included to be added to the testsuite.
>> >
>> > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
>> >
>> >         PR tree-optimization/94290
>> >
>> > gcc/ChangeLog:
>> >
>> >         * match.pd (x >= 0 ? x : 0) + (x <= 0 ? -x : 0): New simplification.
>> >         * match.pd (x <= 0 ? -x : 0): New Simplification.
>> >
>> > gcc/testsuite/ChangeLog:
>> >
>> >         * gcc.c-torture/execute/pr94290-1.c: New test.
>> >         * gcc.dg/pr94290-2.c: New test.
>> >         * gcc.dg/pr94290.c: New test.
>> > ---
>> >  gcc/match.pd                                  | 15 ++++++
>> >  .../gcc.c-torture/execute/pr94290-1.c         | 16 +++++++
>> >  gcc/testsuite/gcc.dg/pr94290-2.c              | 15 ++++++
>> >  gcc/testsuite/gcc.dg/pr94290.c                | 46 +++++++++++++++++++
>> >  4 files changed, 92 insertions(+)
>> >  create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
>> >  create mode 100644 gcc/testsuite/gcc.dg/pr94290-2.c
>> >  create mode 100644 gcc/testsuite/gcc.dg/pr94290.c
>> >
>> > diff --git a/gcc/match.pd b/gcc/match.pd
>> > index 45aefd96688..55ca79d7ac9 100644
>> > --- a/gcc/match.pd
>> > +++ b/gcc/match.pd
>> > @@ -7848,3 +7848,18 @@ and,
>> >        (if (TYPE_UNSIGNED (TREE_TYPE (@0)))
>> >          (bit_and @0 @1)
>> >        (cond (le @0 @1) @0 (bit_and @0 @1))))))
>> > +
>> > +/* (x >= 0 ? x : 0) + (x <= 0 ? -x : 0) -> abs x.  */
>> > +(simplify
>> > +  (plus (max @0 integer_zerop) (max (negate @0) integer_zerop))
>> > +  (abs @0))
>> > +
>> > +/* (x <= 0 ? -x : 0) + (x >= 0 ? x : 0) -> abs x.  */
>> > +(simplify
>> > +  (plus (max (negate @0) integer_zerop) (max @0 integer_zerop) )
>> > +  (abs @0))
>> > +
>> > +/* (x <= 0 ? -x : 0) -> max(-x, 0).  */
>> > +(simplify
>> > + (cond (le @0 integer_zerop@1) (negate @0) integer_zerop@1)
>> > + (max (negate @0) @1))
>> > diff --git a/gcc/testsuite/gcc.c-torture/execute/pr94290-1.c b/gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
>> > new file mode 100644
>> > index 00000000000..93b80d569aa
>> > --- /dev/null
>> > +++ b/gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
>> > @@ -0,0 +1,16 @@
>> > +/* PR tree-optimization/94290 */
>> > +
>> > +#include "../../gcc.dg/pr94290.c"
>> > +
>> > +int main() {
>> > +
>> > +    if (foo(0) != 0
>> > +        || foo(-42) != 42
>> > +        || foo(42) != 42
>> > +        || baz(-10) != 10
>> > +        || baz(-10) != 10) {
>> > +            __builtin_abort();
>> > +        }
>> > +
>> > +    return 0;
>> > +}
>> > diff --git a/gcc/testsuite/gcc.dg/pr94290-2.c b/gcc/testsuite/gcc.dg/pr94290-2.c
>> > new file mode 100644
>> > index 00000000000..ea6e55755f5
>> > --- /dev/null
>> > +++ b/gcc/testsuite/gcc.dg/pr94290-2.c
>> > @@ -0,0 +1,15 @@
>> > +/* PR tree-optimization/94290 */
>> > +/* { dg-do compile } */
>> > +/* { dg-options "-O2 -fdump-tree-optimized" } */
>> > +
>> > +/* Form from PR.  */
>> > +__attribute__((noipa)) unsigned int foo(int x) {
>> > +    return x <= 0 ? -x : 0;
>> > +}
>> > +
>> > +/* Changed order.  */
>> > +__attribute__((noipa)) unsigned int bar(int x) {
>> > +    return 0 >= x ? -x : 0;
>> > +}
>> > +
>> > +/* { dg-final {scan-tree-dump-times " MAX_EXPR " 2 "optimized" } } */
>> > diff --git a/gcc/testsuite/gcc.dg/pr94290.c b/gcc/testsuite/gcc.dg/pr94290.c
>> > new file mode 100644
>> > index 00000000000..47617c36c02
>> > --- /dev/null
>> > +++ b/gcc/testsuite/gcc.dg/pr94290.c
>> > @@ -0,0 +1,46 @@
>> > +/* PR tree-optimization/94290 */
>> > +/* { dg-do compile } */
>> > +/* { dg-options "-O2 -fdump-tree-optimized" } */
>> > +
>> > +
>> > +/* Same form as PR.  */
>> > +__attribute__((noipa)) unsigned int foo(int x) {
>> > +    return (x >= 0 ? x : 0) + (x <= 0 ? -x : 0);
>> > +}
>> > +
>> > +/* Signed function.  */
>> > +__attribute__((noipa)) int bar(int x) {
>> > +    return (x >= 0 ? x : 0) + (x <= 0 ? -x : 0);
>> > +}
>> > +
>> > +/* Commutative property.  */
>> > +__attribute__((noipa)) unsigned int baz(int x) {
>> > +    return (x <= 0 ? -x : 0) + (x >= 0 ? x : 0);
>> > +}
>> > +
>> > +/* Flipped order for max expressions.  */
>> > +__attribute__((noipa)) unsigned int quux(int x) {
>> > +    return (0 <= x ? x : 0) + (0 >= x ? -x : 0);
>> > +}
>> > +
>> > +/* Not zero so should not optimize.  */
>> > +__attribute__((noipa)) unsigned int waldo(int x) {
>> > +    return (x >= 4 ? x : 4) + (x <= 4 ? -x : 4);
>> > +}
>> > +
>> > +/* Not zero so should not optimize.  */
>> > +__attribute__((noipa)) unsigned int fred(int x) {
>> > +    return (x >= -4 ? x : -4) + (x <= -4 ? -x : -4);
>> > +}
>> > +
>> > +/* Incorrect pattern.  */
>> > +__attribute__((noipa)) unsigned int goo(int x) {
>> > +    return (x <= 0 ? x : 0) + (x >= 0 ? -x : 0);
>> > +}
>> > +
>> > +/* Incorrect pattern.  */
>> > +__attribute__((noipa)) int qux(int x) {
>> > +    return (x >= 0 ? x : 0) + (x >= 0 ? x : 0);
>> > +}
>> > +
>> > +/* { dg-final {scan-tree-dump-times " ABS_EXPR " 4 "optimized" } } */
>> >
>> > base-commit: 6af530f914801f5e561057da55c41480f28751f7
>> > --
>> > 2.31.1
>> >
>>
  
Sam Feifer July 14, 2022, 7:38 p.m. UTC | #5
On Thu, Jul 14, 2022 at 1:24 PM Andrew Pinski <pinskia@gmail.com> wrote:

> On Thu, Jul 14, 2022 at 7:09 AM Sam Feifer <sfeifer@redhat.com> wrote:
> >
> >
> > On Wed, Jul 13, 2022 at 3:36 PM Andrew Pinski <pinskia@gmail.com> wrote:
> >>
> >> On Wed, Jul 13, 2022 at 12:26 PM Sam Feifer via Gcc-patches
> >> <gcc-patches@gcc.gnu.org> wrote:
> >> >
> >> > This patch is intended to fix a missed optimization in match.pd. It
> optimizes (x >= 0 ? x : 0) + (x <= 0 ? -x : 0) to just abs(x). I had to
> write a second simplification in match.pd to handle the commutative
> property as the match was not ocurring otherwise. Additionally, the pattern
> (x <= 0 ? -x : 0) now gets optimized to max(-x, 0), which helps with the
> other simplification rule.
> >>
> >> You could use :c for the commutative property instead and that should
> >> simplify things.
> >> That is:
> >>
> >> (simplify
> >>   (plus:c (max @0 integer_zerop) (max (negate @0) integer_zerop))
> >>   (abs @0))
> >>
> >> Also since integer_zerop works on vectors, it seems like you should
> >> add a testcase or two for the vector case.
> >> Also would be useful if you write a testcase that uses different
> >> statements rather than one big one so it gets exercised in the
> >> forwprop case.
> >> Note also if either of the max are used more than just in this
> >> simplification, it could increase the lifetime of @0, maybe you need
> >> to add :s to the max expressions.
> >>
> >
> > Thanks for the feedback. I'm not quite sure what a vector test case
> would look like for this. Could I get some guidance on that?
>
> Yes this should produce the pattern at forwprop1 time (with the C++
> front-end, the C front-end does not support vector selects):
> typedef int __attribute__((vector_size(4*sizeof(int)))) vint;
>
> vint foo(vint x) {
>     vint t = (x >= 0 ? x : 0) ;
>     vint xx = -x;
>     vint t1 =  (xx >= 0 ? xx : 0);
>     return t + t1;
> }
>
> int foo(int x) {
>     int t = (x >= 0 ? x : 0) ;
>     int xx = -x;
>     int t1 =  (xx >= 0 ? xx : 0);
>     return t + t1;
> }
>
> Thanks,
> Andrew Pinski
>
>
Thanks for the help. I'm still having trouble with the vector test, though.
When I try to compile, I get an error saying "used vector type where scalar
is required", referring to the max expressions. How do I use the max
expression with two vectors as the inputs?

Thanks
-Sam

>
> >
> > Thanks
> > -Sam
> >
> >>
> >> Thanks,
> >> Andrew
> >>
> >> >
> >> > Tests are also included to be added to the testsuite.
> >> >
> >> > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> >> >
> >> >         PR tree-optimization/94290
> >> >
> >> > gcc/ChangeLog:
> >> >
> >> >         * match.pd (x >= 0 ? x : 0) + (x <= 0 ? -x : 0): New
> simplification.
> >> >         * match.pd (x <= 0 ? -x : 0): New Simplification.
> >> >
> >> > gcc/testsuite/ChangeLog:
> >> >
> >> >         * gcc.c-torture/execute/pr94290-1.c: New test.
> >> >         * gcc.dg/pr94290-2.c: New test.
> >> >         * gcc.dg/pr94290.c: New test.
> >> > ---
> >> >  gcc/match.pd                                  | 15 ++++++
> >> >  .../gcc.c-torture/execute/pr94290-1.c         | 16 +++++++
> >> >  gcc/testsuite/gcc.dg/pr94290-2.c              | 15 ++++++
> >> >  gcc/testsuite/gcc.dg/pr94290.c                | 46
> +++++++++++++++++++
> >> >  4 files changed, 92 insertions(+)
> >> >  create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
> >> >  create mode 100644 gcc/testsuite/gcc.dg/pr94290-2.c
> >> >  create mode 100644 gcc/testsuite/gcc.dg/pr94290.c
> >> >
> >> > diff --git a/gcc/match.pd b/gcc/match.pd
> >> > index 45aefd96688..55ca79d7ac9 100644
> >> > --- a/gcc/match.pd
> >> > +++ b/gcc/match.pd
> >> > @@ -7848,3 +7848,18 @@ and,
> >> >        (if (TYPE_UNSIGNED (TREE_TYPE (@0)))
> >> >          (bit_and @0 @1)
> >> >        (cond (le @0 @1) @0 (bit_and @0 @1))))))
> >> > +
> >> > +/* (x >= 0 ? x : 0) + (x <= 0 ? -x : 0) -> abs x.  */
> >> > +(simplify
> >> > +  (plus (max @0 integer_zerop) (max (negate @0) integer_zerop))
> >> > +  (abs @0))
> >> > +
> >> > +/* (x <= 0 ? -x : 0) + (x >= 0 ? x : 0) -> abs x.  */
> >> > +(simplify
> >> > +  (plus (max (negate @0) integer_zerop) (max @0 integer_zerop) )
> >> > +  (abs @0))
> >> > +
> >> > +/* (x <= 0 ? -x : 0) -> max(-x, 0).  */
> >> > +(simplify
> >> > + (cond (le @0 integer_zerop@1) (negate @0) integer_zerop@1)
> >> > + (max (negate @0) @1))
> >> > diff --git a/gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
> b/gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
> >> > new file mode 100644
> >> > index 00000000000..93b80d569aa
> >> > --- /dev/null
> >> > +++ b/gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
> >> > @@ -0,0 +1,16 @@
> >> > +/* PR tree-optimization/94290 */
> >> > +
> >> > +#include "../../gcc.dg/pr94290.c"
> >> > +
> >> > +int main() {
> >> > +
> >> > +    if (foo(0) != 0
> >> > +        || foo(-42) != 42
> >> > +        || foo(42) != 42
> >> > +        || baz(-10) != 10
> >> > +        || baz(-10) != 10) {
> >> > +            __builtin_abort();
> >> > +        }
> >> > +
> >> > +    return 0;
> >> > +}
> >> > diff --git a/gcc/testsuite/gcc.dg/pr94290-2.c
> b/gcc/testsuite/gcc.dg/pr94290-2.c
> >> > new file mode 100644
> >> > index 00000000000..ea6e55755f5
> >> > --- /dev/null
> >> > +++ b/gcc/testsuite/gcc.dg/pr94290-2.c
> >> > @@ -0,0 +1,15 @@
> >> > +/* PR tree-optimization/94290 */
> >> > +/* { dg-do compile } */
> >> > +/* { dg-options "-O2 -fdump-tree-optimized" } */
> >> > +
> >> > +/* Form from PR.  */
> >> > +__attribute__((noipa)) unsigned int foo(int x) {
> >> > +    return x <= 0 ? -x : 0;
> >> > +}
> >> > +
> >> > +/* Changed order.  */
> >> > +__attribute__((noipa)) unsigned int bar(int x) {
> >> > +    return 0 >= x ? -x : 0;
> >> > +}
> >> > +
> >> > +/* { dg-final {scan-tree-dump-times " MAX_EXPR " 2 "optimized" } } */
> >> > diff --git a/gcc/testsuite/gcc.dg/pr94290.c
> b/gcc/testsuite/gcc.dg/pr94290.c
> >> > new file mode 100644
> >> > index 00000000000..47617c36c02
> >> > --- /dev/null
> >> > +++ b/gcc/testsuite/gcc.dg/pr94290.c
> >> > @@ -0,0 +1,46 @@
> >> > +/* PR tree-optimization/94290 */
> >> > +/* { dg-do compile } */
> >> > +/* { dg-options "-O2 -fdump-tree-optimized" } */
> >> > +
> >> > +
> >> > +/* Same form as PR.  */
> >> > +__attribute__((noipa)) unsigned int foo(int x) {
> >> > +    return (x >= 0 ? x : 0) + (x <= 0 ? -x : 0);
> >> > +}
> >> > +
> >> > +/* Signed function.  */
> >> > +__attribute__((noipa)) int bar(int x) {
> >> > +    return (x >= 0 ? x : 0) + (x <= 0 ? -x : 0);
> >> > +}
> >> > +
> >> > +/* Commutative property.  */
> >> > +__attribute__((noipa)) unsigned int baz(int x) {
> >> > +    return (x <= 0 ? -x : 0) + (x >= 0 ? x : 0);
> >> > +}
> >> > +
> >> > +/* Flipped order for max expressions.  */
> >> > +__attribute__((noipa)) unsigned int quux(int x) {
> >> > +    return (0 <= x ? x : 0) + (0 >= x ? -x : 0);
> >> > +}
> >> > +
> >> > +/* Not zero so should not optimize.  */
> >> > +__attribute__((noipa)) unsigned int waldo(int x) {
> >> > +    return (x >= 4 ? x : 4) + (x <= 4 ? -x : 4);
> >> > +}
> >> > +
> >> > +/* Not zero so should not optimize.  */
> >> > +__attribute__((noipa)) unsigned int fred(int x) {
> >> > +    return (x >= -4 ? x : -4) + (x <= -4 ? -x : -4);
> >> > +}
> >> > +
> >> > +/* Incorrect pattern.  */
> >> > +__attribute__((noipa)) unsigned int goo(int x) {
> >> > +    return (x <= 0 ? x : 0) + (x >= 0 ? -x : 0);
> >> > +}
> >> > +
> >> > +/* Incorrect pattern.  */
> >> > +__attribute__((noipa)) int qux(int x) {
> >> > +    return (x >= 0 ? x : 0) + (x >= 0 ? x : 0);
> >> > +}
> >> > +
> >> > +/* { dg-final {scan-tree-dump-times " ABS_EXPR " 4 "optimized" } } */
> >> >
> >> > base-commit: 6af530f914801f5e561057da55c41480f28751f7
> >> > --
> >> > 2.31.1
> >> >
> >>
>
>
  
Andrew Pinski July 14, 2022, 7:53 p.m. UTC | #6
On Thu, Jul 14, 2022 at 12:38 PM Sam Feifer <sfeifer@redhat.com> wrote:
>
>
>
> On Thu, Jul 14, 2022 at 1:24 PM Andrew Pinski <pinskia@gmail.com> wrote:
>>
>> On Thu, Jul 14, 2022 at 7:09 AM Sam Feifer <sfeifer@redhat.com> wrote:
>> >
>> >
>> > On Wed, Jul 13, 2022 at 3:36 PM Andrew Pinski <pinskia@gmail.com> wrote:
>> >>
>> >> On Wed, Jul 13, 2022 at 12:26 PM Sam Feifer via Gcc-patches
>> >> <gcc-patches@gcc.gnu.org> wrote:
>> >> >
>> >> > This patch is intended to fix a missed optimization in match.pd. It optimizes (x >= 0 ? x : 0) + (x <= 0 ? -x : 0) to just abs(x). I had to write a second simplification in match.pd to handle the commutative property as the match was not ocurring otherwise. Additionally, the pattern (x <= 0 ? -x : 0) now gets optimized to max(-x, 0), which helps with the other simplification rule.
>> >>
>> >> You could use :c for the commutative property instead and that should
>> >> simplify things.
>> >> That is:
>> >>
>> >> (simplify
>> >>   (plus:c (max @0 integer_zerop) (max (negate @0) integer_zerop))
>> >>   (abs @0))
>> >>
>> >> Also since integer_zerop works on vectors, it seems like you should
>> >> add a testcase or two for the vector case.
>> >> Also would be useful if you write a testcase that uses different
>> >> statements rather than one big one so it gets exercised in the
>> >> forwprop case.
>> >> Note also if either of the max are used more than just in this
>> >> simplification, it could increase the lifetime of @0, maybe you need
>> >> to add :s to the max expressions.
>> >>
>> >
>> > Thanks for the feedback. I'm not quite sure what a vector test case would look like for this. Could I get some guidance on that?
>>
>> Yes this should produce the pattern at forwprop1 time (with the C++
>> front-end, the C front-end does not support vector selects):
>> typedef int __attribute__((vector_size(4*sizeof(int)))) vint;
>>
>> vint foo(vint x) {
>>     vint t = (x >= 0 ? x : 0) ;
>>     vint xx = -x;
>>     vint t1 =  (xx >= 0 ? xx : 0);
>>     return t + t1;
>> }
>>
>> int foo(int x) {
>>     int t = (x >= 0 ? x : 0) ;
>>     int xx = -x;
>>     int t1 =  (xx >= 0 ? xx : 0);
>>     return t + t1;
>> }
>>
>> Thanks,
>> Andrew Pinski
>>
>
> Thanks for the help. I'm still having trouble with the vector test, though. When I try to compile, I get an error saying "used vector type where scalar is required", referring to the max expressions. How do I use the max expression with two vectors as the inputs?

As I mentioned it only works with the C++ front-end :). The C
front-end does not support ?: with vectors types.

Thanks,
Andrew Pinski

>
> Thanks
> -Sam
>>
>>
>> >
>> > Thanks
>> > -Sam
>> >
>> >>
>> >> Thanks,
>> >> Andrew
>> >>
>> >> >
>> >> > Tests are also included to be added to the testsuite.
>> >> >
>> >> > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
>> >> >
>> >> >         PR tree-optimization/94290
>> >> >
>> >> > gcc/ChangeLog:
>> >> >
>> >> >         * match.pd (x >= 0 ? x : 0) + (x <= 0 ? -x : 0): New simplification.
>> >> >         * match.pd (x <= 0 ? -x : 0): New Simplification.
>> >> >
>> >> > gcc/testsuite/ChangeLog:
>> >> >
>> >> >         * gcc.c-torture/execute/pr94290-1.c: New test.
>> >> >         * gcc.dg/pr94290-2.c: New test.
>> >> >         * gcc.dg/pr94290.c: New test.
>> >> > ---
>> >> >  gcc/match.pd                                  | 15 ++++++
>> >> >  .../gcc.c-torture/execute/pr94290-1.c         | 16 +++++++
>> >> >  gcc/testsuite/gcc.dg/pr94290-2.c              | 15 ++++++
>> >> >  gcc/testsuite/gcc.dg/pr94290.c                | 46 +++++++++++++++++++
>> >> >  4 files changed, 92 insertions(+)
>> >> >  create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
>> >> >  create mode 100644 gcc/testsuite/gcc.dg/pr94290-2.c
>> >> >  create mode 100644 gcc/testsuite/gcc.dg/pr94290.c
>> >> >
>> >> > diff --git a/gcc/match.pd b/gcc/match.pd
>> >> > index 45aefd96688..55ca79d7ac9 100644
>> >> > --- a/gcc/match.pd
>> >> > +++ b/gcc/match.pd
>> >> > @@ -7848,3 +7848,18 @@ and,
>> >> >        (if (TYPE_UNSIGNED (TREE_TYPE (@0)))
>> >> >          (bit_and @0 @1)
>> >> >        (cond (le @0 @1) @0 (bit_and @0 @1))))))
>> >> > +
>> >> > +/* (x >= 0 ? x : 0) + (x <= 0 ? -x : 0) -> abs x.  */
>> >> > +(simplify
>> >> > +  (plus (max @0 integer_zerop) (max (negate @0) integer_zerop))
>> >> > +  (abs @0))
>> >> > +
>> >> > +/* (x <= 0 ? -x : 0) + (x >= 0 ? x : 0) -> abs x.  */
>> >> > +(simplify
>> >> > +  (plus (max (negate @0) integer_zerop) (max @0 integer_zerop) )
>> >> > +  (abs @0))
>> >> > +
>> >> > +/* (x <= 0 ? -x : 0) -> max(-x, 0).  */
>> >> > +(simplify
>> >> > + (cond (le @0 integer_zerop@1) (negate @0) integer_zerop@1)
>> >> > + (max (negate @0) @1))
>> >> > diff --git a/gcc/testsuite/gcc.c-torture/execute/pr94290-1.c b/gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
>> >> > new file mode 100644
>> >> > index 00000000000..93b80d569aa
>> >> > --- /dev/null
>> >> > +++ b/gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
>> >> > @@ -0,0 +1,16 @@
>> >> > +/* PR tree-optimization/94290 */
>> >> > +
>> >> > +#include "../../gcc.dg/pr94290.c"
>> >> > +
>> >> > +int main() {
>> >> > +
>> >> > +    if (foo(0) != 0
>> >> > +        || foo(-42) != 42
>> >> > +        || foo(42) != 42
>> >> > +        || baz(-10) != 10
>> >> > +        || baz(-10) != 10) {
>> >> > +            __builtin_abort();
>> >> > +        }
>> >> > +
>> >> > +    return 0;
>> >> > +}
>> >> > diff --git a/gcc/testsuite/gcc.dg/pr94290-2.c b/gcc/testsuite/gcc.dg/pr94290-2.c
>> >> > new file mode 100644
>> >> > index 00000000000..ea6e55755f5
>> >> > --- /dev/null
>> >> > +++ b/gcc/testsuite/gcc.dg/pr94290-2.c
>> >> > @@ -0,0 +1,15 @@
>> >> > +/* PR tree-optimization/94290 */
>> >> > +/* { dg-do compile } */
>> >> > +/* { dg-options "-O2 -fdump-tree-optimized" } */
>> >> > +
>> >> > +/* Form from PR.  */
>> >> > +__attribute__((noipa)) unsigned int foo(int x) {
>> >> > +    return x <= 0 ? -x : 0;
>> >> > +}
>> >> > +
>> >> > +/* Changed order.  */
>> >> > +__attribute__((noipa)) unsigned int bar(int x) {
>> >> > +    return 0 >= x ? -x : 0;
>> >> > +}
>> >> > +
>> >> > +/* { dg-final {scan-tree-dump-times " MAX_EXPR " 2 "optimized" } } */
>> >> > diff --git a/gcc/testsuite/gcc.dg/pr94290.c b/gcc/testsuite/gcc.dg/pr94290.c
>> >> > new file mode 100644
>> >> > index 00000000000..47617c36c02
>> >> > --- /dev/null
>> >> > +++ b/gcc/testsuite/gcc.dg/pr94290.c
>> >> > @@ -0,0 +1,46 @@
>> >> > +/* PR tree-optimization/94290 */
>> >> > +/* { dg-do compile } */
>> >> > +/* { dg-options "-O2 -fdump-tree-optimized" } */
>> >> > +
>> >> > +
>> >> > +/* Same form as PR.  */
>> >> > +__attribute__((noipa)) unsigned int foo(int x) {
>> >> > +    return (x >= 0 ? x : 0) + (x <= 0 ? -x : 0);
>> >> > +}
>> >> > +
>> >> > +/* Signed function.  */
>> >> > +__attribute__((noipa)) int bar(int x) {
>> >> > +    return (x >= 0 ? x : 0) + (x <= 0 ? -x : 0);
>> >> > +}
>> >> > +
>> >> > +/* Commutative property.  */
>> >> > +__attribute__((noipa)) unsigned int baz(int x) {
>> >> > +    return (x <= 0 ? -x : 0) + (x >= 0 ? x : 0);
>> >> > +}
>> >> > +
>> >> > +/* Flipped order for max expressions.  */
>> >> > +__attribute__((noipa)) unsigned int quux(int x) {
>> >> > +    return (0 <= x ? x : 0) + (0 >= x ? -x : 0);
>> >> > +}
>> >> > +
>> >> > +/* Not zero so should not optimize.  */
>> >> > +__attribute__((noipa)) unsigned int waldo(int x) {
>> >> > +    return (x >= 4 ? x : 4) + (x <= 4 ? -x : 4);
>> >> > +}
>> >> > +
>> >> > +/* Not zero so should not optimize.  */
>> >> > +__attribute__((noipa)) unsigned int fred(int x) {
>> >> > +    return (x >= -4 ? x : -4) + (x <= -4 ? -x : -4);
>> >> > +}
>> >> > +
>> >> > +/* Incorrect pattern.  */
>> >> > +__attribute__((noipa)) unsigned int goo(int x) {
>> >> > +    return (x <= 0 ? x : 0) + (x >= 0 ? -x : 0);
>> >> > +}
>> >> > +
>> >> > +/* Incorrect pattern.  */
>> >> > +__attribute__((noipa)) int qux(int x) {
>> >> > +    return (x >= 0 ? x : 0) + (x >= 0 ? x : 0);
>> >> > +}
>> >> > +
>> >> > +/* { dg-final {scan-tree-dump-times " ABS_EXPR " 4 "optimized" } } */
>> >> >
>> >> > base-commit: 6af530f914801f5e561057da55c41480f28751f7
>> >> > --
>> >> > 2.31.1
>> >> >
>> >>
>>
  
Sam Feifer July 18, 2022, 1:07 p.m. UTC | #7
Here's an updated version of the patch.

Thanks
-Sam

On Thu, Jul 14, 2022 at 3:54 PM Andrew Pinski <pinskia@gmail.com> wrote:

> On Thu, Jul 14, 2022 at 12:38 PM Sam Feifer <sfeifer@redhat.com> wrote:
> >
> >
> >
> > On Thu, Jul 14, 2022 at 1:24 PM Andrew Pinski <pinskia@gmail.com> wrote:
> >>
> >> On Thu, Jul 14, 2022 at 7:09 AM Sam Feifer <sfeifer@redhat.com> wrote:
> >> >
> >> >
> >> > On Wed, Jul 13, 2022 at 3:36 PM Andrew Pinski <pinskia@gmail.com>
> wrote:
> >> >>
> >> >> On Wed, Jul 13, 2022 at 12:26 PM Sam Feifer via Gcc-patches
> >> >> <gcc-patches@gcc.gnu.org> wrote:
> >> >> >
> >> >> > This patch is intended to fix a missed optimization in match.pd.
> It optimizes (x >= 0 ? x : 0) + (x <= 0 ? -x : 0) to just abs(x). I had to
> write a second simplification in match.pd to handle the commutative
> property as the match was not ocurring otherwise. Additionally, the pattern
> (x <= 0 ? -x : 0) now gets optimized to max(-x, 0), which helps with the
> other simplification rule.
> >> >>
> >> >> You could use :c for the commutative property instead and that should
> >> >> simplify things.
> >> >> That is:
> >> >>
> >> >> (simplify
> >> >>   (plus:c (max @0 integer_zerop) (max (negate @0) integer_zerop))
> >> >>   (abs @0))
> >> >>
> >> >> Also since integer_zerop works on vectors, it seems like you should
> >> >> add a testcase or two for the vector case.
> >> >> Also would be useful if you write a testcase that uses different
> >> >> statements rather than one big one so it gets exercised in the
> >> >> forwprop case.
> >> >> Note also if either of the max are used more than just in this
> >> >> simplification, it could increase the lifetime of @0, maybe you need
> >> >> to add :s to the max expressions.
> >> >>
> >> >
> >> > Thanks for the feedback. I'm not quite sure what a vector test case
> would look like for this. Could I get some guidance on that?
> >>
> >> Yes this should produce the pattern at forwprop1 time (with the C++
> >> front-end, the C front-end does not support vector selects):
> >> typedef int __attribute__((vector_size(4*sizeof(int)))) vint;
> >>
> >> vint foo(vint x) {
> >>     vint t = (x >= 0 ? x : 0) ;
> >>     vint xx = -x;
> >>     vint t1 =  (xx >= 0 ? xx : 0);
> >>     return t + t1;
> >> }
> >>
> >> int foo(int x) {
> >>     int t = (x >= 0 ? x : 0) ;
> >>     int xx = -x;
> >>     int t1 =  (xx >= 0 ? xx : 0);
> >>     return t + t1;
> >> }
> >>
> >> Thanks,
> >> Andrew Pinski
> >>
> >
> > Thanks for the help. I'm still having trouble with the vector test,
> though. When I try to compile, I get an error saying "used vector type
> where scalar is required", referring to the max expressions. How do I use
> the max expression with two vectors as the inputs?
>
> As I mentioned it only works with the C++ front-end :). The C
> front-end does not support ?: with vectors types.
>
> Thanks,
> Andrew Pinski
>
> >
> > Thanks
> > -Sam
> >>
> >>
> >> >
> >> > Thanks
> >> > -Sam
> >> >
> >> >>
> >> >> Thanks,
> >> >> Andrew
> >> >>
> >> >> >
> >> >> > Tests are also included to be added to the testsuite.
> >> >> >
> >> >> > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> >> >> >
> >> >> >         PR tree-optimization/94290
> >> >> >
> >> >> > gcc/ChangeLog:
> >> >> >
> >> >> >         * match.pd (x >= 0 ? x : 0) + (x <= 0 ? -x : 0): New
> simplification.
> >> >> >         * match.pd (x <= 0 ? -x : 0): New Simplification.
> >> >> >
> >> >> > gcc/testsuite/ChangeLog:
> >> >> >
> >> >> >         * gcc.c-torture/execute/pr94290-1.c: New test.
> >> >> >         * gcc.dg/pr94290-2.c: New test.
> >> >> >         * gcc.dg/pr94290.c: New test.
> >> >> > ---
> >> >> >  gcc/match.pd                                  | 15 ++++++
> >> >> >  .../gcc.c-torture/execute/pr94290-1.c         | 16 +++++++
> >> >> >  gcc/testsuite/gcc.dg/pr94290-2.c              | 15 ++++++
> >> >> >  gcc/testsuite/gcc.dg/pr94290.c                | 46
> +++++++++++++++++++
> >> >> >  4 files changed, 92 insertions(+)
> >> >> >  create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
> >> >> >  create mode 100644 gcc/testsuite/gcc.dg/pr94290-2.c
> >> >> >  create mode 100644 gcc/testsuite/gcc.dg/pr94290.c
> >> >> >
> >> >> > diff --git a/gcc/match.pd b/gcc/match.pd
> >> >> > index 45aefd96688..55ca79d7ac9 100644
> >> >> > --- a/gcc/match.pd
> >> >> > +++ b/gcc/match.pd
> >> >> > @@ -7848,3 +7848,18 @@ and,
> >> >> >        (if (TYPE_UNSIGNED (TREE_TYPE (@0)))
> >> >> >          (bit_and @0 @1)
> >> >> >        (cond (le @0 @1) @0 (bit_and @0 @1))))))
> >> >> > +
> >> >> > +/* (x >= 0 ? x : 0) + (x <= 0 ? -x : 0) -> abs x.  */
> >> >> > +(simplify
> >> >> > +  (plus (max @0 integer_zerop) (max (negate @0) integer_zerop))
> >> >> > +  (abs @0))
> >> >> > +
> >> >> > +/* (x <= 0 ? -x : 0) + (x >= 0 ? x : 0) -> abs x.  */
> >> >> > +(simplify
> >> >> > +  (plus (max (negate @0) integer_zerop) (max @0 integer_zerop) )
> >> >> > +  (abs @0))
> >> >> > +
> >> >> > +/* (x <= 0 ? -x : 0) -> max(-x, 0).  */
> >> >> > +(simplify
> >> >> > + (cond (le @0 integer_zerop@1) (negate @0) integer_zerop@1)
> >> >> > + (max (negate @0) @1))
> >> >> > diff --git a/gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
> b/gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
> >> >> > new file mode 100644
> >> >> > index 00000000000..93b80d569aa
> >> >> > --- /dev/null
> >> >> > +++ b/gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
> >> >> > @@ -0,0 +1,16 @@
> >> >> > +/* PR tree-optimization/94290 */
> >> >> > +
> >> >> > +#include "../../gcc.dg/pr94290.c"
> >> >> > +
> >> >> > +int main() {
> >> >> > +
> >> >> > +    if (foo(0) != 0
> >> >> > +        || foo(-42) != 42
> >> >> > +        || foo(42) != 42
> >> >> > +        || baz(-10) != 10
> >> >> > +        || baz(-10) != 10) {
> >> >> > +            __builtin_abort();
> >> >> > +        }
> >> >> > +
> >> >> > +    return 0;
> >> >> > +}
> >> >> > diff --git a/gcc/testsuite/gcc.dg/pr94290-2.c
> b/gcc/testsuite/gcc.dg/pr94290-2.c
> >> >> > new file mode 100644
> >> >> > index 00000000000..ea6e55755f5
> >> >> > --- /dev/null
> >> >> > +++ b/gcc/testsuite/gcc.dg/pr94290-2.c
> >> >> > @@ -0,0 +1,15 @@
> >> >> > +/* PR tree-optimization/94290 */
> >> >> > +/* { dg-do compile } */
> >> >> > +/* { dg-options "-O2 -fdump-tree-optimized" } */
> >> >> > +
> >> >> > +/* Form from PR.  */
> >> >> > +__attribute__((noipa)) unsigned int foo(int x) {
> >> >> > +    return x <= 0 ? -x : 0;
> >> >> > +}
> >> >> > +
> >> >> > +/* Changed order.  */
> >> >> > +__attribute__((noipa)) unsigned int bar(int x) {
> >> >> > +    return 0 >= x ? -x : 0;
> >> >> > +}
> >> >> > +
> >> >> > +/* { dg-final {scan-tree-dump-times " MAX_EXPR " 2 "optimized" }
> } */
> >> >> > diff --git a/gcc/testsuite/gcc.dg/pr94290.c
> b/gcc/testsuite/gcc.dg/pr94290.c
> >> >> > new file mode 100644
> >> >> > index 00000000000..47617c36c02
> >> >> > --- /dev/null
> >> >> > +++ b/gcc/testsuite/gcc.dg/pr94290.c
> >> >> > @@ -0,0 +1,46 @@
> >> >> > +/* PR tree-optimization/94290 */
> >> >> > +/* { dg-do compile } */
> >> >> > +/* { dg-options "-O2 -fdump-tree-optimized" } */
> >> >> > +
> >> >> > +
> >> >> > +/* Same form as PR.  */
> >> >> > +__attribute__((noipa)) unsigned int foo(int x) {
> >> >> > +    return (x >= 0 ? x : 0) + (x <= 0 ? -x : 0);
> >> >> > +}
> >> >> > +
> >> >> > +/* Signed function.  */
> >> >> > +__attribute__((noipa)) int bar(int x) {
> >> >> > +    return (x >= 0 ? x : 0) + (x <= 0 ? -x : 0);
> >> >> > +}
> >> >> > +
> >> >> > +/* Commutative property.  */
> >> >> > +__attribute__((noipa)) unsigned int baz(int x) {
> >> >> > +    return (x <= 0 ? -x : 0) + (x >= 0 ? x : 0);
> >> >> > +}
> >> >> > +
> >> >> > +/* Flipped order for max expressions.  */
> >> >> > +__attribute__((noipa)) unsigned int quux(int x) {
> >> >> > +    return (0 <= x ? x : 0) + (0 >= x ? -x : 0);
> >> >> > +}
> >> >> > +
> >> >> > +/* Not zero so should not optimize.  */
> >> >> > +__attribute__((noipa)) unsigned int waldo(int x) {
> >> >> > +    return (x >= 4 ? x : 4) + (x <= 4 ? -x : 4);
> >> >> > +}
> >> >> > +
> >> >> > +/* Not zero so should not optimize.  */
> >> >> > +__attribute__((noipa)) unsigned int fred(int x) {
> >> >> > +    return (x >= -4 ? x : -4) + (x <= -4 ? -x : -4);
> >> >> > +}
> >> >> > +
> >> >> > +/* Incorrect pattern.  */
> >> >> > +__attribute__((noipa)) unsigned int goo(int x) {
> >> >> > +    return (x <= 0 ? x : 0) + (x >= 0 ? -x : 0);
> >> >> > +}
> >> >> > +
> >> >> > +/* Incorrect pattern.  */
> >> >> > +__attribute__((noipa)) int qux(int x) {
> >> >> > +    return (x >= 0 ? x : 0) + (x >= 0 ? x : 0);
> >> >> > +}
> >> >> > +
> >> >> > +/* { dg-final {scan-tree-dump-times " ABS_EXPR " 4 "optimized" }
> } */
> >> >> >
> >> >> > base-commit: 6af530f914801f5e561057da55c41480f28751f7
> >> >> > --
> >> >> > 2.31.1
> >> >> >
> >> >>
> >>
>
>
  
Sam Feifer July 18, 2022, 5:30 p.m. UTC | #8
Just realized I had mixed up the 9 and the 2 when labelling the patch. This
patch is referring to pr94920 not pr94290. Attached is a fixed patch file.
Sorry for any confusion.

On Mon, Jul 18, 2022 at 9:07 AM Sam Feifer <sfeifer@redhat.com> wrote:

> Here's an updated version of the patch.
>
> Thanks
> -Sam
>
> On Thu, Jul 14, 2022 at 3:54 PM Andrew Pinski <pinskia@gmail.com> wrote:
>
>> On Thu, Jul 14, 2022 at 12:38 PM Sam Feifer <sfeifer@redhat.com> wrote:
>> >
>> >
>> >
>> > On Thu, Jul 14, 2022 at 1:24 PM Andrew Pinski <pinskia@gmail.com>
>> wrote:
>> >>
>> >> On Thu, Jul 14, 2022 at 7:09 AM Sam Feifer <sfeifer@redhat.com> wrote:
>> >> >
>> >> >
>> >> > On Wed, Jul 13, 2022 at 3:36 PM Andrew Pinski <pinskia@gmail.com>
>> wrote:
>> >> >>
>> >> >> On Wed, Jul 13, 2022 at 12:26 PM Sam Feifer via Gcc-patches
>> >> >> <gcc-patches@gcc.gnu.org> wrote:
>> >> >> >
>> >> >> > This patch is intended to fix a missed optimization in match.pd.
>> It optimizes (x >= 0 ? x : 0) + (x <= 0 ? -x : 0) to just abs(x). I had to
>> write a second simplification in match.pd to handle the commutative
>> property as the match was not ocurring otherwise. Additionally, the pattern
>> (x <= 0 ? -x : 0) now gets optimized to max(-x, 0), which helps with the
>> other simplification rule.
>> >> >>
>> >> >> You could use :c for the commutative property instead and that
>> should
>> >> >> simplify things.
>> >> >> That is:
>> >> >>
>> >> >> (simplify
>> >> >>   (plus:c (max @0 integer_zerop) (max (negate @0) integer_zerop))
>> >> >>   (abs @0))
>> >> >>
>> >> >> Also since integer_zerop works on vectors, it seems like you should
>> >> >> add a testcase or two for the vector case.
>> >> >> Also would be useful if you write a testcase that uses different
>> >> >> statements rather than one big one so it gets exercised in the
>> >> >> forwprop case.
>> >> >> Note also if either of the max are used more than just in this
>> >> >> simplification, it could increase the lifetime of @0, maybe you need
>> >> >> to add :s to the max expressions.
>> >> >>
>> >> >
>> >> > Thanks for the feedback. I'm not quite sure what a vector test case
>> would look like for this. Could I get some guidance on that?
>> >>
>> >> Yes this should produce the pattern at forwprop1 time (with the C++
>> >> front-end, the C front-end does not support vector selects):
>> >> typedef int __attribute__((vector_size(4*sizeof(int)))) vint;
>> >>
>> >> vint foo(vint x) {
>> >>     vint t = (x >= 0 ? x : 0) ;
>> >>     vint xx = -x;
>> >>     vint t1 =  (xx >= 0 ? xx : 0);
>> >>     return t + t1;
>> >> }
>> >>
>> >> int foo(int x) {
>> >>     int t = (x >= 0 ? x : 0) ;
>> >>     int xx = -x;
>> >>     int t1 =  (xx >= 0 ? xx : 0);
>> >>     return t + t1;
>> >> }
>> >>
>> >> Thanks,
>> >> Andrew Pinski
>> >>
>> >
>> > Thanks for the help. I'm still having trouble with the vector test,
>> though. When I try to compile, I get an error saying "used vector type
>> where scalar is required", referring to the max expressions. How do I use
>> the max expression with two vectors as the inputs?
>>
>> As I mentioned it only works with the C++ front-end :). The C
>> front-end does not support ?: with vectors types.
>>
>> Thanks,
>> Andrew Pinski
>>
>> >
>> > Thanks
>> > -Sam
>> >>
>> >>
>> >> >
>> >> > Thanks
>> >> > -Sam
>> >> >
>> >> >>
>> >> >> Thanks,
>> >> >> Andrew
>> >> >>
>> >> >> >
>> >> >> > Tests are also included to be added to the testsuite.
>> >> >> >
>> >> >> > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
>> >> >> >
>> >> >> >         PR tree-optimization/94290
>> >> >> >
>> >> >> > gcc/ChangeLog:
>> >> >> >
>> >> >> >         * match.pd (x >= 0 ? x : 0) + (x <= 0 ? -x : 0): New
>> simplification.
>> >> >> >         * match.pd (x <= 0 ? -x : 0): New Simplification.
>> >> >> >
>> >> >> > gcc/testsuite/ChangeLog:
>> >> >> >
>> >> >> >         * gcc.c-torture/execute/pr94290-1.c: New test.
>> >> >> >         * gcc.dg/pr94290-2.c: New test.
>> >> >> >         * gcc.dg/pr94290.c: New test.
>> >> >> > ---
>> >> >> >  gcc/match.pd                                  | 15 ++++++
>> >> >> >  .../gcc.c-torture/execute/pr94290-1.c         | 16 +++++++
>> >> >> >  gcc/testsuite/gcc.dg/pr94290-2.c              | 15 ++++++
>> >> >> >  gcc/testsuite/gcc.dg/pr94290.c                | 46
>> +++++++++++++++++++
>> >> >> >  4 files changed, 92 insertions(+)
>> >> >> >  create mode 100644
>> gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
>> >> >> >  create mode 100644 gcc/testsuite/gcc.dg/pr94290-2.c
>> >> >> >  create mode 100644 gcc/testsuite/gcc.dg/pr94290.c
>> >> >> >
>> >> >> > diff --git a/gcc/match.pd b/gcc/match.pd
>> >> >> > index 45aefd96688..55ca79d7ac9 100644
>> >> >> > --- a/gcc/match.pd
>> >> >> > +++ b/gcc/match.pd
>> >> >> > @@ -7848,3 +7848,18 @@ and,
>> >> >> >        (if (TYPE_UNSIGNED (TREE_TYPE (@0)))
>> >> >> >          (bit_and @0 @1)
>> >> >> >        (cond (le @0 @1) @0 (bit_and @0 @1))))))
>> >> >> > +
>> >> >> > +/* (x >= 0 ? x : 0) + (x <= 0 ? -x : 0) -> abs x.  */
>> >> >> > +(simplify
>> >> >> > +  (plus (max @0 integer_zerop) (max (negate @0) integer_zerop))
>> >> >> > +  (abs @0))
>> >> >> > +
>> >> >> > +/* (x <= 0 ? -x : 0) + (x >= 0 ? x : 0) -> abs x.  */
>> >> >> > +(simplify
>> >> >> > +  (plus (max (negate @0) integer_zerop) (max @0 integer_zerop) )
>> >> >> > +  (abs @0))
>> >> >> > +
>> >> >> > +/* (x <= 0 ? -x : 0) -> max(-x, 0).  */
>> >> >> > +(simplify
>> >> >> > + (cond (le @0 integer_zerop@1) (negate @0) integer_zerop@1)
>> >> >> > + (max (negate @0) @1))
>> >> >> > diff --git a/gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
>> b/gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
>> >> >> > new file mode 100644
>> >> >> > index 00000000000..93b80d569aa
>> >> >> > --- /dev/null
>> >> >> > +++ b/gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
>> >> >> > @@ -0,0 +1,16 @@
>> >> >> > +/* PR tree-optimization/94290 */
>> >> >> > +
>> >> >> > +#include "../../gcc.dg/pr94290.c"
>> >> >> > +
>> >> >> > +int main() {
>> >> >> > +
>> >> >> > +    if (foo(0) != 0
>> >> >> > +        || foo(-42) != 42
>> >> >> > +        || foo(42) != 42
>> >> >> > +        || baz(-10) != 10
>> >> >> > +        || baz(-10) != 10) {
>> >> >> > +            __builtin_abort();
>> >> >> > +        }
>> >> >> > +
>> >> >> > +    return 0;
>> >> >> > +}
>> >> >> > diff --git a/gcc/testsuite/gcc.dg/pr94290-2.c
>> b/gcc/testsuite/gcc.dg/pr94290-2.c
>> >> >> > new file mode 100644
>> >> >> > index 00000000000..ea6e55755f5
>> >> >> > --- /dev/null
>> >> >> > +++ b/gcc/testsuite/gcc.dg/pr94290-2.c
>> >> >> > @@ -0,0 +1,15 @@
>> >> >> > +/* PR tree-optimization/94290 */
>> >> >> > +/* { dg-do compile } */
>> >> >> > +/* { dg-options "-O2 -fdump-tree-optimized" } */
>> >> >> > +
>> >> >> > +/* Form from PR.  */
>> >> >> > +__attribute__((noipa)) unsigned int foo(int x) {
>> >> >> > +    return x <= 0 ? -x : 0;
>> >> >> > +}
>> >> >> > +
>> >> >> > +/* Changed order.  */
>> >> >> > +__attribute__((noipa)) unsigned int bar(int x) {
>> >> >> > +    return 0 >= x ? -x : 0;
>> >> >> > +}
>> >> >> > +
>> >> >> > +/* { dg-final {scan-tree-dump-times " MAX_EXPR " 2 "optimized" }
>> } */
>> >> >> > diff --git a/gcc/testsuite/gcc.dg/pr94290.c
>> b/gcc/testsuite/gcc.dg/pr94290.c
>> >> >> > new file mode 100644
>> >> >> > index 00000000000..47617c36c02
>> >> >> > --- /dev/null
>> >> >> > +++ b/gcc/testsuite/gcc.dg/pr94290.c
>> >> >> > @@ -0,0 +1,46 @@
>> >> >> > +/* PR tree-optimization/94290 */
>> >> >> > +/* { dg-do compile } */
>> >> >> > +/* { dg-options "-O2 -fdump-tree-optimized" } */
>> >> >> > +
>> >> >> > +
>> >> >> > +/* Same form as PR.  */
>> >> >> > +__attribute__((noipa)) unsigned int foo(int x) {
>> >> >> > +    return (x >= 0 ? x : 0) + (x <= 0 ? -x : 0);
>> >> >> > +}
>> >> >> > +
>> >> >> > +/* Signed function.  */
>> >> >> > +__attribute__((noipa)) int bar(int x) {
>> >> >> > +    return (x >= 0 ? x : 0) + (x <= 0 ? -x : 0);
>> >> >> > +}
>> >> >> > +
>> >> >> > +/* Commutative property.  */
>> >> >> > +__attribute__((noipa)) unsigned int baz(int x) {
>> >> >> > +    return (x <= 0 ? -x : 0) + (x >= 0 ? x : 0);
>> >> >> > +}
>> >> >> > +
>> >> >> > +/* Flipped order for max expressions.  */
>> >> >> > +__attribute__((noipa)) unsigned int quux(int x) {
>> >> >> > +    return (0 <= x ? x : 0) + (0 >= x ? -x : 0);
>> >> >> > +}
>> >> >> > +
>> >> >> > +/* Not zero so should not optimize.  */
>> >> >> > +__attribute__((noipa)) unsigned int waldo(int x) {
>> >> >> > +    return (x >= 4 ? x : 4) + (x <= 4 ? -x : 4);
>> >> >> > +}
>> >> >> > +
>> >> >> > +/* Not zero so should not optimize.  */
>> >> >> > +__attribute__((noipa)) unsigned int fred(int x) {
>> >> >> > +    return (x >= -4 ? x : -4) + (x <= -4 ? -x : -4);
>> >> >> > +}
>> >> >> > +
>> >> >> > +/* Incorrect pattern.  */
>> >> >> > +__attribute__((noipa)) unsigned int goo(int x) {
>> >> >> > +    return (x <= 0 ? x : 0) + (x >= 0 ? -x : 0);
>> >> >> > +}
>> >> >> > +
>> >> >> > +/* Incorrect pattern.  */
>> >> >> > +__attribute__((noipa)) int qux(int x) {
>> >> >> > +    return (x >= 0 ? x : 0) + (x >= 0 ? x : 0);
>> >> >> > +}
>> >> >> > +
>> >> >> > +/* { dg-final {scan-tree-dump-times " ABS_EXPR " 4 "optimized" }
>> } */
>> >> >> >
>> >> >> > base-commit: 6af530f914801f5e561057da55c41480f28751f7
>> >> >> > --
>> >> >> > 2.31.1
>> >> >> >
>> >> >>
>> >>
>>
>>
  
Richard Biener July 19, 2022, 6:36 a.m. UTC | #9
On Mon, Jul 18, 2022 at 7:31 PM Sam Feifer via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> Just realized I had mixed up the 9 and the 2 when labelling the patch. This
> patch is referring to pr94920 not pr94290. Attached is a fixed patch file.
> Sorry for any confusion.

Can you put the patterns somewhere related?  The abs producing one
seems to fit around line 323, the max producing before line 3415?

+/* (x <= 0 ? -x : 0) -> max(-x, 0).  */
+(simplify
+  (cond (le @0 integer_zerop@1) (negate @0) integer_zerop@1)
+  (max (negate @0) @1))

you can re-use the existing (negate @0) in the result by doing

+/* (x <= 0 ? -x : 0) -> max(-x, 0).  */
+(simplify
+  (cond (le @0 integer_zerop@1) (negate@2 @0) integer_zerop@1)
+  (max @2 @1))

OK with those changes.

Thanks,
Richard.

> On Mon, Jul 18, 2022 at 9:07 AM Sam Feifer <sfeifer@redhat.com> wrote:
>
> > Here's an updated version of the patch.
> >
> > Thanks
> > -Sam
> >
> > On Thu, Jul 14, 2022 at 3:54 PM Andrew Pinski <pinskia@gmail.com> wrote:
> >
> >> On Thu, Jul 14, 2022 at 12:38 PM Sam Feifer <sfeifer@redhat.com> wrote:
> >> >
> >> >
> >> >
> >> > On Thu, Jul 14, 2022 at 1:24 PM Andrew Pinski <pinskia@gmail.com>
> >> wrote:
> >> >>
> >> >> On Thu, Jul 14, 2022 at 7:09 AM Sam Feifer <sfeifer@redhat.com> wrote:
> >> >> >
> >> >> >
> >> >> > On Wed, Jul 13, 2022 at 3:36 PM Andrew Pinski <pinskia@gmail.com>
> >> wrote:
> >> >> >>
> >> >> >> On Wed, Jul 13, 2022 at 12:26 PM Sam Feifer via Gcc-patches
> >> >> >> <gcc-patches@gcc.gnu.org> wrote:
> >> >> >> >
> >> >> >> > This patch is intended to fix a missed optimization in match.pd.
> >> It optimizes (x >= 0 ? x : 0) + (x <= 0 ? -x : 0) to just abs(x). I had to
> >> write a second simplification in match.pd to handle the commutative
> >> property as the match was not ocurring otherwise. Additionally, the pattern
> >> (x <= 0 ? -x : 0) now gets optimized to max(-x, 0), which helps with the
> >> other simplification rule.
> >> >> >>
> >> >> >> You could use :c for the commutative property instead and that
> >> should
> >> >> >> simplify things.
> >> >> >> That is:
> >> >> >>
> >> >> >> (simplify
> >> >> >>   (plus:c (max @0 integer_zerop) (max (negate @0) integer_zerop))
> >> >> >>   (abs @0))
> >> >> >>
> >> >> >> Also since integer_zerop works on vectors, it seems like you should
> >> >> >> add a testcase or two for the vector case.
> >> >> >> Also would be useful if you write a testcase that uses different
> >> >> >> statements rather than one big one so it gets exercised in the
> >> >> >> forwprop case.
> >> >> >> Note also if either of the max are used more than just in this
> >> >> >> simplification, it could increase the lifetime of @0, maybe you need
> >> >> >> to add :s to the max expressions.
> >> >> >>
> >> >> >
> >> >> > Thanks for the feedback. I'm not quite sure what a vector test case
> >> would look like for this. Could I get some guidance on that?
> >> >>
> >> >> Yes this should produce the pattern at forwprop1 time (with the C++
> >> >> front-end, the C front-end does not support vector selects):
> >> >> typedef int __attribute__((vector_size(4*sizeof(int)))) vint;
> >> >>
> >> >> vint foo(vint x) {
> >> >>     vint t = (x >= 0 ? x : 0) ;
> >> >>     vint xx = -x;
> >> >>     vint t1 =  (xx >= 0 ? xx : 0);
> >> >>     return t + t1;
> >> >> }
> >> >>
> >> >> int foo(int x) {
> >> >>     int t = (x >= 0 ? x : 0) ;
> >> >>     int xx = -x;
> >> >>     int t1 =  (xx >= 0 ? xx : 0);
> >> >>     return t + t1;
> >> >> }
> >> >>
> >> >> Thanks,
> >> >> Andrew Pinski
> >> >>
> >> >
> >> > Thanks for the help. I'm still having trouble with the vector test,
> >> though. When I try to compile, I get an error saying "used vector type
> >> where scalar is required", referring to the max expressions. How do I use
> >> the max expression with two vectors as the inputs?
> >>
> >> As I mentioned it only works with the C++ front-end :). The C
> >> front-end does not support ?: with vectors types.
> >>
> >> Thanks,
> >> Andrew Pinski
> >>
> >> >
> >> > Thanks
> >> > -Sam
> >> >>
> >> >>
> >> >> >
> >> >> > Thanks
> >> >> > -Sam
> >> >> >
> >> >> >>
> >> >> >> Thanks,
> >> >> >> Andrew
> >> >> >>
> >> >> >> >
> >> >> >> > Tests are also included to be added to the testsuite.
> >> >> >> >
> >> >> >> > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> >> >> >> >
> >> >> >> >         PR tree-optimization/94290
> >> >> >> >
> >> >> >> > gcc/ChangeLog:
> >> >> >> >
> >> >> >> >         * match.pd (x >= 0 ? x : 0) + (x <= 0 ? -x : 0): New
> >> simplification.
> >> >> >> >         * match.pd (x <= 0 ? -x : 0): New Simplification.
> >> >> >> >
> >> >> >> > gcc/testsuite/ChangeLog:
> >> >> >> >
> >> >> >> >         * gcc.c-torture/execute/pr94290-1.c: New test.
> >> >> >> >         * gcc.dg/pr94290-2.c: New test.
> >> >> >> >         * gcc.dg/pr94290.c: New test.
> >> >> >> > ---
> >> >> >> >  gcc/match.pd                                  | 15 ++++++
> >> >> >> >  .../gcc.c-torture/execute/pr94290-1.c         | 16 +++++++
> >> >> >> >  gcc/testsuite/gcc.dg/pr94290-2.c              | 15 ++++++
> >> >> >> >  gcc/testsuite/gcc.dg/pr94290.c                | 46
> >> +++++++++++++++++++
> >> >> >> >  4 files changed, 92 insertions(+)
> >> >> >> >  create mode 100644
> >> gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
> >> >> >> >  create mode 100644 gcc/testsuite/gcc.dg/pr94290-2.c
> >> >> >> >  create mode 100644 gcc/testsuite/gcc.dg/pr94290.c
> >> >> >> >
> >> >> >> > diff --git a/gcc/match.pd b/gcc/match.pd
> >> >> >> > index 45aefd96688..55ca79d7ac9 100644
> >> >> >> > --- a/gcc/match.pd
> >> >> >> > +++ b/gcc/match.pd
> >> >> >> > @@ -7848,3 +7848,18 @@ and,
> >> >> >> >        (if (TYPE_UNSIGNED (TREE_TYPE (@0)))
> >> >> >> >          (bit_and @0 @1)
> >> >> >> >        (cond (le @0 @1) @0 (bit_and @0 @1))))))
> >> >> >> > +
> >> >> >> > +/* (x >= 0 ? x : 0) + (x <= 0 ? -x : 0) -> abs x.  */
> >> >> >> > +(simplify
> >> >> >> > +  (plus (max @0 integer_zerop) (max (negate @0) integer_zerop))
> >> >> >> > +  (abs @0))
> >> >> >> > +
> >> >> >> > +/* (x <= 0 ? -x : 0) + (x >= 0 ? x : 0) -> abs x.  */
> >> >> >> > +(simplify
> >> >> >> > +  (plus (max (negate @0) integer_zerop) (max @0 integer_zerop) )
> >> >> >> > +  (abs @0))
> >> >> >> > +
> >> >> >> > +/* (x <= 0 ? -x : 0) -> max(-x, 0).  */
> >> >> >> > +(simplify
> >> >> >> > + (cond (le @0 integer_zerop@1) (negate @0) integer_zerop@1)
> >> >> >> > + (max (negate @0) @1))
> >> >> >> > diff --git a/gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
> >> b/gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
> >> >> >> > new file mode 100644
> >> >> >> > index 00000000000..93b80d569aa
> >> >> >> > --- /dev/null
> >> >> >> > +++ b/gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
> >> >> >> > @@ -0,0 +1,16 @@
> >> >> >> > +/* PR tree-optimization/94290 */
> >> >> >> > +
> >> >> >> > +#include "../../gcc.dg/pr94290.c"
> >> >> >> > +
> >> >> >> > +int main() {
> >> >> >> > +
> >> >> >> > +    if (foo(0) != 0
> >> >> >> > +        || foo(-42) != 42
> >> >> >> > +        || foo(42) != 42
> >> >> >> > +        || baz(-10) != 10
> >> >> >> > +        || baz(-10) != 10) {
> >> >> >> > +            __builtin_abort();
> >> >> >> > +        }
> >> >> >> > +
> >> >> >> > +    return 0;
> >> >> >> > +}
> >> >> >> > diff --git a/gcc/testsuite/gcc.dg/pr94290-2.c
> >> b/gcc/testsuite/gcc.dg/pr94290-2.c
> >> >> >> > new file mode 100644
> >> >> >> > index 00000000000..ea6e55755f5
> >> >> >> > --- /dev/null
> >> >> >> > +++ b/gcc/testsuite/gcc.dg/pr94290-2.c
> >> >> >> > @@ -0,0 +1,15 @@
> >> >> >> > +/* PR tree-optimization/94290 */
> >> >> >> > +/* { dg-do compile } */
> >> >> >> > +/* { dg-options "-O2 -fdump-tree-optimized" } */
> >> >> >> > +
> >> >> >> > +/* Form from PR.  */
> >> >> >> > +__attribute__((noipa)) unsigned int foo(int x) {
> >> >> >> > +    return x <= 0 ? -x : 0;
> >> >> >> > +}
> >> >> >> > +
> >> >> >> > +/* Changed order.  */
> >> >> >> > +__attribute__((noipa)) unsigned int bar(int x) {
> >> >> >> > +    return 0 >= x ? -x : 0;
> >> >> >> > +}
> >> >> >> > +
> >> >> >> > +/* { dg-final {scan-tree-dump-times " MAX_EXPR " 2 "optimized" }
> >> } */
> >> >> >> > diff --git a/gcc/testsuite/gcc.dg/pr94290.c
> >> b/gcc/testsuite/gcc.dg/pr94290.c
> >> >> >> > new file mode 100644
> >> >> >> > index 00000000000..47617c36c02
> >> >> >> > --- /dev/null
> >> >> >> > +++ b/gcc/testsuite/gcc.dg/pr94290.c
> >> >> >> > @@ -0,0 +1,46 @@
> >> >> >> > +/* PR tree-optimization/94290 */
> >> >> >> > +/* { dg-do compile } */
> >> >> >> > +/* { dg-options "-O2 -fdump-tree-optimized" } */
> >> >> >> > +
> >> >> >> > +
> >> >> >> > +/* Same form as PR.  */
> >> >> >> > +__attribute__((noipa)) unsigned int foo(int x) {
> >> >> >> > +    return (x >= 0 ? x : 0) + (x <= 0 ? -x : 0);
> >> >> >> > +}
> >> >> >> > +
> >> >> >> > +/* Signed function.  */
> >> >> >> > +__attribute__((noipa)) int bar(int x) {
> >> >> >> > +    return (x >= 0 ? x : 0) + (x <= 0 ? -x : 0);
> >> >> >> > +}
> >> >> >> > +
> >> >> >> > +/* Commutative property.  */
> >> >> >> > +__attribute__((noipa)) unsigned int baz(int x) {
> >> >> >> > +    return (x <= 0 ? -x : 0) + (x >= 0 ? x : 0);
> >> >> >> > +}
> >> >> >> > +
> >> >> >> > +/* Flipped order for max expressions.  */
> >> >> >> > +__attribute__((noipa)) unsigned int quux(int x) {
> >> >> >> > +    return (0 <= x ? x : 0) + (0 >= x ? -x : 0);
> >> >> >> > +}
> >> >> >> > +
> >> >> >> > +/* Not zero so should not optimize.  */
> >> >> >> > +__attribute__((noipa)) unsigned int waldo(int x) {
> >> >> >> > +    return (x >= 4 ? x : 4) + (x <= 4 ? -x : 4);
> >> >> >> > +}
> >> >> >> > +
> >> >> >> > +/* Not zero so should not optimize.  */
> >> >> >> > +__attribute__((noipa)) unsigned int fred(int x) {
> >> >> >> > +    return (x >= -4 ? x : -4) + (x <= -4 ? -x : -4);
> >> >> >> > +}
> >> >> >> > +
> >> >> >> > +/* Incorrect pattern.  */
> >> >> >> > +__attribute__((noipa)) unsigned int goo(int x) {
> >> >> >> > +    return (x <= 0 ? x : 0) + (x >= 0 ? -x : 0);
> >> >> >> > +}
> >> >> >> > +
> >> >> >> > +/* Incorrect pattern.  */
> >> >> >> > +__attribute__((noipa)) int qux(int x) {
> >> >> >> > +    return (x >= 0 ? x : 0) + (x >= 0 ? x : 0);
> >> >> >> > +}
> >> >> >> > +
> >> >> >> > +/* { dg-final {scan-tree-dump-times " ABS_EXPR " 4 "optimized" }
> >> } */
> >> >> >> >
> >> >> >> > base-commit: 6af530f914801f5e561057da55c41480f28751f7
> >> >> >> > --
> >> >> >> > 2.31.1
> >> >> >> >
> >> >> >>
> >> >>
> >>
> >>
  
Sam Feifer July 19, 2022, 1:48 p.m. UTC | #10
Attached is a patch file with those changes.

Thanks
-Sam

On Tue, Jul 19, 2022 at 2:36 AM Richard Biener <richard.guenther@gmail.com>
wrote:

> On Mon, Jul 18, 2022 at 7:31 PM Sam Feifer via Gcc-patches
> <gcc-patches@gcc.gnu.org> wrote:
> >
> > Just realized I had mixed up the 9 and the 2 when labelling the patch.
> This
> > patch is referring to pr94920 not pr94290. Attached is a fixed patch
> file.
> > Sorry for any confusion.
>
> Can you put the patterns somewhere related?  The abs producing one
> seems to fit around line 323, the max producing before line 3415?
>
> +/* (x <= 0 ? -x : 0) -> max(-x, 0).  */
> +(simplify
> +  (cond (le @0 integer_zerop@1) (negate @0) integer_zerop@1)
> +  (max (negate @0) @1))
>
> you can re-use the existing (negate @0) in the result by doing
>
> +/* (x <= 0 ? -x : 0) -> max(-x, 0).  */
> +(simplify
> +  (cond (le @0 integer_zerop@1) (negate@2 @0) integer_zerop@1)
> +  (max @2 @1))
>
> OK with those changes.
>
> Thanks,
> Richard.
>
> > On Mon, Jul 18, 2022 at 9:07 AM Sam Feifer <sfeifer@redhat.com> wrote:
> >
> > > Here's an updated version of the patch.
> > >
> > > Thanks
> > > -Sam
> > >
> > > On Thu, Jul 14, 2022 at 3:54 PM Andrew Pinski <pinskia@gmail.com>
> wrote:
> > >
> > >> On Thu, Jul 14, 2022 at 12:38 PM Sam Feifer <sfeifer@redhat.com>
> wrote:
> > >> >
> > >> >
> > >> >
> > >> > On Thu, Jul 14, 2022 at 1:24 PM Andrew Pinski <pinskia@gmail.com>
> > >> wrote:
> > >> >>
> > >> >> On Thu, Jul 14, 2022 at 7:09 AM Sam Feifer <sfeifer@redhat.com>
> wrote:
> > >> >> >
> > >> >> >
> > >> >> > On Wed, Jul 13, 2022 at 3:36 PM Andrew Pinski <pinskia@gmail.com
> >
> > >> wrote:
> > >> >> >>
> > >> >> >> On Wed, Jul 13, 2022 at 12:26 PM Sam Feifer via Gcc-patches
> > >> >> >> <gcc-patches@gcc.gnu.org> wrote:
> > >> >> >> >
> > >> >> >> > This patch is intended to fix a missed optimization in
> match.pd.
> > >> It optimizes (x >= 0 ? x : 0) + (x <= 0 ? -x : 0) to just abs(x). I
> had to
> > >> write a second simplification in match.pd to handle the commutative
> > >> property as the match was not ocurring otherwise. Additionally, the
> pattern
> > >> (x <= 0 ? -x : 0) now gets optimized to max(-x, 0), which helps with
> the
> > >> other simplification rule.
> > >> >> >>
> > >> >> >> You could use :c for the commutative property instead and that
> > >> should
> > >> >> >> simplify things.
> > >> >> >> That is:
> > >> >> >>
> > >> >> >> (simplify
> > >> >> >>   (plus:c (max @0 integer_zerop) (max (negate @0)
> integer_zerop))
> > >> >> >>   (abs @0))
> > >> >> >>
> > >> >> >> Also since integer_zerop works on vectors, it seems like you
> should
> > >> >> >> add a testcase or two for the vector case.
> > >> >> >> Also would be useful if you write a testcase that uses different
> > >> >> >> statements rather than one big one so it gets exercised in the
> > >> >> >> forwprop case.
> > >> >> >> Note also if either of the max are used more than just in this
> > >> >> >> simplification, it could increase the lifetime of @0, maybe you
> need
> > >> >> >> to add :s to the max expressions.
> > >> >> >>
> > >> >> >
> > >> >> > Thanks for the feedback. I'm not quite sure what a vector test
> case
> > >> would look like for this. Could I get some guidance on that?
> > >> >>
> > >> >> Yes this should produce the pattern at forwprop1 time (with the C++
> > >> >> front-end, the C front-end does not support vector selects):
> > >> >> typedef int __attribute__((vector_size(4*sizeof(int)))) vint;
> > >> >>
> > >> >> vint foo(vint x) {
> > >> >>     vint t = (x >= 0 ? x : 0) ;
> > >> >>     vint xx = -x;
> > >> >>     vint t1 =  (xx >= 0 ? xx : 0);
> > >> >>     return t + t1;
> > >> >> }
> > >> >>
> > >> >> int foo(int x) {
> > >> >>     int t = (x >= 0 ? x : 0) ;
> > >> >>     int xx = -x;
> > >> >>     int t1 =  (xx >= 0 ? xx : 0);
> > >> >>     return t + t1;
> > >> >> }
> > >> >>
> > >> >> Thanks,
> > >> >> Andrew Pinski
> > >> >>
> > >> >
> > >> > Thanks for the help. I'm still having trouble with the vector test,
> > >> though. When I try to compile, I get an error saying "used vector type
> > >> where scalar is required", referring to the max expressions. How do I
> use
> > >> the max expression with two vectors as the inputs?
> > >>
> > >> As I mentioned it only works with the C++ front-end :). The C
> > >> front-end does not support ?: with vectors types.
> > >>
> > >> Thanks,
> > >> Andrew Pinski
> > >>
> > >> >
> > >> > Thanks
> > >> > -Sam
> > >> >>
> > >> >>
> > >> >> >
> > >> >> > Thanks
> > >> >> > -Sam
> > >> >> >
> > >> >> >>
> > >> >> >> Thanks,
> > >> >> >> Andrew
> > >> >> >>
> > >> >> >> >
> > >> >> >> > Tests are also included to be added to the testsuite.
> > >> >> >> >
> > >> >> >> > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> > >> >> >> >
> > >> >> >> >         PR tree-optimization/94290
> > >> >> >> >
> > >> >> >> > gcc/ChangeLog:
> > >> >> >> >
> > >> >> >> >         * match.pd (x >= 0 ? x : 0) + (x <= 0 ? -x : 0): New
> > >> simplification.
> > >> >> >> >         * match.pd (x <= 0 ? -x : 0): New Simplification.
> > >> >> >> >
> > >> >> >> > gcc/testsuite/ChangeLog:
> > >> >> >> >
> > >> >> >> >         * gcc.c-torture/execute/pr94290-1.c: New test.
> > >> >> >> >         * gcc.dg/pr94290-2.c: New test.
> > >> >> >> >         * gcc.dg/pr94290.c: New test.
> > >> >> >> > ---
> > >> >> >> >  gcc/match.pd                                  | 15 ++++++
> > >> >> >> >  .../gcc.c-torture/execute/pr94290-1.c         | 16 +++++++
> > >> >> >> >  gcc/testsuite/gcc.dg/pr94290-2.c              | 15 ++++++
> > >> >> >> >  gcc/testsuite/gcc.dg/pr94290.c                | 46
> > >> +++++++++++++++++++
> > >> >> >> >  4 files changed, 92 insertions(+)
> > >> >> >> >  create mode 100644
> > >> gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
> > >> >> >> >  create mode 100644 gcc/testsuite/gcc.dg/pr94290-2.c
> > >> >> >> >  create mode 100644 gcc/testsuite/gcc.dg/pr94290.c
> > >> >> >> >
> > >> >> >> > diff --git a/gcc/match.pd b/gcc/match.pd
> > >> >> >> > index 45aefd96688..55ca79d7ac9 100644
> > >> >> >> > --- a/gcc/match.pd
> > >> >> >> > +++ b/gcc/match.pd
> > >> >> >> > @@ -7848,3 +7848,18 @@ and,
> > >> >> >> >        (if (TYPE_UNSIGNED (TREE_TYPE (@0)))
> > >> >> >> >          (bit_and @0 @1)
> > >> >> >> >        (cond (le @0 @1) @0 (bit_and @0 @1))))))
> > >> >> >> > +
> > >> >> >> > +/* (x >= 0 ? x : 0) + (x <= 0 ? -x : 0) -> abs x.  */
> > >> >> >> > +(simplify
> > >> >> >> > +  (plus (max @0 integer_zerop) (max (negate @0)
> integer_zerop))
> > >> >> >> > +  (abs @0))
> > >> >> >> > +
> > >> >> >> > +/* (x <= 0 ? -x : 0) + (x >= 0 ? x : 0) -> abs x.  */
> > >> >> >> > +(simplify
> > >> >> >> > +  (plus (max (negate @0) integer_zerop) (max @0
> integer_zerop) )
> > >> >> >> > +  (abs @0))
> > >> >> >> > +
> > >> >> >> > +/* (x <= 0 ? -x : 0) -> max(-x, 0).  */
> > >> >> >> > +(simplify
> > >> >> >> > + (cond (le @0 integer_zerop@1) (negate @0) integer_zerop@1)
> > >> >> >> > + (max (negate @0) @1))
> > >> >> >> > diff --git a/gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
> > >> b/gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
> > >> >> >> > new file mode 100644
> > >> >> >> > index 00000000000..93b80d569aa
> > >> >> >> > --- /dev/null
> > >> >> >> > +++ b/gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
> > >> >> >> > @@ -0,0 +1,16 @@
> > >> >> >> > +/* PR tree-optimization/94290 */
> > >> >> >> > +
> > >> >> >> > +#include "../../gcc.dg/pr94290.c"
> > >> >> >> > +
> > >> >> >> > +int main() {
> > >> >> >> > +
> > >> >> >> > +    if (foo(0) != 0
> > >> >> >> > +        || foo(-42) != 42
> > >> >> >> > +        || foo(42) != 42
> > >> >> >> > +        || baz(-10) != 10
> > >> >> >> > +        || baz(-10) != 10) {
> > >> >> >> > +            __builtin_abort();
> > >> >> >> > +        }
> > >> >> >> > +
> > >> >> >> > +    return 0;
> > >> >> >> > +}
> > >> >> >> > diff --git a/gcc/testsuite/gcc.dg/pr94290-2.c
> > >> b/gcc/testsuite/gcc.dg/pr94290-2.c
> > >> >> >> > new file mode 100644
> > >> >> >> > index 00000000000..ea6e55755f5
> > >> >> >> > --- /dev/null
> > >> >> >> > +++ b/gcc/testsuite/gcc.dg/pr94290-2.c
> > >> >> >> > @@ -0,0 +1,15 @@
> > >> >> >> > +/* PR tree-optimization/94290 */
> > >> >> >> > +/* { dg-do compile } */
> > >> >> >> > +/* { dg-options "-O2 -fdump-tree-optimized" } */
> > >> >> >> > +
> > >> >> >> > +/* Form from PR.  */
> > >> >> >> > +__attribute__((noipa)) unsigned int foo(int x) {
> > >> >> >> > +    return x <= 0 ? -x : 0;
> > >> >> >> > +}
> > >> >> >> > +
> > >> >> >> > +/* Changed order.  */
> > >> >> >> > +__attribute__((noipa)) unsigned int bar(int x) {
> > >> >> >> > +    return 0 >= x ? -x : 0;
> > >> >> >> > +}
> > >> >> >> > +
> > >> >> >> > +/* { dg-final {scan-tree-dump-times " MAX_EXPR " 2
> "optimized" }
> > >> } */
> > >> >> >> > diff --git a/gcc/testsuite/gcc.dg/pr94290.c
> > >> b/gcc/testsuite/gcc.dg/pr94290.c
> > >> >> >> > new file mode 100644
> > >> >> >> > index 00000000000..47617c36c02
> > >> >> >> > --- /dev/null
> > >> >> >> > +++ b/gcc/testsuite/gcc.dg/pr94290.c
> > >> >> >> > @@ -0,0 +1,46 @@
> > >> >> >> > +/* PR tree-optimization/94290 */
> > >> >> >> > +/* { dg-do compile } */
> > >> >> >> > +/* { dg-options "-O2 -fdump-tree-optimized" } */
> > >> >> >> > +
> > >> >> >> > +
> > >> >> >> > +/* Same form as PR.  */
> > >> >> >> > +__attribute__((noipa)) unsigned int foo(int x) {
> > >> >> >> > +    return (x >= 0 ? x : 0) + (x <= 0 ? -x : 0);
> > >> >> >> > +}
> > >> >> >> > +
> > >> >> >> > +/* Signed function.  */
> > >> >> >> > +__attribute__((noipa)) int bar(int x) {
> > >> >> >> > +    return (x >= 0 ? x : 0) + (x <= 0 ? -x : 0);
> > >> >> >> > +}
> > >> >> >> > +
> > >> >> >> > +/* Commutative property.  */
> > >> >> >> > +__attribute__((noipa)) unsigned int baz(int x) {
> > >> >> >> > +    return (x <= 0 ? -x : 0) + (x >= 0 ? x : 0);
> > >> >> >> > +}
> > >> >> >> > +
> > >> >> >> > +/* Flipped order for max expressions.  */
> > >> >> >> > +__attribute__((noipa)) unsigned int quux(int x) {
> > >> >> >> > +    return (0 <= x ? x : 0) + (0 >= x ? -x : 0);
> > >> >> >> > +}
> > >> >> >> > +
> > >> >> >> > +/* Not zero so should not optimize.  */
> > >> >> >> > +__attribute__((noipa)) unsigned int waldo(int x) {
> > >> >> >> > +    return (x >= 4 ? x : 4) + (x <= 4 ? -x : 4);
> > >> >> >> > +}
> > >> >> >> > +
> > >> >> >> > +/* Not zero so should not optimize.  */
> > >> >> >> > +__attribute__((noipa)) unsigned int fred(int x) {
> > >> >> >> > +    return (x >= -4 ? x : -4) + (x <= -4 ? -x : -4);
> > >> >> >> > +}
> > >> >> >> > +
> > >> >> >> > +/* Incorrect pattern.  */
> > >> >> >> > +__attribute__((noipa)) unsigned int goo(int x) {
> > >> >> >> > +    return (x <= 0 ? x : 0) + (x >= 0 ? -x : 0);
> > >> >> >> > +}
> > >> >> >> > +
> > >> >> >> > +/* Incorrect pattern.  */
> > >> >> >> > +__attribute__((noipa)) int qux(int x) {
> > >> >> >> > +    return (x >= 0 ? x : 0) + (x >= 0 ? x : 0);
> > >> >> >> > +}
> > >> >> >> > +
> > >> >> >> > +/* { dg-final {scan-tree-dump-times " ABS_EXPR " 4
> "optimized" }
> > >> } */
> > >> >> >> >
> > >> >> >> > base-commit: 6af530f914801f5e561057da55c41480f28751f7
> > >> >> >> > --
> > >> >> >> > 2.31.1
> > >> >> >> >
> > >> >> >>
> > >> >>
> > >>
> > >>
>
>
  

Patch

diff --git a/gcc/match.pd b/gcc/match.pd
index 45aefd96688..55ca79d7ac9 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -7848,3 +7848,18 @@  and,
       (if (TYPE_UNSIGNED (TREE_TYPE (@0)))
         (bit_and @0 @1)
       (cond (le @0 @1) @0 (bit_and @0 @1))))))
+
+/* (x >= 0 ? x : 0) + (x <= 0 ? -x : 0) -> abs x.  */
+(simplify
+  (plus (max @0 integer_zerop) (max (negate @0) integer_zerop))
+  (abs @0))
+
+/* (x <= 0 ? -x : 0) + (x >= 0 ? x : 0) -> abs x.  */
+(simplify
+  (plus (max (negate @0) integer_zerop) (max @0 integer_zerop) )
+  (abs @0))
+
+/* (x <= 0 ? -x : 0) -> max(-x, 0).  */
+(simplify
+ (cond (le @0 integer_zerop@1) (negate @0) integer_zerop@1)
+ (max (negate @0) @1))
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr94290-1.c b/gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
new file mode 100644
index 00000000000..93b80d569aa
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr94290-1.c
@@ -0,0 +1,16 @@ 
+/* PR tree-optimization/94290 */
+
+#include "../../gcc.dg/pr94290.c"
+
+int main() {
+
+    if (foo(0) != 0
+        || foo(-42) != 42
+        || foo(42) != 42
+        || baz(-10) != 10
+        || baz(-10) != 10) {
+            __builtin_abort();
+        }
+    
+    return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr94290-2.c b/gcc/testsuite/gcc.dg/pr94290-2.c
new file mode 100644
index 00000000000..ea6e55755f5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr94290-2.c
@@ -0,0 +1,15 @@ 
+/* PR tree-optimization/94290 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+/* Form from PR.  */
+__attribute__((noipa)) unsigned int foo(int x) {
+    return x <= 0 ? -x : 0;
+}
+
+/* Changed order.  */
+__attribute__((noipa)) unsigned int bar(int x) {
+    return 0 >= x ? -x : 0;
+}
+
+/* { dg-final {scan-tree-dump-times " MAX_EXPR " 2 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/pr94290.c b/gcc/testsuite/gcc.dg/pr94290.c
new file mode 100644
index 00000000000..47617c36c02
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr94290.c
@@ -0,0 +1,46 @@ 
+/* PR tree-optimization/94290 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+
+/* Same form as PR.  */
+__attribute__((noipa)) unsigned int foo(int x) {
+    return (x >= 0 ? x : 0) + (x <= 0 ? -x : 0);
+}
+
+/* Signed function.  */
+__attribute__((noipa)) int bar(int x) {
+    return (x >= 0 ? x : 0) + (x <= 0 ? -x : 0);
+}
+
+/* Commutative property.  */
+__attribute__((noipa)) unsigned int baz(int x) {
+    return (x <= 0 ? -x : 0) + (x >= 0 ? x : 0);
+}
+
+/* Flipped order for max expressions.  */
+__attribute__((noipa)) unsigned int quux(int x) {
+    return (0 <= x ? x : 0) + (0 >= x ? -x : 0);
+}
+
+/* Not zero so should not optimize.  */
+__attribute__((noipa)) unsigned int waldo(int x) {
+    return (x >= 4 ? x : 4) + (x <= 4 ? -x : 4);
+}
+
+/* Not zero so should not optimize.  */
+__attribute__((noipa)) unsigned int fred(int x) {
+    return (x >= -4 ? x : -4) + (x <= -4 ? -x : -4);
+}
+
+/* Incorrect pattern.  */
+__attribute__((noipa)) unsigned int goo(int x) {
+    return (x <= 0 ? x : 0) + (x >= 0 ? -x : 0);
+}
+
+/* Incorrect pattern.  */
+__attribute__((noipa)) int qux(int x) {
+    return (x >= 0 ? x : 0) + (x >= 0 ? x : 0);
+}
+
+/* { dg-final {scan-tree-dump-times " ABS_EXPR " 4 "optimized" } } */