diff mbox

Fix PR middle-end/71654 (missed shortening of a compare)

Message ID 20160809140416.3352-1-patrick@parcs.ath.cx
State New
Headers show

Commit Message

Patrick Palka Aug. 9, 2016, 2:04 p.m. UTC
Hi, this patch makes match.pd to shorten comparisons that involve a
sign-changing cast from a shorter unsigned type to a wider signed type.
This should be safe to do because a wider signed type can hold all the
possible values of a shorter unsigned type.

This change causes vrp23.c and vrp24.c to fail because it makes the
"n_sets > 0" tests within get trivially simplified by forwprop and so
there is nothing left to simplify by VRP.  Fixed by passing
-fno-tree-forwprop in these tests.

Bootstrapped + regtested on x86_64-pc-linux-gnu.  Does this look OK to commit?

gcc/ChangeLog:

	PR middle-end/71654
	* match.pd ((T)A CMP (T)B -> A CMP B): Allow (T)A to be a
	sign-changing cast from a shorter unsigned type to a wider
	signed type.

gcc/testsuite/ChangeLog:

	PR middle-end/71654
	* gcc.dg/c-c++-common/pr71654.c: New test.
	* gcc.dg/tree-ssa/vrp23: Add -fno-tree-forwprop to
	dg-options.
	* gcc.dg/tree-ssa/vrp24: Likewise.
---
 gcc/match.pd                          |  4 +++-
 gcc/testsuite/c-c++-common/pr71654.c  | 28 ++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/vrp23.c |  2 +-
 gcc/testsuite/gcc.dg/tree-ssa/vrp24.c |  2 +-
 4 files changed, 33 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/pr71654.c

Comments

Richard Biener Aug. 12, 2016, 10:45 a.m. UTC | #1
On Tue, Aug 9, 2016 at 4:04 PM, Patrick Palka <patrick@parcs.ath.cx> wrote:
> Hi, this patch makes match.pd to shorten comparisons that involve a
> sign-changing cast from a shorter unsigned type to a wider signed type.
> This should be safe to do because a wider signed type can hold all the
> possible values of a shorter unsigned type.
>
> This change causes vrp23.c and vrp24.c to fail because it makes the
> "n_sets > 0" tests within get trivially simplified by forwprop and so
> there is nothing left to simplify by VRP.  Fixed by passing
> -fno-tree-forwprop in these tests.
>
> Bootstrapped + regtested on x86_64-pc-linux-gnu.  Does this look OK to commit?

Ok.

Thanks,
Richard.

> gcc/ChangeLog:
>
>         PR middle-end/71654
>         * match.pd ((T)A CMP (T)B -> A CMP B): Allow (T)A to be a
>         sign-changing cast from a shorter unsigned type to a wider
>         signed type.
>
> gcc/testsuite/ChangeLog:
>
>         PR middle-end/71654
>         * gcc.dg/c-c++-common/pr71654.c: New test.
>         * gcc.dg/tree-ssa/vrp23: Add -fno-tree-forwprop to
>         dg-options.
>         * gcc.dg/tree-ssa/vrp24: Likewise.
> ---
>  gcc/match.pd                          |  4 +++-
>  gcc/testsuite/c-c++-common/pr71654.c  | 28 ++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.dg/tree-ssa/vrp23.c |  2 +-
>  gcc/testsuite/gcc.dg/tree-ssa/vrp24.c |  2 +-
>  4 files changed, 33 insertions(+), 3 deletions(-)
>  create mode 100644 gcc/testsuite/c-c++-common/pr71654.c
>
> diff --git a/gcc/match.pd b/gcc/match.pd
> index ac7cfff..da87b02 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -2350,7 +2350,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>      (if (TYPE_PRECISION (TREE_TYPE (@0)) > TYPE_PRECISION (TREE_TYPE (@00)))
>       /* If possible, express the comparison in the shorter mode.  */
>       (if ((cmp == EQ_EXPR || cmp == NE_EXPR
> -          || TYPE_UNSIGNED (TREE_TYPE (@0)) == TYPE_UNSIGNED (TREE_TYPE (@00)))
> +          || TYPE_UNSIGNED (TREE_TYPE (@0)) == TYPE_UNSIGNED (TREE_TYPE (@00))
> +          || (!TYPE_UNSIGNED (TREE_TYPE (@0))
> +              && TYPE_UNSIGNED (TREE_TYPE (@00))))
>           && (types_match (TREE_TYPE (@10), TREE_TYPE (@00))
>               || ((TYPE_PRECISION (TREE_TYPE (@00))
>                    >= TYPE_PRECISION (TREE_TYPE (@10)))
> diff --git a/gcc/testsuite/c-c++-common/pr71654.c b/gcc/testsuite/c-c++-common/pr71654.c
> new file mode 100644
> index 0000000..2942493
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/pr71654.c
> @@ -0,0 +1,28 @@
> +/* PR middle-end/71654  */
> +/* { dg-do link }  */
> +/* { dg-options "-O2" }  */
> +
> +unsigned char i0, i1;
> +
> +void foo (void);
> +
> +int
> +main (void)
> +{
> +  int j = i0;
> +  if (j < 4)
> +    {
> +      if (i0 & 4)
> +        foo ();
> +    }
> +
> +  unsigned int k = i1;
> +  if (k < 8)
> +    {
> +      if (i1 & 8)
> +        foo ();
> +    }
> +
> +  return 0;
> +}
> +
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp23.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp23.c
> index b877ccc..ae68c090 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/vrp23.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp23.c
> @@ -1,5 +1,5 @@
>  /* { dg-do compile } */
> -/* { dg-options "-O2 -fdump-tree-vrp1-details" } */
> +/* { dg-options "-O2 -fno-tree-forwprop -fdump-tree-vrp1-details" } */
>
>  void aa (void);
>  void aos (void);
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp24.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp24.c
> index e740575..853ee21 100644
> --- a/gcc/testsuite/gcc.dg/tree-ssa/vrp24.c
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp24.c
> @@ -1,5 +1,5 @@
>  /* { dg-do compile } */
> -/* { dg-options "-O2 -fdump-tree-vrp1-details" } */
> +/* { dg-options "-O2 -fno-tree-forwprop -fdump-tree-vrp1-details" } */
>
>
>  struct rtx_def;
> --
> 2.9.2.614.g990027a
>
diff mbox

Patch

diff --git a/gcc/match.pd b/gcc/match.pd
index ac7cfff..da87b02 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -2350,7 +2350,9 @@  DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
     (if (TYPE_PRECISION (TREE_TYPE (@0)) > TYPE_PRECISION (TREE_TYPE (@00)))
      /* If possible, express the comparison in the shorter mode.  */
      (if ((cmp == EQ_EXPR || cmp == NE_EXPR
-	   || TYPE_UNSIGNED (TREE_TYPE (@0)) == TYPE_UNSIGNED (TREE_TYPE (@00)))
+	   || TYPE_UNSIGNED (TREE_TYPE (@0)) == TYPE_UNSIGNED (TREE_TYPE (@00))
+	   || (!TYPE_UNSIGNED (TREE_TYPE (@0))
+	       && TYPE_UNSIGNED (TREE_TYPE (@00))))
 	  && (types_match (TREE_TYPE (@10), TREE_TYPE (@00))
 	      || ((TYPE_PRECISION (TREE_TYPE (@00))
 		   >= TYPE_PRECISION (TREE_TYPE (@10)))
diff --git a/gcc/testsuite/c-c++-common/pr71654.c b/gcc/testsuite/c-c++-common/pr71654.c
new file mode 100644
index 0000000..2942493
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr71654.c
@@ -0,0 +1,28 @@ 
+/* PR middle-end/71654  */
+/* { dg-do link }  */
+/* { dg-options "-O2" }  */
+
+unsigned char i0, i1;
+
+void foo (void);
+
+int
+main (void)
+{
+  int j = i0;
+  if (j < 4)
+    {
+      if (i0 & 4)
+        foo ();
+    }
+
+  unsigned int k = i1;
+  if (k < 8)
+    {
+      if (i1 & 8)
+        foo ();
+    }
+
+  return 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp23.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp23.c
index b877ccc..ae68c090 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/vrp23.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp23.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-vrp1-details" } */
+/* { dg-options "-O2 -fno-tree-forwprop -fdump-tree-vrp1-details" } */
 
 void aa (void);
 void aos (void);
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp24.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp24.c
index e740575..853ee21 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/vrp24.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp24.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-vrp1-details" } */
+/* { dg-options "-O2 -fno-tree-forwprop -fdump-tree-vrp1-details" } */
 
 
 struct rtx_def;