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