public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] MATCH: [PR110937/PR100798] (a ? ~b : b) should be optimized to b ^ -(a)
@ 2023-08-09 19:19 Andrew Pinski
  2023-08-10 13:37 ` Christophe Lyon
  2023-09-05  7:28 ` [PATCH 17/12] _BitInt a ? ~b : b match.pd fix [PR102989] Jakub Jelinek
  0 siblings, 2 replies; 12+ messages in thread
From: Andrew Pinski @ 2023-08-09 19:19 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Pinski

This adds a simple match pattern for this case.
I noticed it a couple of different places.
One while I was looking at code generation of a parser and
also while I was looking at locations where bitwise_inverted_equal_p
should be used more.

Committed as approved after bootstrapped and tested on x86_64-linux-gnu with no regressions.

	PR tree-optimization/110937
	PR tree-optimization/100798

gcc/ChangeLog:

	* match.pd (`a ? ~b : b`): Handle this
	case.

gcc/testsuite/ChangeLog:

	* gcc.dg/tree-ssa/bool-14.c: New test.
	* gcc.dg/tree-ssa/bool-15.c: New test.
	* gcc.dg/tree-ssa/phi-opt-33.c: New test.
	* gcc.dg/tree-ssa/20030709-2.c: Update testcase
	so `a ? -1 : 0` is not used to hit the match
	pattern.
---
 gcc/match.pd                               | 14 ++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c |  5 +++--
 gcc/testsuite/gcc.dg/tree-ssa/bool-14.c    | 15 +++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/bool-15.c    | 18 ++++++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-33.c | 13 +++++++++++++
 5 files changed, 63 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/bool-14.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/bool-15.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-33.c

diff --git a/gcc/match.pd b/gcc/match.pd
index 9b4819e5be7..fc630b63563 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -6460,6 +6460,20 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
       (if (cmp == NE_EXPR)
        { constant_boolean_node (true, type); })))))))
 
+#if GIMPLE
+/* a?~t:t -> (-(a))^t */
+(simplify
+ (cond @0 @1 @2)
+ (if (INTEGRAL_TYPE_P (type)
+      && bitwise_inverted_equal_p (@1, @2))
+  (with {
+    auto prec = TYPE_PRECISION (type);
+    auto unsign = TYPE_UNSIGNED (type);
+    tree inttype = build_nonstandard_integer_type (prec, unsign);
+   }
+   (convert (bit_xor (negate (convert:inttype @0)) (convert:inttype @2))))))
+#endif
+
 /* Simplify pointer equality compares using PTA.  */
 (for neeq (ne eq)
  (simplify
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c
index 5009cd69cfe..78938f919d4 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c
@@ -29,15 +29,16 @@ union tree_node
 };
 int make_decl_rtl (tree, int);
 void *
-get_alias_set (t)
+get_alias_set (t, t1)
      tree t;
+     void *t1;
 {
   long set;
   if (t->decl.rtl)
     return (t->decl.rtl->fld[1].rtmem 
 	    ? 0
 	    : (((t->decl.rtl ? t->decl.rtl: (make_decl_rtl (t, 0), t->decl.rtl)))->fld[1]).rtmem);
-  return (void*)-1;
+  return t1;
 }
 
 /* There should be precisely one load of ->decl.rtl.  If there is
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/bool-14.c b/gcc/testsuite/gcc.dg/tree-ssa/bool-14.c
new file mode 100644
index 00000000000..0149380a63b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/bool-14.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized-raw" } */
+/* PR tree-optimization/110937 */
+
+_Bool f2(_Bool a, _Bool b)
+{
+        if (a)
+          return !b;
+        return b;
+}
+
+/* We should be able to remove the conditional and convert it to an xor. */
+/* { dg-final { scan-tree-dump-not "gimple_cond " "optimized" } } */
+/* { dg-final { scan-tree-dump-not "gimple_phi " "optimized" } } */
+/* { dg-final { scan-tree-dump-times "bit_xor_expr, " 1 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/bool-15.c b/gcc/testsuite/gcc.dg/tree-ssa/bool-15.c
new file mode 100644
index 00000000000..1f496663863
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/bool-15.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized-raw" } */
+/* PR tree-optimization/110937 */
+
+_Bool f2(int x, int y, int w, int z)
+{
+  _Bool a = x == y;
+  _Bool b = w == z;
+  if (a)
+    return !b;
+  return b;
+}
+
+/* We should be able to remove the conditional and convert it to an xor. */
+/* { dg-final { scan-tree-dump-not "gimple_cond " "optimized" } } */
+/* { dg-final { scan-tree-dump-not "gimple_phi " "optimized" } } */
+/* { dg-final { scan-tree-dump-not "ne_expr, " "optimized" } } */
+/* { dg-final { scan-tree-dump-times "bit_xor_expr, " 1 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-33.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-33.c
new file mode 100644
index 00000000000..b79fe44187a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-33.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized-raw" } */
+/* PR tree-optimization/100798 */
+
+int f(int a, int t)
+{
+  return (a=='s' ? ~t : t);
+}
+
+/* This should be convert into t^-(a=='s').  */
+/* { dg-final { scan-tree-dump-times "bit_xor_expr, " 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "negate_expr, " 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-not "bit_not_expr, " "optimized" } } */
-- 
2.31.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH] MATCH: [PR110937/PR100798] (a ? ~b : b) should be optimized to b ^ -(a)
  2023-08-09 19:19 [PATCH] MATCH: [PR110937/PR100798] (a ? ~b : b) should be optimized to b ^ -(a) Andrew Pinski
@ 2023-08-10 13:37 ` Christophe Lyon
  2023-08-10 18:52   ` Andrew Pinski
  2023-09-05  7:28 ` [PATCH 17/12] _BitInt a ? ~b : b match.pd fix [PR102989] Jakub Jelinek
  1 sibling, 1 reply; 12+ messages in thread
From: Christophe Lyon @ 2023-08-10 13:37 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 6573 bytes --]

Hi Andrew,


On Wed, 9 Aug 2023 at 21:20, Andrew Pinski via Gcc-patches <
gcc-patches@gcc.gnu.org> wrote:

> This adds a simple match pattern for this case.
> I noticed it a couple of different places.
> One while I was looking at code generation of a parser and
> also while I was looking at locations where bitwise_inverted_equal_p
> should be used more.
>
> Committed as approved after bootstrapped and tested on x86_64-linux-gnu
> with no regressions.
>
>         PR tree-optimization/110937
>         PR tree-optimization/100798
>
> gcc/ChangeLog:
>
>         * match.pd (`a ? ~b : b`): Handle this
>         case.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.dg/tree-ssa/bool-14.c: New test.
>         * gcc.dg/tree-ssa/bool-15.c: New test.
>         * gcc.dg/tree-ssa/phi-opt-33.c: New test.
>         * gcc.dg/tree-ssa/20030709-2.c: Update testcase
>         so `a ? -1 : 0` is not used to hit the match
>         pattern.
>

Our CI noticed that your patch introduced regressions as follows on aarch64:

 Running gcc:gcc.target/aarch64/aarch64.exp ...
FAIL: gcc.target/aarch64/cond_op_imm_1.c scan-assembler csinv\tw[0-9]*.*
FAIL: gcc.target/aarch64/cond_op_imm_1.c scan-assembler csinv\tx[0-9]*.*

Running gcc:gcc.target/aarch64/sve/aarch64-sve.exp ...
FAIL: gcc.target/aarch64/sve/cond_unary_5.c scan-assembler-not \\tmov\\tz
FAIL: gcc.target/aarch64/sve/cond_unary_5.c scan-assembler-times
\\tneg\\tz[0-9]+\\.b, p[0-7]/m, 3
FAIL: gcc.target/aarch64/sve/cond_unary_5.c scan-assembler-times
\\tneg\\tz[0-9]+\\.h, p[0-7]/m, 2
FAIL: gcc.target/aarch64/sve/cond_unary_5.c scan-assembler-times
\\tneg\\tz[0-9]+\\.s, p[0-7]/m, 1
FAIL: gcc.target/aarch64/sve/cond_unary_5.c scan-assembler-times
\\tnot\\tz[0-9]+\\.b, p[0-7]/m, 3
FAIL: gcc.target/aarch64/sve/cond_unary_5.c scan-assembler-times
\\tnot\\tz[0-9]+\\.h, p[0-7]/m, 2
FAIL: gcc.target/aarch64/sve/cond_unary_5.c scan-assembler-times
\\tnot\\tz[0-9]+\\.s, p[0-7]/m, 1

Hopefully you'll just need to update the testcases (I didn't check
manually, I think you can easily reproduce this on aarch64?)

Thanks,

Christophe




> ---
>  gcc/match.pd                               | 14 ++++++++++++++
>  gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c |  5 +++--
>  gcc/testsuite/gcc.dg/tree-ssa/bool-14.c    | 15 +++++++++++++++
>  gcc/testsuite/gcc.dg/tree-ssa/bool-15.c    | 18 ++++++++++++++++++
>  gcc/testsuite/gcc.dg/tree-ssa/phi-opt-33.c | 13 +++++++++++++
>  5 files changed, 63 insertions(+), 2 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/bool-14.c
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/bool-15.c
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-33.c
>
> diff --git a/gcc/match.pd b/gcc/match.pd
> index 9b4819e5be7..fc630b63563 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -6460,6 +6460,20 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>        (if (cmp == NE_EXPR)
>         { constant_boolean_node (true, type); })))))))
>
> +#if GIMPLE
> +/* a?~t:t -> (-(a))^t */
> +(simplify
> + (cond @0 @1 @2)
> + (if (INTEGRAL_TYPE_P (type)
> +      && bitwise_inverted_equal_p (@1, @2))
> +  (with {
> +    auto prec = TYPE_PRECISION (type);
> +    auto unsign = TYPE_UNSIGNED (type);
> +    tree inttype = build_nonstandard_integer_type (prec, unsign);
> +   }
> +   (convert (bit_xor (negate (convert:inttype @0)) (convert:inttype
> @2))))))
> +#endif
> +
>  /* Simplify pointer equality compares using PTA.  */
>  (for neeq (ne eq)
>   (simplify
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c
> b/gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c
> index 5009cd69cfe..78938f919d4 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c
> @@ -29,15 +29,16 @@ union tree_node
>  };
>  int make_decl_rtl (tree, int);
>  void *
> -get_alias_set (t)
> +get_alias_set (t, t1)
>       tree t;
> +     void *t1;
>  {
>    long set;
>    if (t->decl.rtl)
>      return (t->decl.rtl->fld[1].rtmem
>             ? 0
>             : (((t->decl.rtl ? t->decl.rtl: (make_decl_rtl (t, 0),
> t->decl.rtl)))->fld[1]).rtmem);
> -  return (void*)-1;
> +  return t1;
>  }
>
>  /* There should be precisely one load of ->decl.rtl.  If there is
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/bool-14.c
> b/gcc/testsuite/gcc.dg/tree-ssa/bool-14.c
> new file mode 100644
> index 00000000000..0149380a63b
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/bool-14.c
> @@ -0,0 +1,15 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized-raw" } */
> +/* PR tree-optimization/110937 */
> +
> +_Bool f2(_Bool a, _Bool b)
> +{
> +        if (a)
> +          return !b;
> +        return b;
> +}
> +
> +/* We should be able to remove the conditional and convert it to an xor.
> */
> +/* { dg-final { scan-tree-dump-not "gimple_cond " "optimized" } } */
> +/* { dg-final { scan-tree-dump-not "gimple_phi " "optimized" } } */
> +/* { dg-final { scan-tree-dump-times "bit_xor_expr, " 1 "optimized" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/bool-15.c
> b/gcc/testsuite/gcc.dg/tree-ssa/bool-15.c
> new file mode 100644
> index 00000000000..1f496663863
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/bool-15.c
> @@ -0,0 +1,18 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized-raw" } */
> +/* PR tree-optimization/110937 */
> +
> +_Bool f2(int x, int y, int w, int z)
> +{
> +  _Bool a = x == y;
> +  _Bool b = w == z;
> +  if (a)
> +    return !b;
> +  return b;
> +}
> +
> +/* We should be able to remove the conditional and convert it to an xor.
> */
> +/* { dg-final { scan-tree-dump-not "gimple_cond " "optimized" } } */
> +/* { dg-final { scan-tree-dump-not "gimple_phi " "optimized" } } */
> +/* { dg-final { scan-tree-dump-not "ne_expr, " "optimized" } } */
> +/* { dg-final { scan-tree-dump-times "bit_xor_expr, " 1 "optimized" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-33.c
> b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-33.c
> new file mode 100644
> index 00000000000..b79fe44187a
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-33.c
> @@ -0,0 +1,13 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized-raw" } */
> +/* PR tree-optimization/100798 */
> +
> +int f(int a, int t)
> +{
> +  return (a=='s' ? ~t : t);
> +}
> +
> +/* This should be convert into t^-(a=='s').  */
> +/* { dg-final { scan-tree-dump-times "bit_xor_expr, " 1 "optimized" } } */
> +/* { dg-final { scan-tree-dump-times "negate_expr, " 1 "optimized" } } */
> +/* { dg-final { scan-tree-dump-not "bit_not_expr, " "optimized" } } */
> --
> 2.31.1
>
>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH] MATCH: [PR110937/PR100798] (a ? ~b : b) should be optimized to b ^ -(a)
  2023-08-10 13:37 ` Christophe Lyon
@ 2023-08-10 18:52   ` Andrew Pinski
  2023-08-11  8:06     ` Christophe Lyon
  0 siblings, 1 reply; 12+ messages in thread
From: Andrew Pinski @ 2023-08-10 18:52 UTC (permalink / raw)
  To: Christophe Lyon; +Cc: Andrew Pinski, gcc-patches

On Thu, Aug 10, 2023 at 6:39 AM Christophe Lyon via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> Hi Andrew,
>
>
> On Wed, 9 Aug 2023 at 21:20, Andrew Pinski via Gcc-patches <
> gcc-patches@gcc.gnu.org> wrote:
>
> > This adds a simple match pattern for this case.
> > I noticed it a couple of different places.
> > One while I was looking at code generation of a parser and
> > also while I was looking at locations where bitwise_inverted_equal_p
> > should be used more.
> >
> > Committed as approved after bootstrapped and tested on x86_64-linux-gnu
> > with no regressions.
> >
> >         PR tree-optimization/110937
> >         PR tree-optimization/100798
> >
> > gcc/ChangeLog:
> >
> >         * match.pd (`a ? ~b : b`): Handle this
> >         case.
> >
> > gcc/testsuite/ChangeLog:
> >
> >         * gcc.dg/tree-ssa/bool-14.c: New test.
> >         * gcc.dg/tree-ssa/bool-15.c: New test.
> >         * gcc.dg/tree-ssa/phi-opt-33.c: New test.
> >         * gcc.dg/tree-ssa/20030709-2.c: Update testcase
> >         so `a ? -1 : 0` is not used to hit the match
> >         pattern.
> >
>
> Our CI noticed that your patch introduced regressions as follows on aarch64:
>
>  Running gcc:gcc.target/aarch64/aarch64.exp ...
> FAIL: gcc.target/aarch64/cond_op_imm_1.c scan-assembler csinv\tw[0-9]*.*
> FAIL: gcc.target/aarch64/cond_op_imm_1.c scan-assembler csinv\tx[0-9]*.*
>
> Running gcc:gcc.target/aarch64/sve/aarch64-sve.exp ...
> FAIL: gcc.target/aarch64/sve/cond_unary_5.c scan-assembler-not \\tmov\\tz
> FAIL: gcc.target/aarch64/sve/cond_unary_5.c scan-assembler-times
> \\tneg\\tz[0-9]+\\.b, p[0-7]/m, 3
> FAIL: gcc.target/aarch64/sve/cond_unary_5.c scan-assembler-times
> \\tneg\\tz[0-9]+\\.h, p[0-7]/m, 2
> FAIL: gcc.target/aarch64/sve/cond_unary_5.c scan-assembler-times
> \\tneg\\tz[0-9]+\\.s, p[0-7]/m, 1
> FAIL: gcc.target/aarch64/sve/cond_unary_5.c scan-assembler-times
> \\tnot\\tz[0-9]+\\.b, p[0-7]/m, 3
> FAIL: gcc.target/aarch64/sve/cond_unary_5.c scan-assembler-times
> \\tnot\\tz[0-9]+\\.h, p[0-7]/m, 2
> FAIL: gcc.target/aarch64/sve/cond_unary_5.c scan-assembler-times
> \\tnot\\tz[0-9]+\\.s, p[0-7]/m, 1
>
> Hopefully you'll just need to update the testcases (I didn't check
> manually, I think you can easily reproduce this on aarch64?)

I have a few ideas of how to fix this properly inside isel without
changing the testcases. I will start working on that starting
tomorrow.
In the meantime can you file a bug report? So we don't lose track of
the regression?

Thanks,
Andrew

>
> Thanks,
>
> Christophe
>
>
>
>
> > ---
> >  gcc/match.pd                               | 14 ++++++++++++++
> >  gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c |  5 +++--
> >  gcc/testsuite/gcc.dg/tree-ssa/bool-14.c    | 15 +++++++++++++++
> >  gcc/testsuite/gcc.dg/tree-ssa/bool-15.c    | 18 ++++++++++++++++++
> >  gcc/testsuite/gcc.dg/tree-ssa/phi-opt-33.c | 13 +++++++++++++
> >  5 files changed, 63 insertions(+), 2 deletions(-)
> >  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/bool-14.c
> >  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/bool-15.c
> >  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-33.c
> >
> > diff --git a/gcc/match.pd b/gcc/match.pd
> > index 9b4819e5be7..fc630b63563 100644
> > --- a/gcc/match.pd
> > +++ b/gcc/match.pd
> > @@ -6460,6 +6460,20 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> >        (if (cmp == NE_EXPR)
> >         { constant_boolean_node (true, type); })))))))
> >
> > +#if GIMPLE
> > +/* a?~t:t -> (-(a))^t */
> > +(simplify
> > + (cond @0 @1 @2)
> > + (if (INTEGRAL_TYPE_P (type)
> > +      && bitwise_inverted_equal_p (@1, @2))
> > +  (with {
> > +    auto prec = TYPE_PRECISION (type);
> > +    auto unsign = TYPE_UNSIGNED (type);
> > +    tree inttype = build_nonstandard_integer_type (prec, unsign);
> > +   }
> > +   (convert (bit_xor (negate (convert:inttype @0)) (convert:inttype
> > @2))))))
> > +#endif
> > +
> >  /* Simplify pointer equality compares using PTA.  */
> >  (for neeq (ne eq)
> >   (simplify
> > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c
> > b/gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c
> > index 5009cd69cfe..78938f919d4 100644
> > --- a/gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c
> > +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c
> > @@ -29,15 +29,16 @@ union tree_node
> >  };
> >  int make_decl_rtl (tree, int);
> >  void *
> > -get_alias_set (t)
> > +get_alias_set (t, t1)
> >       tree t;
> > +     void *t1;
> >  {
> >    long set;
> >    if (t->decl.rtl)
> >      return (t->decl.rtl->fld[1].rtmem
> >             ? 0
> >             : (((t->decl.rtl ? t->decl.rtl: (make_decl_rtl (t, 0),
> > t->decl.rtl)))->fld[1]).rtmem);
> > -  return (void*)-1;
> > +  return t1;
> >  }
> >
> >  /* There should be precisely one load of ->decl.rtl.  If there is
> > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/bool-14.c
> > b/gcc/testsuite/gcc.dg/tree-ssa/bool-14.c
> > new file mode 100644
> > index 00000000000..0149380a63b
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/tree-ssa/bool-14.c
> > @@ -0,0 +1,15 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-O2 -fdump-tree-optimized-raw" } */
> > +/* PR tree-optimization/110937 */
> > +
> > +_Bool f2(_Bool a, _Bool b)
> > +{
> > +        if (a)
> > +          return !b;
> > +        return b;
> > +}
> > +
> > +/* We should be able to remove the conditional and convert it to an xor.
> > */
> > +/* { dg-final { scan-tree-dump-not "gimple_cond " "optimized" } } */
> > +/* { dg-final { scan-tree-dump-not "gimple_phi " "optimized" } } */
> > +/* { dg-final { scan-tree-dump-times "bit_xor_expr, " 1 "optimized" } } */
> > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/bool-15.c
> > b/gcc/testsuite/gcc.dg/tree-ssa/bool-15.c
> > new file mode 100644
> > index 00000000000..1f496663863
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/tree-ssa/bool-15.c
> > @@ -0,0 +1,18 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-O2 -fdump-tree-optimized-raw" } */
> > +/* PR tree-optimization/110937 */
> > +
> > +_Bool f2(int x, int y, int w, int z)
> > +{
> > +  _Bool a = x == y;
> > +  _Bool b = w == z;
> > +  if (a)
> > +    return !b;
> > +  return b;
> > +}
> > +
> > +/* We should be able to remove the conditional and convert it to an xor.
> > */
> > +/* { dg-final { scan-tree-dump-not "gimple_cond " "optimized" } } */
> > +/* { dg-final { scan-tree-dump-not "gimple_phi " "optimized" } } */
> > +/* { dg-final { scan-tree-dump-not "ne_expr, " "optimized" } } */
> > +/* { dg-final { scan-tree-dump-times "bit_xor_expr, " 1 "optimized" } } */
> > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-33.c
> > b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-33.c
> > new file mode 100644
> > index 00000000000..b79fe44187a
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-33.c
> > @@ -0,0 +1,13 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-O2 -fdump-tree-optimized-raw" } */
> > +/* PR tree-optimization/100798 */
> > +
> > +int f(int a, int t)
> > +{
> > +  return (a=='s' ? ~t : t);
> > +}
> > +
> > +/* This should be convert into t^-(a=='s').  */
> > +/* { dg-final { scan-tree-dump-times "bit_xor_expr, " 1 "optimized" } } */
> > +/* { dg-final { scan-tree-dump-times "negate_expr, " 1 "optimized" } } */
> > +/* { dg-final { scan-tree-dump-not "bit_not_expr, " "optimized" } } */
> > --
> > 2.31.1
> >
> >

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH] MATCH: [PR110937/PR100798] (a ? ~b : b) should be optimized to b ^ -(a)
  2023-08-10 18:52   ` Andrew Pinski
@ 2023-08-11  8:06     ` Christophe Lyon
  0 siblings, 0 replies; 12+ messages in thread
From: Christophe Lyon @ 2023-08-11  8:06 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: Andrew Pinski, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 8150 bytes --]

On Thu, 10 Aug 2023 at 20:52, Andrew Pinski <pinskia@gmail.com> wrote:

> On Thu, Aug 10, 2023 at 6:39 AM Christophe Lyon via Gcc-patches
> <gcc-patches@gcc.gnu.org> wrote:
> >
> > Hi Andrew,
> >
> >
> > On Wed, 9 Aug 2023 at 21:20, Andrew Pinski via Gcc-patches <
> > gcc-patches@gcc.gnu.org> wrote:
> >
> > > This adds a simple match pattern for this case.
> > > I noticed it a couple of different places.
> > > One while I was looking at code generation of a parser and
> > > also while I was looking at locations where bitwise_inverted_equal_p
> > > should be used more.
> > >
> > > Committed as approved after bootstrapped and tested on x86_64-linux-gnu
> > > with no regressions.
> > >
> > >         PR tree-optimization/110937
> > >         PR tree-optimization/100798
> > >
> > > gcc/ChangeLog:
> > >
> > >         * match.pd (`a ? ~b : b`): Handle this
> > >         case.
> > >
> > > gcc/testsuite/ChangeLog:
> > >
> > >         * gcc.dg/tree-ssa/bool-14.c: New test.
> > >         * gcc.dg/tree-ssa/bool-15.c: New test.
> > >         * gcc.dg/tree-ssa/phi-opt-33.c: New test.
> > >         * gcc.dg/tree-ssa/20030709-2.c: Update testcase
> > >         so `a ? -1 : 0` is not used to hit the match
> > >         pattern.
> > >
> >
> > Our CI noticed that your patch introduced regressions as follows on
> aarch64:
> >
> >  Running gcc:gcc.target/aarch64/aarch64.exp ...
> > FAIL: gcc.target/aarch64/cond_op_imm_1.c scan-assembler csinv\tw[0-9]*.*
> > FAIL: gcc.target/aarch64/cond_op_imm_1.c scan-assembler csinv\tx[0-9]*.*
> >
> > Running gcc:gcc.target/aarch64/sve/aarch64-sve.exp ...
> > FAIL: gcc.target/aarch64/sve/cond_unary_5.c scan-assembler-not \\tmov\\tz
> > FAIL: gcc.target/aarch64/sve/cond_unary_5.c scan-assembler-times
> > \\tneg\\tz[0-9]+\\.b, p[0-7]/m, 3
> > FAIL: gcc.target/aarch64/sve/cond_unary_5.c scan-assembler-times
> > \\tneg\\tz[0-9]+\\.h, p[0-7]/m, 2
> > FAIL: gcc.target/aarch64/sve/cond_unary_5.c scan-assembler-times
> > \\tneg\\tz[0-9]+\\.s, p[0-7]/m, 1
> > FAIL: gcc.target/aarch64/sve/cond_unary_5.c scan-assembler-times
> > \\tnot\\tz[0-9]+\\.b, p[0-7]/m, 3
> > FAIL: gcc.target/aarch64/sve/cond_unary_5.c scan-assembler-times
> > \\tnot\\tz[0-9]+\\.h, p[0-7]/m, 2
> > FAIL: gcc.target/aarch64/sve/cond_unary_5.c scan-assembler-times
> > \\tnot\\tz[0-9]+\\.s, p[0-7]/m, 1
> >
> > Hopefully you'll just need to update the testcases (I didn't check
> > manually, I think you can easily reproduce this on aarch64?)
>
> I have a few ideas of how to fix this properly inside isel without
> changing the testcases. I will start working on that starting
> tomorrow.
> In the meantime can you file a bug report? So we don't lose track of
> the regression?
>
> Hi Andrew,

Sure, I've just filed:  https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110986

Thanks,

Christophe

Thanks,
> Andrew
>
> >
> > Thanks,
> >
> > Christophe
> >
> >
> >
> >
> > > ---
> > >  gcc/match.pd                               | 14 ++++++++++++++
> > >  gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c |  5 +++--
> > >  gcc/testsuite/gcc.dg/tree-ssa/bool-14.c    | 15 +++++++++++++++
> > >  gcc/testsuite/gcc.dg/tree-ssa/bool-15.c    | 18 ++++++++++++++++++
> > >  gcc/testsuite/gcc.dg/tree-ssa/phi-opt-33.c | 13 +++++++++++++
> > >  5 files changed, 63 insertions(+), 2 deletions(-)
> > >  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/bool-14.c
> > >  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/bool-15.c
> > >  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-33.c
> > >
> > > diff --git a/gcc/match.pd b/gcc/match.pd
> > > index 9b4819e5be7..fc630b63563 100644
> > > --- a/gcc/match.pd
> > > +++ b/gcc/match.pd
> > > @@ -6460,6 +6460,20 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> > >        (if (cmp == NE_EXPR)
> > >         { constant_boolean_node (true, type); })))))))
> > >
> > > +#if GIMPLE
> > > +/* a?~t:t -> (-(a))^t */
> > > +(simplify
> > > + (cond @0 @1 @2)
> > > + (if (INTEGRAL_TYPE_P (type)
> > > +      && bitwise_inverted_equal_p (@1, @2))
> > > +  (with {
> > > +    auto prec = TYPE_PRECISION (type);
> > > +    auto unsign = TYPE_UNSIGNED (type);
> > > +    tree inttype = build_nonstandard_integer_type (prec, unsign);
> > > +   }
> > > +   (convert (bit_xor (negate (convert:inttype @0)) (convert:inttype
> > > @2))))))
> > > +#endif
> > > +
> > >  /* Simplify pointer equality compares using PTA.  */
> > >  (for neeq (ne eq)
> > >   (simplify
> > > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c
> > > b/gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c
> > > index 5009cd69cfe..78938f919d4 100644
> > > --- a/gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c
> > > +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c
> > > @@ -29,15 +29,16 @@ union tree_node
> > >  };
> > >  int make_decl_rtl (tree, int);
> > >  void *
> > > -get_alias_set (t)
> > > +get_alias_set (t, t1)
> > >       tree t;
> > > +     void *t1;
> > >  {
> > >    long set;
> > >    if (t->decl.rtl)
> > >      return (t->decl.rtl->fld[1].rtmem
> > >             ? 0
> > >             : (((t->decl.rtl ? t->decl.rtl: (make_decl_rtl (t, 0),
> > > t->decl.rtl)))->fld[1]).rtmem);
> > > -  return (void*)-1;
> > > +  return t1;
> > >  }
> > >
> > >  /* There should be precisely one load of ->decl.rtl.  If there is
> > > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/bool-14.c
> > > b/gcc/testsuite/gcc.dg/tree-ssa/bool-14.c
> > > new file mode 100644
> > > index 00000000000..0149380a63b
> > > --- /dev/null
> > > +++ b/gcc/testsuite/gcc.dg/tree-ssa/bool-14.c
> > > @@ -0,0 +1,15 @@
> > > +/* { dg-do compile } */
> > > +/* { dg-options "-O2 -fdump-tree-optimized-raw" } */
> > > +/* PR tree-optimization/110937 */
> > > +
> > > +_Bool f2(_Bool a, _Bool b)
> > > +{
> > > +        if (a)
> > > +          return !b;
> > > +        return b;
> > > +}
> > > +
> > > +/* We should be able to remove the conditional and convert it to an
> xor.
> > > */
> > > +/* { dg-final { scan-tree-dump-not "gimple_cond " "optimized" } } */
> > > +/* { dg-final { scan-tree-dump-not "gimple_phi " "optimized" } } */
> > > +/* { dg-final { scan-tree-dump-times "bit_xor_expr, " 1 "optimized" }
> } */
> > > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/bool-15.c
> > > b/gcc/testsuite/gcc.dg/tree-ssa/bool-15.c
> > > new file mode 100644
> > > index 00000000000..1f496663863
> > > --- /dev/null
> > > +++ b/gcc/testsuite/gcc.dg/tree-ssa/bool-15.c
> > > @@ -0,0 +1,18 @@
> > > +/* { dg-do compile } */
> > > +/* { dg-options "-O2 -fdump-tree-optimized-raw" } */
> > > +/* PR tree-optimization/110937 */
> > > +
> > > +_Bool f2(int x, int y, int w, int z)
> > > +{
> > > +  _Bool a = x == y;
> > > +  _Bool b = w == z;
> > > +  if (a)
> > > +    return !b;
> > > +  return b;
> > > +}
> > > +
> > > +/* We should be able to remove the conditional and convert it to an
> xor.
> > > */
> > > +/* { dg-final { scan-tree-dump-not "gimple_cond " "optimized" } } */
> > > +/* { dg-final { scan-tree-dump-not "gimple_phi " "optimized" } } */
> > > +/* { dg-final { scan-tree-dump-not "ne_expr, " "optimized" } } */
> > > +/* { dg-final { scan-tree-dump-times "bit_xor_expr, " 1 "optimized" }
> } */
> > > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-33.c
> > > b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-33.c
> > > new file mode 100644
> > > index 00000000000..b79fe44187a
> > > --- /dev/null
> > > +++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-33.c
> > > @@ -0,0 +1,13 @@
> > > +/* { dg-do compile } */
> > > +/* { dg-options "-O2 -fdump-tree-optimized-raw" } */
> > > +/* PR tree-optimization/100798 */
> > > +
> > > +int f(int a, int t)
> > > +{
> > > +  return (a=='s' ? ~t : t);
> > > +}
> > > +
> > > +/* This should be convert into t^-(a=='s').  */
> > > +/* { dg-final { scan-tree-dump-times "bit_xor_expr, " 1 "optimized" }
> } */
> > > +/* { dg-final { scan-tree-dump-times "negate_expr, " 1 "optimized" }
> } */
> > > +/* { dg-final { scan-tree-dump-not "bit_not_expr, " "optimized" } } */
> > > --
> > > 2.31.1
> > >
> > >
>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 17/12] _BitInt a ? ~b : b match.pd fix [PR102989]
  2023-08-09 19:19 [PATCH] MATCH: [PR110937/PR100798] (a ? ~b : b) should be optimized to b ^ -(a) Andrew Pinski
  2023-08-10 13:37 ` Christophe Lyon
@ 2023-09-05  7:28 ` Jakub Jelinek
  2023-09-05 21:27   ` Andrew Pinski
  1 sibling, 1 reply; 12+ messages in thread
From: Jakub Jelinek @ 2023-09-05  7:28 UTC (permalink / raw)
  To: Andrew Pinski, Richard Biener; +Cc: gcc-patches

On Wed, Aug 09, 2023 at 12:19:54PM -0700, Andrew Pinski via Gcc-patches wrote:
> 	PR tree-optimization/110937
> 	PR tree-optimization/100798
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -6460,6 +6460,20 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>        (if (cmp == NE_EXPR)
>         { constant_boolean_node (true, type); })))))))
>  
> +#if GIMPLE
> +/* a?~t:t -> (-(a))^t */
> +(simplify
> + (cond @0 @1 @2)
> + (if (INTEGRAL_TYPE_P (type)
> +      && bitwise_inverted_equal_p (@1, @2))
> +  (with {
> +    auto prec = TYPE_PRECISION (type);
> +    auto unsign = TYPE_UNSIGNED (type);
> +    tree inttype = build_nonstandard_integer_type (prec, unsign);
> +   }
> +   (convert (bit_xor (negate (convert:inttype @0)) (convert:inttype @2))))))
> +#endif

This broke one bitint test - bitint-42.c for -O1 and -Os (in admittedly not yet
committed series).
Using build_nonstandard_integer_type this way doesn't work well for larger
precision BITINT_TYPEs, because it always creates an INTEGER_TYPE and
say 467-bit INTEGER_TYPE doesn't work very well.  To get a BITINT_TYPE, one
needs to use build_bitint_type instead (but similarly to
build_nonstandard_integer_type one should first make sure such a type
actually can be created).

I admit it isn't really clear to me what do you want to achieve by the
above build_nonstandard_integer_type.  Is it because of BOOLEAN_TYPE
or perhaps ENUMERAL_TYPE as well?

If type is INTEGER_TYPE or BITINT_TYPE, one doesn't really need to create a
new type, type already is an integral type with that precision and
signedness.  In other places using unsigned_type_for or signed_type_for
might be better than using build_nonstandard_integer_type if that is what
one wants to achieve, those functions handle BITINT_TYPE.

Or shall we instead test for == BOOLEAN_TYPE (or if ENUMERAL_TYPE for
some reason needs the same treatment also || == ENUMERAL_TYPE)?

2023-09-05  Jakub Jelinek  <jakub@redhat.com>

	PR c/102989
	* match.pd (a ? ~b : b): Don't use build_nonstandard_integer_type
	for INTEGER_TYPE or BITINT_TYPE.

--- gcc/match.pd.jj	2023-09-04 09:45:33.553058301 +0200
+++ gcc/match.pd	2023-09-05 08:45:53.258078971 +0200
@@ -6631,7 +6631,9 @@ (define_operator_list SYNC_FETCH_AND_AND
    (with {
      auto prec = TYPE_PRECISION (type);
      auto unsign = TYPE_UNSIGNED (type);
-     tree inttype = build_nonstandard_integer_type (prec, unsign);
+     tree inttype = type;
+     if (TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != BITINT_TYPE)
+       inttype = build_nonstandard_integer_type (prec, unsign);
     }
     (convert (bit_xor (negate (convert:inttype @0)) (convert:inttype @2)))))))
 #endif


	Jakub


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 17/12] _BitInt a ? ~b : b match.pd fix [PR102989]
  2023-09-05  7:28 ` [PATCH 17/12] _BitInt a ? ~b : b match.pd fix [PR102989] Jakub Jelinek
@ 2023-09-05 21:27   ` Andrew Pinski
  2023-09-05 21:50     ` Jakub Jelinek
  0 siblings, 1 reply; 12+ messages in thread
From: Andrew Pinski @ 2023-09-05 21:27 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Andrew Pinski, Richard Biener, gcc-patches

On Tue, Sep 5, 2023 at 12:28 AM Jakub Jelinek via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> On Wed, Aug 09, 2023 at 12:19:54PM -0700, Andrew Pinski via Gcc-patches wrote:
> >       PR tree-optimization/110937
> >       PR tree-optimization/100798
> > --- a/gcc/match.pd
> > +++ b/gcc/match.pd
> > @@ -6460,6 +6460,20 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> >        (if (cmp == NE_EXPR)
> >         { constant_boolean_node (true, type); })))))))
> >
> > +#if GIMPLE
> > +/* a?~t:t -> (-(a))^t */
> > +(simplify
> > + (cond @0 @1 @2)
> > + (if (INTEGRAL_TYPE_P (type)
> > +      && bitwise_inverted_equal_p (@1, @2))
> > +  (with {
> > +    auto prec = TYPE_PRECISION (type);
> > +    auto unsign = TYPE_UNSIGNED (type);
> > +    tree inttype = build_nonstandard_integer_type (prec, unsign);
> > +   }
> > +   (convert (bit_xor (negate (convert:inttype @0)) (convert:inttype @2))))))
> > +#endif
>
> This broke one bitint test - bitint-42.c for -O1 and -Os (in admittedly not yet
> committed series).
> Using build_nonstandard_integer_type this way doesn't work well for larger
> precision BITINT_TYPEs, because it always creates an INTEGER_TYPE and
> say 467-bit INTEGER_TYPE doesn't work very well.  To get a BITINT_TYPE, one
> needs to use build_bitint_type instead (but similarly to
> build_nonstandard_integer_type one should first make sure such a type
> actually can be created).
>
> I admit it isn't really clear to me what do you want to achieve by the
> above build_nonstandard_integer_type.  Is it because of BOOLEAN_TYPE
> or perhaps ENUMERAL_TYPE as well?

Yes I was worried about types where the precision was set but MIN/MAX
of that type was not over the full precision and would not include
both 0 and allones in that range.
There is another match.pd pattern where we do a similar thing with
calling build_nonstandard_integer_type for a similar reason but
because we don't know if the type includes 0, 1, and allones in their
range.

>
> If type is INTEGER_TYPE or BITINT_TYPE, one doesn't really need to create a
> new type, type already is an integral type with that precision and
> signedness.  In other places using unsigned_type_for or signed_type_for
> might be better than using build_nonstandard_integer_type if that is what
> one wants to achieve, those functions handle BITINT_TYPE.

Maybe here we should just use `signed_or_unsigned_type_for (type,
TYPE_SIGN (type));`
instead of build_nonstandard_integer_type.

Thanks,
Andrew

>
> Or shall we instead test for == BOOLEAN_TYPE (or if ENUMERAL_TYPE for
> some reason needs the same treatment also || == ENUMERAL_TYPE)?
>
> 2023-09-05  Jakub Jelinek  <jakub@redhat.com>
>
>         PR c/102989
>         * match.pd (a ? ~b : b): Don't use build_nonstandard_integer_type
>         for INTEGER_TYPE or BITINT_TYPE.
>
> --- gcc/match.pd.jj     2023-09-04 09:45:33.553058301 +0200
> +++ gcc/match.pd        2023-09-05 08:45:53.258078971 +0200
> @@ -6631,7 +6631,9 @@ (define_operator_list SYNC_FETCH_AND_AND
>     (with {
>       auto prec = TYPE_PRECISION (type);
>       auto unsign = TYPE_UNSIGNED (type);
> -     tree inttype = build_nonstandard_integer_type (prec, unsign);
> +     tree inttype = type;
> +     if (TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != BITINT_TYPE)
> +       inttype = build_nonstandard_integer_type (prec, unsign);
>      }
>      (convert (bit_xor (negate (convert:inttype @0)) (convert:inttype @2)))))))
>  #endif
>
>
>         Jakub
>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 17/12] _BitInt a ? ~b : b match.pd fix [PR102989]
  2023-09-05 21:27   ` Andrew Pinski
@ 2023-09-05 21:50     ` Jakub Jelinek
  2023-09-05 22:07       ` Andrew Pinski
  0 siblings, 1 reply; 12+ messages in thread
From: Jakub Jelinek @ 2023-09-05 21:50 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: Andrew Pinski, Richard Biener, gcc-patches

On Tue, Sep 05, 2023 at 02:27:10PM -0700, Andrew Pinski wrote:
> > I admit it isn't really clear to me what do you want to achieve by the
> > above build_nonstandard_integer_type.  Is it because of BOOLEAN_TYPE
> > or perhaps ENUMERAL_TYPE as well?
> 
> Yes I was worried about types where the precision was set but MIN/MAX
> of that type was not over the full precision and would not include
> both 0 and allones in that range.
> There is another match.pd pattern where we do a similar thing with
> calling build_nonstandard_integer_type for a similar reason but
> because we don't know if the type includes 0, 1, and allones in their
> range.

Ah, in that case you should use range_check_type, that is used already
in multiple spots in match.pd for the same purpose.  It can return NULL and
in that case one should punt on the optimization.  Otherwise, that is the
function which ensures that the type is unsigned and max + 1 is min and min
- 1 is max.
And for me, I should add BITINT_TYPE handling to that function.

> > If type is INTEGER_TYPE or BITINT_TYPE, one doesn't really need to create a
> > new type, type already is an integral type with that precision and
> > signedness.  In other places using unsigned_type_for or signed_type_for
> > might be better than using build_nonstandard_integer_type if that is what
> > one wants to achieve, those functions handle BITINT_TYPE.
> 
> Maybe here we should just use `signed_or_unsigned_type_for (type,
> TYPE_SIGN (type));`
> instead of build_nonstandard_integer_type.

No, signed_or_unsigned_type_for (TYPE_UNSIGNED (type), type) will just return
type.
  if (ANY_INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type) == unsignedp)
    return type;

	Jakub


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 17/12] _BitInt a ? ~b : b match.pd fix [PR102989]
  2023-09-05 21:50     ` Jakub Jelinek
@ 2023-09-05 22:07       ` Andrew Pinski
  2023-09-06  6:38         ` Jakub Jelinek
  0 siblings, 1 reply; 12+ messages in thread
From: Andrew Pinski @ 2023-09-05 22:07 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Andrew Pinski, Richard Biener, gcc-patches

On Tue, Sep 5, 2023 at 2:51 PM Jakub Jelinek <jakub@redhat.com> wrote:
>
> On Tue, Sep 05, 2023 at 02:27:10PM -0700, Andrew Pinski wrote:
> > > I admit it isn't really clear to me what do you want to achieve by the
> > > above build_nonstandard_integer_type.  Is it because of BOOLEAN_TYPE
> > > or perhaps ENUMERAL_TYPE as well?
> >
> > Yes I was worried about types where the precision was set but MIN/MAX
> > of that type was not over the full precision and would not include
> > both 0 and allones in that range.
> > There is another match.pd pattern where we do a similar thing with
> > calling build_nonstandard_integer_type for a similar reason but
> > because we don't know if the type includes 0, 1, and allones in their
> > range.
>
> Ah, in that case you should use range_check_type, that is used already
> in multiple spots in match.pd for the same purpose.  It can return NULL and
> in that case one should punt on the optimization.  Otherwise, that is the
> function which ensures that the type is unsigned and max + 1 is min and min
> - 1 is max.
> And for me, I should add BITINT_TYPE handling to that function.

Hmm maybe range_check_type is the correct one here.


>
> > > If type is INTEGER_TYPE or BITINT_TYPE, one doesn't really need to create a
> > > new type, type already is an integral type with that precision and
> > > signedness.  In other places using unsigned_type_for or signed_type_for
> > > might be better than using build_nonstandard_integer_type if that is what
> > > one wants to achieve, those functions handle BITINT_TYPE.
> >
> > Maybe here we should just use `signed_or_unsigned_type_for (type,
> > TYPE_SIGN (type));`
> > instead of build_nonstandard_integer_type.
>
> No, signed_or_unsigned_type_for (TYPE_UNSIGNED (type), type) will just return
> type.
>   if (ANY_INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type) == unsignedp)
>     return type;

Oh I missed that.

Note I notice another all to build_nonstandard_integer_type in this
match pattern which might also need to be fixed:
/* For (x << c) >> c, optimize into x & ((unsigned)-1 >> c) for
   unsigned x OR truncate into the precision(type) - c lowest bits
   of signed x (if they have mode precision or a precision of 1).  */
(simplify
 (rshift (nop_convert? (lshift @0 INTEGER_CST@1)) @@1)
 (if (wi::ltu_p (wi::to_wide (@1), element_precision (type)))
  (if (TYPE_UNSIGNED (type))
   (bit_and (convert @0) (rshift { build_minus_one_cst (type); } @1))
   (if (INTEGRAL_TYPE_P (type))
    (with {
      int width = element_precision (type) - tree_to_uhwi (@1);
      tree stype = build_nonstandard_integer_type (width, 0);
     }
     (if (width == 1 || type_has_mode_precision_p (stype))
      (convert (convert:stype @0))))))))

Do we have ranges on BITINT_TYPEs? If so the two_value_replacement
pattern in match.pd has a similar issue too.
(that is where I copied the code to use build_nonstandard_integer_type
from originally too.

Thanks,
Andrew


>
>         Jakub
>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 17/12] _BitInt a ? ~b : b match.pd fix [PR102989]
  2023-09-05 22:07       ` Andrew Pinski
@ 2023-09-06  6:38         ` Jakub Jelinek
  0 siblings, 0 replies; 12+ messages in thread
From: Jakub Jelinek @ 2023-09-06  6:38 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: Andrew Pinski, Richard Biener, gcc-patches

On Tue, Sep 05, 2023 at 03:07:15PM -0700, Andrew Pinski wrote:
> Note I notice another all to build_nonstandard_integer_type in this
> match pattern which might also need to be fixed:
> /* For (x << c) >> c, optimize into x & ((unsigned)-1 >> c) for
>    unsigned x OR truncate into the precision(type) - c lowest bits
>    of signed x (if they have mode precision or a precision of 1).  */
> (simplify
>  (rshift (nop_convert? (lshift @0 INTEGER_CST@1)) @@1)
>  (if (wi::ltu_p (wi::to_wide (@1), element_precision (type)))
>   (if (TYPE_UNSIGNED (type))
>    (bit_and (convert @0) (rshift { build_minus_one_cst (type); } @1))
>    (if (INTEGRAL_TYPE_P (type))
>     (with {
>       int width = element_precision (type) - tree_to_uhwi (@1);
>       tree stype = build_nonstandard_integer_type (width, 0);
>      }
>      (if (width == 1 || type_has_mode_precision_p (stype))
>       (convert (convert:stype @0))))))))
> 
> Do we have ranges on BITINT_TYPEs? If so the two_value_replacement
> pattern in match.pd has a similar issue too.
> (that is where I copied the code to use build_nonstandard_integer_type
> from originally too.

BITINT_TYPEs do have ranges like any other integral types.  But the larger
ones should be lowered shortly after IPA and arithmetics etc. on them
shouldn't appear in later passes.
Most BITINT_TYPEs or for the above cases overly large INTEGER_TYPEs
will not satisfy type_has_mode_precision_p (but it isn't a good idea
to create such types only to throw them away).
But some BITINT_TYPEs do have non-BLKmode TYPE_MODE, they follow what modes
get similarly sized structures, so on some targets one could get OImode or
XImode.  For the above case, I think we definitely don't want to emit
integral types with such modes because nothing during expansion will support
them.  So, I wonder if the above shouldn't do
      tree stype = NULL_TREE;
      if (width <= (targetm.scalar_mode_supported_p (TImode)
		    ? TImode : DImode))
	stype = build_nonstandard_integer_type (width, 0);
and || (stype && type_has_mode_precision_p (stype)))
so that we don't create types which wouldn't work.

	Jakub


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH] MATCH: [PR110937/PR100798] (a ? ~b : b) should be optimized to b ^ -(a)
  2023-08-08  7:43 ` Richard Biener
@ 2023-08-08 18:26   ` Andrew Pinski
  0 siblings, 0 replies; 12+ messages in thread
From: Andrew Pinski @ 2023-08-08 18:26 UTC (permalink / raw)
  To: Richard Biener; +Cc: Andrew Pinski, gcc-patches

On Tue, Aug 8, 2023 at 12:44 AM Richard Biener via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> On Tue, Aug 8, 2023 at 2:55 AM Andrew Pinski via Gcc-patches
> <gcc-patches@gcc.gnu.org> wrote:
> >
> > This adds a simple match pattern for this case.
> > I noticed it a couple of different places.
> > One while I was looking at code generation of a parser and
> > also while I was looking at locations where bitwise_inverted_equal_p
> > should be used more.
> >
> > OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions.
> >
> >         PR tree-optimization/110937
> >         PR tree-optimization/100798
> >
> > gcc/ChangeLog:
> >
> >         * match.pd (`a ? ~b : b`): Handle this
> >         case.
> >
> > gcc/testsuite/ChangeLog:
> >
> >         * gcc.dg/tree-ssa/bool-14.c: New test.
> >         * gcc.dg/tree-ssa/bool-15.c: New test.
> >         * gcc.dg/tree-ssa/phi-opt-33.c: New test.
> >         * gcc.dg/tree-ssa/20030709-2.c: Update testcase
> >         so `a ? -1 : 0` is not used to hit the match
> >         pattern.
> > ---
> >  gcc/match.pd                               | 13 +++++++++++++
> >  gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c |  5 +++--
> >  gcc/testsuite/gcc.dg/tree-ssa/bool-14.c    | 15 +++++++++++++++
> >  gcc/testsuite/gcc.dg/tree-ssa/bool-15.c    | 18 ++++++++++++++++++
> >  gcc/testsuite/gcc.dg/tree-ssa/phi-opt-33.c | 13 +++++++++++++
> >  5 files changed, 62 insertions(+), 2 deletions(-)
> >  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/bool-14.c
> >  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/bool-15.c
> >  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-33.c
> >
> > diff --git a/gcc/match.pd b/gcc/match.pd
> > index 9b4819e5be7..f887c517c81 100644
> > --- a/gcc/match.pd
> > +++ b/gcc/match.pd
> > @@ -6460,6 +6460,19 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
> >        (if (cmp == NE_EXPR)
> >         { constant_boolean_node (true, type); })))))))
> >
> > +#if GIMPLE
> > +/* a?~t:t -> (-(a))^t */
> > +(simplify
> > + (cond @0 @1 @2)
> > + (if (bitwise_inverted_equal_p (@1, @2))
>
> I'm not sure if that can ever match a not INTEGRAL_TYPE_P
> but we can have vector typed @1 and @2 and then the
> TYPE_PRECISION ask below would be wrong.  So can you
> add
>
>       INTEGRAL_TYPE_P (type)
>       && bitwise_in...
>
> if only for clarity?
>
> > +  (with {
> > +    auto prec = TYPE_PRECISION (type);
> > +    auto unsign = TYPE_UNSIGNED (type);
> > +    tree inttype = build_nonstandard_integer_type (prec, unsign);
> > +   }
> > +   (convert (bit_xor (negate (convert:inttype @0)) (convert:inttype @2))))))
>
> so we don't get to know which of @1 or @2 is "simpler" (the not
> explicitely inverted
> operand), I suppose that's the disadvantage of using bitwise_inverted_equal_p.
> I'll note that if you make bitwise_inverted_equal_p a match you'd need a :c on
> the 'cond' but otherwise complexity would be the same as match patterns are not
> "inlined".

Right, The disadvantage is definitely not knowing which is "simpler".
And I found a testcase which shows that but I suspect we can fix that.
```
int f(int a, int t)
{
  int t1 = ~t;
 return (a=='s' ? t : t1);
}
```
Basically we are missing transforming:
~(-(cast)(cmp)) into -(cast)(cmp`)
Filed as PR 110949 .

>
> In any case, OK with the INTEGRAL_TYPE_P check.
Will update the patch and commit it after a bootstrap/test.

Thanks,
Andrew

>
> Thanks,
> Richard.
>
> > +#endif
> > +
> >  /* Simplify pointer equality compares using PTA.  */
> >  (for neeq (ne eq)
> >   (simplify
> > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c
> > index 5009cd69cfe..78938f919d4 100644
> > --- a/gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c
> > +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c
> > @@ -29,15 +29,16 @@ union tree_node
> >  };
> >  int make_decl_rtl (tree, int);
> >  void *
> > -get_alias_set (t)
> > +get_alias_set (t, t1)
> >       tree t;
> > +     void *t1;
> >  {
> >    long set;
> >    if (t->decl.rtl)
> >      return (t->decl.rtl->fld[1].rtmem
> >             ? 0
> >             : (((t->decl.rtl ? t->decl.rtl: (make_decl_rtl (t, 0), t->decl.rtl)))->fld[1]).rtmem);
> > -  return (void*)-1;
> > +  return t1;
> >  }
> >
> >  /* There should be precisely one load of ->decl.rtl.  If there is
> > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/bool-14.c b/gcc/testsuite/gcc.dg/tree-ssa/bool-14.c
> > new file mode 100644
> > index 00000000000..0149380a63b
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/tree-ssa/bool-14.c
> > @@ -0,0 +1,15 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-O2 -fdump-tree-optimized-raw" } */
> > +/* PR tree-optimization/110937 */
> > +
> > +_Bool f2(_Bool a, _Bool b)
> > +{
> > +        if (a)
> > +          return !b;
> > +        return b;
> > +}
> > +
> > +/* We should be able to remove the conditional and convert it to an xor. */
> > +/* { dg-final { scan-tree-dump-not "gimple_cond " "optimized" } } */
> > +/* { dg-final { scan-tree-dump-not "gimple_phi " "optimized" } } */
> > +/* { dg-final { scan-tree-dump-times "bit_xor_expr, " 1 "optimized" } } */
> > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/bool-15.c b/gcc/testsuite/gcc.dg/tree-ssa/bool-15.c
> > new file mode 100644
> > index 00000000000..1f496663863
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/tree-ssa/bool-15.c
> > @@ -0,0 +1,18 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-O2 -fdump-tree-optimized-raw" } */
> > +/* PR tree-optimization/110937 */
> > +
> > +_Bool f2(int x, int y, int w, int z)
> > +{
> > +  _Bool a = x == y;
> > +  _Bool b = w == z;
> > +  if (a)
> > +    return !b;
> > +  return b;
> > +}
> > +
> > +/* We should be able to remove the conditional and convert it to an xor. */
> > +/* { dg-final { scan-tree-dump-not "gimple_cond " "optimized" } } */
> > +/* { dg-final { scan-tree-dump-not "gimple_phi " "optimized" } } */
> > +/* { dg-final { scan-tree-dump-not "ne_expr, " "optimized" } } */
> > +/* { dg-final { scan-tree-dump-times "bit_xor_expr, " 1 "optimized" } } */
> > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-33.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-33.c
> > new file mode 100644
> > index 00000000000..b79fe44187a
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-33.c
> > @@ -0,0 +1,13 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-O2 -fdump-tree-optimized-raw" } */
> > +/* PR tree-optimization/100798 */
> > +
> > +int f(int a, int t)
> > +{
> > +  return (a=='s' ? ~t : t);
> > +}
> > +
> > +/* This should be convert into t^-(a=='s').  */
> > +/* { dg-final { scan-tree-dump-times "bit_xor_expr, " 1 "optimized" } } */
> > +/* { dg-final { scan-tree-dump-times "negate_expr, " 1 "optimized" } } */
> > +/* { dg-final { scan-tree-dump-not "bit_not_expr, " "optimized" } } */
> > --
> > 2.31.1
> >

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH] MATCH: [PR110937/PR100798] (a ? ~b : b) should be optimized to b ^ -(a)
  2023-08-08  0:54 [PATCH] MATCH: [PR110937/PR100798] (a ? ~b : b) should be optimized to b ^ -(a) Andrew Pinski
@ 2023-08-08  7:43 ` Richard Biener
  2023-08-08 18:26   ` Andrew Pinski
  0 siblings, 1 reply; 12+ messages in thread
From: Richard Biener @ 2023-08-08  7:43 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: gcc-patches

On Tue, Aug 8, 2023 at 2:55 AM Andrew Pinski via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> This adds a simple match pattern for this case.
> I noticed it a couple of different places.
> One while I was looking at code generation of a parser and
> also while I was looking at locations where bitwise_inverted_equal_p
> should be used more.
>
> OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions.
>
>         PR tree-optimization/110937
>         PR tree-optimization/100798
>
> gcc/ChangeLog:
>
>         * match.pd (`a ? ~b : b`): Handle this
>         case.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.dg/tree-ssa/bool-14.c: New test.
>         * gcc.dg/tree-ssa/bool-15.c: New test.
>         * gcc.dg/tree-ssa/phi-opt-33.c: New test.
>         * gcc.dg/tree-ssa/20030709-2.c: Update testcase
>         so `a ? -1 : 0` is not used to hit the match
>         pattern.
> ---
>  gcc/match.pd                               | 13 +++++++++++++
>  gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c |  5 +++--
>  gcc/testsuite/gcc.dg/tree-ssa/bool-14.c    | 15 +++++++++++++++
>  gcc/testsuite/gcc.dg/tree-ssa/bool-15.c    | 18 ++++++++++++++++++
>  gcc/testsuite/gcc.dg/tree-ssa/phi-opt-33.c | 13 +++++++++++++
>  5 files changed, 62 insertions(+), 2 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/bool-14.c
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/bool-15.c
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-33.c
>
> diff --git a/gcc/match.pd b/gcc/match.pd
> index 9b4819e5be7..f887c517c81 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -6460,6 +6460,19 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>        (if (cmp == NE_EXPR)
>         { constant_boolean_node (true, type); })))))))
>
> +#if GIMPLE
> +/* a?~t:t -> (-(a))^t */
> +(simplify
> + (cond @0 @1 @2)
> + (if (bitwise_inverted_equal_p (@1, @2))

I'm not sure if that can ever match a not INTEGRAL_TYPE_P
but we can have vector typed @1 and @2 and then the
TYPE_PRECISION ask below would be wrong.  So can you
add

      INTEGRAL_TYPE_P (type)
      && bitwise_in...

if only for clarity?

> +  (with {
> +    auto prec = TYPE_PRECISION (type);
> +    auto unsign = TYPE_UNSIGNED (type);
> +    tree inttype = build_nonstandard_integer_type (prec, unsign);
> +   }
> +   (convert (bit_xor (negate (convert:inttype @0)) (convert:inttype @2))))))

so we don't get to know which of @1 or @2 is "simpler" (the not
explicitely inverted
operand), I suppose that's the disadvantage of using bitwise_inverted_equal_p.
I'll note that if you make bitwise_inverted_equal_p a match you'd need a :c on
the 'cond' but otherwise complexity would be the same as match patterns are not
"inlined".

In any case, OK with the INTEGRAL_TYPE_P check.

Thanks,
Richard.

> +#endif
> +
>  /* Simplify pointer equality compares using PTA.  */
>  (for neeq (ne eq)
>   (simplify
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c
> index 5009cd69cfe..78938f919d4 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c
> @@ -29,15 +29,16 @@ union tree_node
>  };
>  int make_decl_rtl (tree, int);
>  void *
> -get_alias_set (t)
> +get_alias_set (t, t1)
>       tree t;
> +     void *t1;
>  {
>    long set;
>    if (t->decl.rtl)
>      return (t->decl.rtl->fld[1].rtmem
>             ? 0
>             : (((t->decl.rtl ? t->decl.rtl: (make_decl_rtl (t, 0), t->decl.rtl)))->fld[1]).rtmem);
> -  return (void*)-1;
> +  return t1;
>  }
>
>  /* There should be precisely one load of ->decl.rtl.  If there is
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/bool-14.c b/gcc/testsuite/gcc.dg/tree-ssa/bool-14.c
> new file mode 100644
> index 00000000000..0149380a63b
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/bool-14.c
> @@ -0,0 +1,15 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized-raw" } */
> +/* PR tree-optimization/110937 */
> +
> +_Bool f2(_Bool a, _Bool b)
> +{
> +        if (a)
> +          return !b;
> +        return b;
> +}
> +
> +/* We should be able to remove the conditional and convert it to an xor. */
> +/* { dg-final { scan-tree-dump-not "gimple_cond " "optimized" } } */
> +/* { dg-final { scan-tree-dump-not "gimple_phi " "optimized" } } */
> +/* { dg-final { scan-tree-dump-times "bit_xor_expr, " 1 "optimized" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/bool-15.c b/gcc/testsuite/gcc.dg/tree-ssa/bool-15.c
> new file mode 100644
> index 00000000000..1f496663863
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/bool-15.c
> @@ -0,0 +1,18 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized-raw" } */
> +/* PR tree-optimization/110937 */
> +
> +_Bool f2(int x, int y, int w, int z)
> +{
> +  _Bool a = x == y;
> +  _Bool b = w == z;
> +  if (a)
> +    return !b;
> +  return b;
> +}
> +
> +/* We should be able to remove the conditional and convert it to an xor. */
> +/* { dg-final { scan-tree-dump-not "gimple_cond " "optimized" } } */
> +/* { dg-final { scan-tree-dump-not "gimple_phi " "optimized" } } */
> +/* { dg-final { scan-tree-dump-not "ne_expr, " "optimized" } } */
> +/* { dg-final { scan-tree-dump-times "bit_xor_expr, " 1 "optimized" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-33.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-33.c
> new file mode 100644
> index 00000000000..b79fe44187a
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-33.c
> @@ -0,0 +1,13 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized-raw" } */
> +/* PR tree-optimization/100798 */
> +
> +int f(int a, int t)
> +{
> +  return (a=='s' ? ~t : t);
> +}
> +
> +/* This should be convert into t^-(a=='s').  */
> +/* { dg-final { scan-tree-dump-times "bit_xor_expr, " 1 "optimized" } } */
> +/* { dg-final { scan-tree-dump-times "negate_expr, " 1 "optimized" } } */
> +/* { dg-final { scan-tree-dump-not "bit_not_expr, " "optimized" } } */
> --
> 2.31.1
>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH] MATCH: [PR110937/PR100798] (a ? ~b : b) should be optimized to b ^ -(a)
@ 2023-08-08  0:54 Andrew Pinski
  2023-08-08  7:43 ` Richard Biener
  0 siblings, 1 reply; 12+ messages in thread
From: Andrew Pinski @ 2023-08-08  0:54 UTC (permalink / raw)
  To: gcc-patches; +Cc: Andrew Pinski

This adds a simple match pattern for this case.
I noticed it a couple of different places.
One while I was looking at code generation of a parser and
also while I was looking at locations where bitwise_inverted_equal_p
should be used more.

OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions.

	PR tree-optimization/110937
	PR tree-optimization/100798

gcc/ChangeLog:

	* match.pd (`a ? ~b : b`): Handle this
	case.

gcc/testsuite/ChangeLog:

	* gcc.dg/tree-ssa/bool-14.c: New test.
	* gcc.dg/tree-ssa/bool-15.c: New test.
	* gcc.dg/tree-ssa/phi-opt-33.c: New test.
	* gcc.dg/tree-ssa/20030709-2.c: Update testcase
	so `a ? -1 : 0` is not used to hit the match
	pattern.
---
 gcc/match.pd                               | 13 +++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c |  5 +++--
 gcc/testsuite/gcc.dg/tree-ssa/bool-14.c    | 15 +++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/bool-15.c    | 18 ++++++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-33.c | 13 +++++++++++++
 5 files changed, 62 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/bool-14.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/bool-15.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-33.c

diff --git a/gcc/match.pd b/gcc/match.pd
index 9b4819e5be7..f887c517c81 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -6460,6 +6460,19 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
       (if (cmp == NE_EXPR)
        { constant_boolean_node (true, type); })))))))
 
+#if GIMPLE
+/* a?~t:t -> (-(a))^t */
+(simplify
+ (cond @0 @1 @2)
+ (if (bitwise_inverted_equal_p (@1, @2))
+  (with {
+    auto prec = TYPE_PRECISION (type);
+    auto unsign = TYPE_UNSIGNED (type);
+    tree inttype = build_nonstandard_integer_type (prec, unsign);
+   }
+   (convert (bit_xor (negate (convert:inttype @0)) (convert:inttype @2))))))
+#endif
+
 /* Simplify pointer equality compares using PTA.  */
 (for neeq (ne eq)
  (simplify
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c
index 5009cd69cfe..78938f919d4 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c
@@ -29,15 +29,16 @@ union tree_node
 };
 int make_decl_rtl (tree, int);
 void *
-get_alias_set (t)
+get_alias_set (t, t1)
      tree t;
+     void *t1;
 {
   long set;
   if (t->decl.rtl)
     return (t->decl.rtl->fld[1].rtmem 
 	    ? 0
 	    : (((t->decl.rtl ? t->decl.rtl: (make_decl_rtl (t, 0), t->decl.rtl)))->fld[1]).rtmem);
-  return (void*)-1;
+  return t1;
 }
 
 /* There should be precisely one load of ->decl.rtl.  If there is
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/bool-14.c b/gcc/testsuite/gcc.dg/tree-ssa/bool-14.c
new file mode 100644
index 00000000000..0149380a63b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/bool-14.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized-raw" } */
+/* PR tree-optimization/110937 */
+
+_Bool f2(_Bool a, _Bool b)
+{
+        if (a)
+          return !b;
+        return b;
+}
+
+/* We should be able to remove the conditional and convert it to an xor. */
+/* { dg-final { scan-tree-dump-not "gimple_cond " "optimized" } } */
+/* { dg-final { scan-tree-dump-not "gimple_phi " "optimized" } } */
+/* { dg-final { scan-tree-dump-times "bit_xor_expr, " 1 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/bool-15.c b/gcc/testsuite/gcc.dg/tree-ssa/bool-15.c
new file mode 100644
index 00000000000..1f496663863
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/bool-15.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized-raw" } */
+/* PR tree-optimization/110937 */
+
+_Bool f2(int x, int y, int w, int z)
+{
+  _Bool a = x == y;
+  _Bool b = w == z;
+  if (a)
+    return !b;
+  return b;
+}
+
+/* We should be able to remove the conditional and convert it to an xor. */
+/* { dg-final { scan-tree-dump-not "gimple_cond " "optimized" } } */
+/* { dg-final { scan-tree-dump-not "gimple_phi " "optimized" } } */
+/* { dg-final { scan-tree-dump-not "ne_expr, " "optimized" } } */
+/* { dg-final { scan-tree-dump-times "bit_xor_expr, " 1 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-33.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-33.c
new file mode 100644
index 00000000000..b79fe44187a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-33.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized-raw" } */
+/* PR tree-optimization/100798 */
+
+int f(int a, int t)
+{
+  return (a=='s' ? ~t : t);
+}
+
+/* This should be convert into t^-(a=='s').  */
+/* { dg-final { scan-tree-dump-times "bit_xor_expr, " 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "negate_expr, " 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-not "bit_not_expr, " "optimized" } } */
-- 
2.31.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2023-09-06  6:38 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-09 19:19 [PATCH] MATCH: [PR110937/PR100798] (a ? ~b : b) should be optimized to b ^ -(a) Andrew Pinski
2023-08-10 13:37 ` Christophe Lyon
2023-08-10 18:52   ` Andrew Pinski
2023-08-11  8:06     ` Christophe Lyon
2023-09-05  7:28 ` [PATCH 17/12] _BitInt a ? ~b : b match.pd fix [PR102989] Jakub Jelinek
2023-09-05 21:27   ` Andrew Pinski
2023-09-05 21:50     ` Jakub Jelinek
2023-09-05 22:07       ` Andrew Pinski
2023-09-06  6:38         ` Jakub Jelinek
  -- strict thread matches above, loose matches on Subject: below --
2023-08-08  0:54 [PATCH] MATCH: [PR110937/PR100798] (a ? ~b : b) should be optimized to b ^ -(a) Andrew Pinski
2023-08-08  7:43 ` Richard Biener
2023-08-08 18:26   ` Andrew Pinski

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).