re PR tree-optimization/71588 (ICE on valid code at -O2 and -O3 on x86_64-linux-gnu: in execute_todo, at passes.c:2009)
PR tree-optimization/71588 * tree-ssa-strlen.c (valid_builtin_call): New function. (adjust_last_stmt, handle_builtin_memset, strlen_optimize_stmt): Use it. * gcc.dg/pr71558.c: New test. From-SVN: r237628
This commit is contained in:
parent
e71e8d944f
commit
0ad84f34fc
|
@ -1,3 +1,10 @@
|
|||
2016-06-21 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/71588
|
||||
* tree-ssa-strlen.c (valid_builtin_call): New function.
|
||||
(adjust_last_stmt, handle_builtin_memset, strlen_optimize_stmt): Use
|
||||
it.
|
||||
|
||||
2016-06-20 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR middle-end/71581
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2016-06-21 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/71588
|
||||
* gcc.dg/pr71558.c: New test.
|
||||
|
||||
2016-06-21 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
|
||||
|
||||
* c-c++-common/pr68657-1.c: Require ptr32plus support.
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
/* PR tree-optimization/71588 */
|
||||
|
||||
/* strcpy must not be pure, but make sure we don't ICE even when
|
||||
it is declared incorrectly. */
|
||||
char *strcpy (char *, const char *) __attribute__ ((__pure__));
|
||||
__SIZE_TYPE__ strlen (const char *);
|
||||
void *malloc (__SIZE_TYPE__);
|
||||
|
||||
char a[20];
|
||||
|
||||
char *
|
||||
foo (void)
|
||||
{
|
||||
__SIZE_TYPE__ b = strlen (a);
|
||||
char *c = malloc (b);
|
||||
return strcpy (c, a);
|
||||
}
|
|
@ -860,6 +860,66 @@ find_equal_ptrs (tree ptr, int idx)
|
|||
}
|
||||
}
|
||||
|
||||
/* Return true if STMT is a call to a builtin function with the right
|
||||
arguments and attributes that should be considered for optimization
|
||||
by this pass. */
|
||||
|
||||
static bool
|
||||
valid_builtin_call (gimple *stmt)
|
||||
{
|
||||
if (!gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
|
||||
return false;
|
||||
|
||||
tree callee = gimple_call_fndecl (stmt);
|
||||
switch (DECL_FUNCTION_CODE (callee))
|
||||
{
|
||||
case BUILT_IN_MEMCMP:
|
||||
case BUILT_IN_MEMCMP_EQ:
|
||||
case BUILT_IN_STRCHR:
|
||||
case BUILT_IN_STRCHR_CHKP:
|
||||
case BUILT_IN_STRLEN:
|
||||
case BUILT_IN_STRLEN_CHKP:
|
||||
/* The above functions should be pure. Punt if they aren't. */
|
||||
if (gimple_vdef (stmt) || gimple_vuse (stmt) == NULL_TREE)
|
||||
return false;
|
||||
break;
|
||||
|
||||
case BUILT_IN_CALLOC:
|
||||
case BUILT_IN_MALLOC:
|
||||
case BUILT_IN_MEMCPY:
|
||||
case BUILT_IN_MEMCPY_CHK:
|
||||
case BUILT_IN_MEMCPY_CHKP:
|
||||
case BUILT_IN_MEMCPY_CHK_CHKP:
|
||||
case BUILT_IN_MEMPCPY:
|
||||
case BUILT_IN_MEMPCPY_CHK:
|
||||
case BUILT_IN_MEMPCPY_CHKP:
|
||||
case BUILT_IN_MEMPCPY_CHK_CHKP:
|
||||
case BUILT_IN_MEMSET:
|
||||
case BUILT_IN_STPCPY:
|
||||
case BUILT_IN_STPCPY_CHK:
|
||||
case BUILT_IN_STPCPY_CHKP:
|
||||
case BUILT_IN_STPCPY_CHK_CHKP:
|
||||
case BUILT_IN_STRCAT:
|
||||
case BUILT_IN_STRCAT_CHK:
|
||||
case BUILT_IN_STRCAT_CHKP:
|
||||
case BUILT_IN_STRCAT_CHK_CHKP:
|
||||
case BUILT_IN_STRCPY:
|
||||
case BUILT_IN_STRCPY_CHK:
|
||||
case BUILT_IN_STRCPY_CHKP:
|
||||
case BUILT_IN_STRCPY_CHK_CHKP:
|
||||
/* The above functions should be neither const nor pure. Punt if they
|
||||
aren't. */
|
||||
if (gimple_vdef (stmt) == NULL_TREE || gimple_vuse (stmt) == NULL_TREE)
|
||||
return false;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* If the last .MEM setter statement before STMT is
|
||||
memcpy (x, y, strlen (y) + 1), the only .MEM use of it is STMT
|
||||
and STMT is known to overwrite x[strlen (x)], adjust the last memcpy to
|
||||
|
@ -935,7 +995,7 @@ adjust_last_stmt (strinfo *si, gimple *stmt, bool is_strcat)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!gimple_call_builtin_p (last.stmt, BUILT_IN_NORMAL))
|
||||
if (!valid_builtin_call (last.stmt))
|
||||
return;
|
||||
|
||||
callee = gimple_call_fndecl (last.stmt);
|
||||
|
@ -1811,7 +1871,7 @@ handle_builtin_memset (gimple_stmt_iterator *gsi)
|
|||
if (!stmt1 || !is_gimple_call (stmt1))
|
||||
return true;
|
||||
tree callee1 = gimple_call_fndecl (stmt1);
|
||||
if (!gimple_call_builtin_p (stmt1, BUILT_IN_NORMAL))
|
||||
if (!valid_builtin_call (stmt1))
|
||||
return true;
|
||||
enum built_in_function code1 = DECL_FUNCTION_CODE (callee1);
|
||||
tree size = gimple_call_arg (stmt2, 2);
|
||||
|
@ -2140,7 +2200,7 @@ strlen_optimize_stmt (gimple_stmt_iterator *gsi)
|
|||
if (is_gimple_call (stmt))
|
||||
{
|
||||
tree callee = gimple_call_fndecl (stmt);
|
||||
if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
|
||||
if (valid_builtin_call (stmt))
|
||||
switch (DECL_FUNCTION_CODE (callee))
|
||||
{
|
||||
case BUILT_IN_STRLEN:
|
||||
|
|
Loading…
Reference in New Issue