re PR tree-optimization/59860 (ICE in compute_may_aliases, at tree-ssa-structalias.c:6843)
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
This commit is contained in:
parent
3e7291458b
commit
9a7eefec74
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue