We're confused when void * pointers enter memcpy folding.  The
following fixes it.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2011-05-23  Richard Guenther  <rguent...@suse.de>

        PR middle-end/15419
        * builtins.c (fold_builtin_memory_op): Be less restrictive about
        what pointer types we accept for folding.

        * gcc.dg/memcpy-3.c: New testcase.

Index: gcc/builtins.c
===================================================================
--- gcc/builtins.c      (revision 174058)
+++ gcc/builtins.c      (working copy)
@@ -8509,6 +8509,9 @@ fold_builtin_memory_op (location_t loc,
         Perhaps we ought to inherit type from non-VOID argument here?  */
       STRIP_NOPS (src);
       STRIP_NOPS (dest);
+      if (!POINTER_TYPE_P (TREE_TYPE (src))
+         || !POINTER_TYPE_P (TREE_TYPE (dest)))
+       return NULL_TREE;
       /* As we fold (void *)(p + CST) to (void *)p + CST undo this here.  */
       if (TREE_CODE (src) == POINTER_PLUS_EXPR)
        {
@@ -8525,8 +8528,7 @@ fold_builtin_memory_op (location_t loc,
            dest = build1 (NOP_EXPR, TREE_TYPE (tem), dest);
        }
       srctype = TREE_TYPE (TREE_TYPE (src));
-      if (srctype
-         && TREE_CODE (srctype) == ARRAY_TYPE
+      if (TREE_CODE (srctype) == ARRAY_TYPE
          && !tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len))
        {
          srctype = TREE_TYPE (srctype);
@@ -8534,21 +8536,15 @@ fold_builtin_memory_op (location_t loc,
          src = build1 (NOP_EXPR, build_pointer_type (srctype), src);
        }
       desttype = TREE_TYPE (TREE_TYPE (dest));
-      if (desttype
-         && TREE_CODE (desttype) == ARRAY_TYPE
+      if (TREE_CODE (desttype) == ARRAY_TYPE
          && !tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
        {
          desttype = TREE_TYPE (desttype);
          STRIP_NOPS (dest);
          dest = build1 (NOP_EXPR, build_pointer_type (desttype), dest);
        }
-      if (!srctype || !desttype
-         || TREE_ADDRESSABLE (srctype)
-         || TREE_ADDRESSABLE (desttype)
-         || !TYPE_SIZE_UNIT (srctype)
-         || !TYPE_SIZE_UNIT (desttype)
-         || TREE_CODE (TYPE_SIZE_UNIT (srctype)) != INTEGER_CST
-         || TREE_CODE (TYPE_SIZE_UNIT (desttype)) != INTEGER_CST)
+      if (TREE_ADDRESSABLE (srctype)
+         || TREE_ADDRESSABLE (desttype))
        return NULL_TREE;
 
       src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
Index: gcc/testsuite/gcc.dg/memcpy-3.c
===================================================================
--- gcc/testsuite/gcc.dg/memcpy-3.c     (revision 0)
+++ gcc/testsuite/gcc.dg/memcpy-3.c     (revision 0)
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-optimized" } */
+
+int get_int(const void *p)
+{
+  int w;
+  __builtin_memcpy(&w, p, sizeof (int));
+  return w;
+}
+
+/* { dg-final { scan-tree-dump-not "memcpy" "optimized" } } */
+/* { dg-final { scan-tree-dump-times "MEM" 1 "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */

Reply via email to