aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2015-05-19 15:54:32 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2015-05-19 15:54:32 +0200
commita60c51fe4803ad63d909c819642490630d893152 (patch)
tree10eb4f7411e8dc56c8e74c0a8a4e98363bae7752 /gcc
parent0e50b62468123005202598f2a88b59f9ca695eb8 (diff)
downloadgcc-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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/match.pd4
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr66187.c16
-rw-r--r--gcc/testsuite/gcc.dg/pr66187-1.c97
-rw-r--r--gcc/testsuite/gcc.dg/pr66187-2.c97
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;
+}