re PR middle-end/19857 (alignment check of SSE constant fails in simple test program)
authorJakub Jelinek <jakub@redhat.com>
Wed, 16 Feb 2005 13:54:30 +0000 (14:54 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 16 Feb 2005 13:54:30 +0000 (14:54 +0100)
PR middle-end/19857
* fold-const.c (fold): Don't optimize (T)(x & cst) to
(T)x & (T)cst if (T)cst overflows.
* convert.c (convert_to_integer) <case POINTER_TYPE>: Pass
TYPE_UNSIGNED (type) as type_for_size's UNSIGNEDP argument.

* gcc.dg/tree-ssa/20050215-1.c: New test.
* gcc.c-torture/execute/20050215-1.c: New test.

From-SVN: r95106

gcc/ChangeLog
gcc/convert.c
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/20050215-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/20050215-1.c [new file with mode: 0644]

index fbbe2b5187878aa9ca3ebd07952deadb6d5cafaa..1dbbf273a042a2f1aaaf303506b622ab5bbee6a8 100644 (file)
@@ -1,3 +1,11 @@
+2005-02-16  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/19857
+       * fold-const.c (fold): Don't optimize (T)(x & cst) to
+       (T)x & (T)cst if (T)cst overflows.
+       * convert.c (convert_to_integer) <case POINTER_TYPE>: Pass
+       TYPE_UNSIGNED (type) as type_for_size's UNSIGNEDP argument.
+
 2005-02-15  Jeff Law  <law@redhat.com>
 
        * gcse.c (blocks_with_calls): New bitmap.
index 005d3e2089b2c2c50e481025a1791678070919e2..f1a38c2d240768803d09f713c69de198b6e28b80 100644 (file)
@@ -387,7 +387,8 @@ convert_to_integer (tree type, tree expr)
        expr = integer_zero_node;
       else
        expr = fold (build1 (CONVERT_EXPR,
-                            lang_hooks.types.type_for_size (POINTER_SIZE, 0),
+                            lang_hooks.types.type_for_size
+                               (POINTER_SIZE, TYPE_UNSIGNED (type)),
                             expr));
 
       return convert_to_integer (type, expr);
index ef31a32f54ef63a2f4630f92195659cffadb5c4a..5e2a8682c0980e6805d915343ec3bd8220588674 100644 (file)
@@ -6874,9 +6874,14 @@ fold (tree expr)
 #endif
            }
          if (change)
-           return fold (build2 (BIT_AND_EXPR, type,
-                                fold_convert (type, and0),
-                                fold_convert (type, and1)));
+           {
+             tem = build_int_cst_wide (type, TREE_INT_CST_LOW (and1),
+                                       TREE_INT_CST_HIGH (and1));
+             tem = force_fit_type (tem, 0, TREE_OVERFLOW (and1),
+                                   TREE_CONSTANT_OVERFLOW (and1));
+             return fold (build2 (BIT_AND_EXPR, type,
+                                  fold_convert (type, and0), tem));
+           }
        }
 
       /* Convert (T1)((T2)X op Y) into (T1)X op Y, for pointer types T1 and
index 34b9f12ddcdcd98b5a2f9d3c2d35267334d55e91..950407318abf036c87fc32318b74696f6c9a9ba1 100644 (file)
@@ -1,3 +1,9 @@
+2005-02-16  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/19857
+       * gcc.dg/tree-ssa/20050215-1.c: New test.
+       * gcc.c-torture/execute/20050215-1.c: New test.
+
 2005-02-15  Eric Christopher  <echristo@redhat.com>
 
        * gcc.dg/cpp/20050215-1.c: New file.
diff --git a/gcc/testsuite/gcc.c-torture/execute/20050215-1.c b/gcc/testsuite/gcc.c-torture/execute/20050215-1.c
new file mode 100644 (file)
index 0000000..f4920ce
--- /dev/null
@@ -0,0 +1,25 @@
+/* PR middle-end/19857 */
+
+typedef struct { char c[8]; } V
+#ifdef __ELF__
+  __attribute__ ((aligned (8)))
+#endif
+  ;
+typedef __SIZE_TYPE__ size_t;
+V v;
+void abort (void);
+
+int
+main (void)
+{
+  V *w = &v;
+  if (((size_t) ((float *) ((size_t) w & ~(size_t) 3)) % 8) != 0
+      || ((size_t) w & 1))
+    {
+#ifndef __ELF__
+      if (((size_t) &v & 7) == 0)
+#endif
+       abort ();
+    }
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20050215-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20050215-1.c
new file mode 100644 (file)
index 0000000..6ce5880
--- /dev/null
@@ -0,0 +1,13 @@
+/* PR middle-end/19857 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int i;
+int foo (void)
+{
+  return i & ~(unsigned int) 3;
+}
+
+/* Make sure the optimizers don't introduce overflow where one
+   did not exist in the original.  */
+/* { dg-final { scan-tree-dump-times "-0+4" 0 "optimized"} } */