diff options
author | Jakub Jelinek <jakub@redhat.com> | 2015-05-19 15:54:32 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2015-05-19 15:54:32 +0200 |
commit | a60c51fe4803ad63d909c819642490630d893152 (patch) | |
tree | 10eb4f7411e8dc56c8e74c0a8a4e98363bae7752 | |
parent | 0e50b62468123005202598f2a88b59f9ca695eb8 (diff) | |
download | gcc-a60c51fe4803ad63d909c819642490630d893152.zip gcc-a60c51fe4803ad63d909c819642490630d893152.tar.gz gcc-a60c51fe4803ad63d909c819642490630d893152.tar.bz2 |
re PR rtl-optimization/66187 (wrong code at -O1, -O2 and -O3 on x86_64-linux-gnu)
PR tree-optimization/66187
* match.pd ((bit_and (plus/minus (convert @0) (convert @1)) mask)):
Pass TYPE_SIGN to tree_int_cst_min_precision. If
!TYPE_OVERFLOW_WRAPS, ensure @4 is non-negative.
* gcc.c-torture/execute/pr66187.c: New test.
* gcc.dg/pr66187-1.c: New test.
* gcc.dg/pr66187-2.c: New test.
From-SVN: r223366
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/match.pd | 4 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr66187.c | 16 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr66187-1.c | 97 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr66187-2.c | 97 |
6 files changed, 227 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b2374c2..bd18867 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2015-05-19 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/66187 + * match.pd ((bit_and (plus/minus (convert @0) (convert @1)) mask)): + Pass TYPE_SIGN to tree_int_cst_min_precision. If + !TYPE_OVERFLOW_WRAPS, ensure @4 is non-negative. + 2015-05-19 David Malcolm <dmalcolm@redhat.com> * diagnostic.c (diagnostic_report_current_module): Strengthen diff --git a/gcc/match.pd b/gcc/match.pd index f277fe3..54500d9 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -1115,8 +1115,10 @@ along with GCC; see the file COPYING3. If not see /* The inner conversion must be a widening conversion. */ && TYPE_PRECISION (TREE_TYPE (@2)) > TYPE_PRECISION (TREE_TYPE (@0)) && types_match (@0, @1) - && (tree_int_cst_min_precision (@4, UNSIGNED) + && (tree_int_cst_min_precision (@4, TYPE_SIGN (TREE_TYPE (@0))) <= TYPE_PRECISION (TREE_TYPE (@0))) + && (TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0)) + || tree_int_cst_sgn (@4) >= 0) && single_use (@5)) (if (TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0))) (with { tree ntype = TREE_TYPE (@0); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a48c038..4933fee 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2015-05-19 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/66187 + * gcc.c-torture/execute/pr66187.c: New test. + * gcc.dg/pr66187-1.c: New test. + * gcc.dg/pr66187-2.c: New test. + 2015-05-19 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> * gcc.dg/vect/bb-slp-35.c: Adjust. diff --git a/gcc/testsuite/gcc.c-torture/execute/pr66187.c b/gcc/testsuite/gcc.c-torture/execute/pr66187.c new file mode 100644 index 0000000..1677e86 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr66187.c @@ -0,0 +1,16 @@ +/* PR tree-optimization/66187 */ + +int a = 1, e = -1; +short b, f; + +int +main () +{ + f = e; + int g = b < 0 ? 0 : f + b; + if ((g & -4) < 0) + a = 0; + if (a) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr66187-1.c b/gcc/testsuite/gcc.dg/pr66187-1.c new file mode 100644 index 0000000..62aea69 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr66187-1.c @@ -0,0 +1,97 @@ +/* PR tree-optimization/66187 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fno-wrapv" } */ + +__attribute__((noinline, noclone)) int +f0 (unsigned char x, unsigned char y) +{ + return (x + y) & 0x2ff; +} + +__attribute__((noinline, noclone)) int +f1 (unsigned char x, unsigned char y) +{ + return (x - y) & 0x2ff; +} + +__attribute__((noinline, noclone)) int +f2 (signed char x, signed char y) +{ + return (x + y) & -4; +} + +__attribute__((noinline, noclone)) int +f3 (signed char x, signed char y) +{ + return (x + y) & 0xf8; +} + +__attribute__((noinline, noclone)) int +f4 (signed char x, signed char y) +{ + return (x + y) & 0x78; +} + +__attribute__((noinline, noclone)) int +f5 (unsigned char x, unsigned char y) +{ + int a = x; + int b = y; + int c = a + b; + return c & 0x2ff; +} + +__attribute__((noinline, noclone)) int +f6 (unsigned char x, unsigned char y) +{ + int a = x; + int b = y; + int c = a - b; + return c & 0x2ff; +} + +__attribute__((noinline, noclone)) int +f7 (signed char x, signed char y) +{ + int a = x; + int b = y; + int c = a + b; + return c & -4; +} + +__attribute__((noinline, noclone)) int +f8 (signed char x, signed char y) +{ + int a = x; + int b = y; + int c = a + b; + return c & 0xf8; +} + +__attribute__((noinline, noclone)) int +f9 (signed char x, signed char y) +{ + int a = x; + int b = y; + int c = a + b; + return c & 0x78; +} + +int +main () +{ + if (__SCHAR_MAX__ != 127 || sizeof (int) != 4) + return 0; + if (f0 (0xff, 0xff) != 0xfe + || f1 (0, 1) != 0x2ff + || f2 (-2, 1) != -4 + || f3 (-2, 1) != 0xf8 + || f4 (-2, 1) != 0x78 + || f5 (0xff, 0xff) != 0xfe + || f6 (0, 1) != 0x2ff + || f7 (-2, 1) != -4 + || f8 (-2, 1) != 0xf8 + || f9 (-2, 1) != 0x78) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr66187-2.c b/gcc/testsuite/gcc.dg/pr66187-2.c new file mode 100644 index 0000000..580b233 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr66187-2.c @@ -0,0 +1,97 @@ +/* PR tree-optimization/66187 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fwrapv" } */ + +__attribute__((noinline, noclone)) int +f0 (unsigned char x, unsigned char y) +{ + return (x + y) & 0x2ff; +} + +__attribute__((noinline, noclone)) int +f1 (unsigned char x, unsigned char y) +{ + return (x - y) & 0x2ff; +} + +__attribute__((noinline, noclone)) int +f2 (signed char x, signed char y) +{ + return (x + y) & -4; +} + +__attribute__((noinline, noclone)) int +f3 (signed char x, signed char y) +{ + return (x + y) & 0xf8; +} + +__attribute__((noinline, noclone)) int +f4 (signed char x, signed char y) +{ + return (x + y) & 0x78; +} + +__attribute__((noinline, noclone)) int +f5 (unsigned char x, unsigned char y) +{ + int a = x; + int b = y; + int c = a + b; + return c & 0x2ff; +} + +__attribute__((noinline, noclone)) int +f6 (unsigned char x, unsigned char y) +{ + int a = x; + int b = y; + int c = a - b; + return c & 0x2ff; +} + +__attribute__((noinline, noclone)) int +f7 (signed char x, signed char y) +{ + int a = x; + int b = y; + int c = a + b; + return c & -4; +} + +__attribute__((noinline, noclone)) int +f8 (signed char x, signed char y) +{ + int a = x; + int b = y; + int c = a + b; + return c & 0xf8; +} + +__attribute__((noinline, noclone)) int +f9 (signed char x, signed char y) +{ + int a = x; + int b = y; + int c = a + b; + return c & 0x78; +} + +int +main () +{ + if (__SCHAR_MAX__ != 127 || sizeof (int) != 4) + return 0; + if (f0 (0xff, 0xff) != 0xfe + || f1 (0, 1) != 0x2ff + || f2 (-2, 1) != -4 + || f3 (-2, 1) != 0xf8 + || f4 (-2, 1) != 0x78 + || f5 (0xff, 0xff) != 0xfe + || f6 (0, 1) != 0x2ff + || f7 (-2, 1) != -4 + || f8 (-2, 1) != 0xf8 + || f9 (-2, 1) != 0x78) + __builtin_abort (); + return 0; +} |