This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR middle-end/71654 (missed shortening of a compare)
- From: Patrick Palka <patrick at parcs dot ath dot cx>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Patrick Palka <patrick at parcs dot ath dot cx>
- Date: Tue, 9 Aug 2016 10:04:16 -0400
- Subject: [PATCH] Fix PR middle-end/71654 (missed shortening of a compare)
- Authentication-results: sourceware.org; auth=none
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
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