]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/59860 (ICE in compute_may_aliases, at tree-ssa-structalias...
authorJakub Jelinek <jakub@redhat.com>
Mon, 20 Jan 2014 18:18:21 +0000 (19:18 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 20 Jan 2014 18:18:21 +0000 (19:18 +0100)
PR middle-end/59860
* tree.h (fold_builtin_strcat): New prototype.
* builtins.c (fold_builtin_strcat): No longer static.  Add len
argument, if non-NULL, don't call c_strlen.  Optimize
directly into __builtin_memcpy instead of __builtin_strcpy.
(fold_builtin_2): Adjust fold_builtin_strcat caller.
* gimple-fold.c (gimple_fold_builtin): Handle BUILT_IN_STRCAT.

From-SVN: r206848

gcc/ChangeLog
gcc/builtins.c
gcc/gimple-fold.c
gcc/tree.h

index a199b8da9591d8f262ea69b1cca9d844b33f1cba..a57bffec83cf1fbc8a05d3ab0a3183cce1d4b305 100644 (file)
@@ -1,3 +1,13 @@
+2014-01-20  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/59860
+       * tree.h (fold_builtin_strcat): New prototype.
+       * builtins.c (fold_builtin_strcat): No longer static.  Add len
+       argument, if non-NULL, don't call c_strlen.  Optimize
+       directly into __builtin_memcpy instead of __builtin_strcpy.
+       (fold_builtin_2): Adjust fold_builtin_strcat caller.
+       * gimple-fold.c (gimple_fold_builtin): Handle BUILT_IN_STRCAT.
+
 2014-01-20  Uros Bizjak  <ubizjak@gmail.com>
 
        * config/i386/i386.c (ix86_avoid_lea_for_addr): Return false
index c597e44e58cff2789b6cc7130096efc66881674f..d2ea606260bcf58fd4b3b09b8c7b5c86366f912c 100644 (file)
@@ -191,7 +191,6 @@ static tree fold_builtin_varargs (location_t, tree, tree, bool);
 static tree fold_builtin_strpbrk (location_t, tree, tree, tree);
 static tree fold_builtin_strstr (location_t, tree, tree, tree);
 static tree fold_builtin_strrchr (location_t, tree, tree, tree);
-static tree fold_builtin_strcat (location_t, tree, tree);
 static tree fold_builtin_strncat (location_t, tree, tree, tree);
 static tree fold_builtin_strspn (location_t, tree, tree);
 static tree fold_builtin_strcspn (location_t, tree, tree);
@@ -10787,7 +10786,7 @@ fold_builtin_2 (location_t loc, tree fndecl, tree arg0, tree arg1, bool ignore)
       return fold_builtin_strstr (loc, arg0, arg1, type);
 
     case BUILT_IN_STRCAT:
-      return fold_builtin_strcat (loc, arg0, arg1);
+      return fold_builtin_strcat (loc, arg0, arg1, NULL_TREE);
 
     case BUILT_IN_STRSPN:
       return fold_builtin_strspn (loc, arg0, arg1);
@@ -11736,8 +11735,9 @@ fold_builtin_strpbrk (location_t loc, tree s1, tree s2, tree type)
    COMPOUND_EXPR in the chain will contain the tree for the simplified
    form of the builtin function call.  */
 
-static tree
-fold_builtin_strcat (location_t loc ATTRIBUTE_UNUSED, tree dst, tree src)
+tree
+fold_builtin_strcat (location_t loc ATTRIBUTE_UNUSED, tree dst, tree src,
+                    tree len)
 {
   if (!validate_arg (dst, POINTER_TYPE)
       || !validate_arg (src, POINTER_TYPE))
@@ -11755,14 +11755,15 @@ fold_builtin_strcat (location_t loc ATTRIBUTE_UNUSED, tree dst, tree src)
          /* See if we can store by pieces into (dst + strlen(dst)).  */
          tree newdst, call;
          tree strlen_fn = builtin_decl_implicit (BUILT_IN_STRLEN);
-         tree strcpy_fn = builtin_decl_implicit (BUILT_IN_STRCPY);
+         tree memcpy_fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
 
-         if (!strlen_fn || !strcpy_fn)
+         if (!strlen_fn || !memcpy_fn)
            return NULL_TREE;
 
          /* If the length of the source string isn't computable don't
-            split strcat into strlen and strcpy.  */
-         tree len = c_strlen (src, 1);
+            split strcat into strlen and memcpy.  */
+         if (! len)
+           len = c_strlen (src, 1);
          if (! len || TREE_SIDE_EFFECTS (len))
            return NULL_TREE;
 
@@ -11776,7 +11777,11 @@ fold_builtin_strcat (location_t loc ATTRIBUTE_UNUSED, tree dst, tree src)
          newdst = fold_build_pointer_plus_loc (loc, dst, newdst);
          newdst = builtin_save_expr (newdst);
 
-         call = build_call_expr_loc (loc, strcpy_fn, 2, newdst, src);
+         len = fold_convert_loc (loc, size_type_node, len);
+         len = size_binop_loc (loc, PLUS_EXPR, len,
+                               build_int_cst (size_type_node, 1));
+
+         call = build_call_expr_loc (loc, memcpy_fn, 3, newdst, src, len);
          return build2 (COMPOUND_EXPR, TREE_TYPE (dst), call, dst);
        }
       return NULL_TREE;
index bace6f892d2ef5eb32ad056dc2a775f707888e8c..569b49225b6f6a44e35bfadae1f6643f71ab2071 100644 (file)
@@ -921,6 +921,7 @@ gimple_fold_builtin (gimple stmt)
       break;
     case BUILT_IN_STRCPY:
     case BUILT_IN_STRNCPY:
+    case BUILT_IN_STRCAT:
       arg_idx = 1;
       type = 0;
       break;
@@ -996,6 +997,13 @@ gimple_fold_builtin (gimple stmt)
                                       val[1]);
       break;
 
+    case BUILT_IN_STRCAT:
+      if (val[1] && is_gimple_val (val[1]) && nargs == 2)
+       result = fold_builtin_strcat (loc, gimple_call_arg (stmt, 0),
+                                     gimple_call_arg (stmt, 1),
+                                     val[1]);
+      break;
+
     case BUILT_IN_FPUTS:
       if (nargs == 2)
        result = fold_builtin_fputs (loc, gimple_call_arg (stmt, 0),
index e22e53c152f2a1d963af6af4d1e3edcacb43b8be..e918ec54d24bd8771e3252c65ae436ab70f23cf0 100644 (file)
@@ -4527,6 +4527,7 @@ extern tree fold_call_expr (location_t, tree, bool);
 extern tree fold_builtin_fputs (location_t, tree, tree, bool, bool, tree);
 extern tree fold_builtin_strcpy (location_t, tree, tree, tree, tree);
 extern tree fold_builtin_strncpy (location_t, tree, tree, tree, tree, tree);
+extern tree fold_builtin_strcat (location_t, tree, tree, tree);
 extern tree fold_builtin_memory_chk (location_t, tree, tree, tree, tree, tree, tree, bool,
                                     enum built_in_function);
 extern tree fold_builtin_stxcpy_chk (location_t, tree, tree, tree, tree, tree, bool,