From: Jakub Jelinek Date: Thu, 7 Jul 2016 21:52:31 +0000 (+0200) Subject: backport: re PR tree-optimization/71588 (ICE on valid code at -O2 and -O3 on x86_64... X-Git-Tag: releases/gcc-4.9.4~86 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=17642b8d352f88bfb3133f8015c8650d87a40fff;p=thirdparty%2Fgcc.git backport: 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) Backported from mainline 2016-06-21 Jakub Jelinek PR tree-optimization/71588 * tree-ssa-strlen.c (valid_builtin_call): New function. (adjust_last_stmt, strlen_optimize_stmt): Use it. * gcc.dg/pr71558.c: New test. From-SVN: r238144 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c8db5319f4e4..1fc09f34a5dc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,6 +1,12 @@ 2016-07-07 Jakub Jelinek Backported from mainline + 2016-06-21 Jakub Jelinek + + PR tree-optimization/71588 + * tree-ssa-strlen.c (valid_builtin_call): New function. + (adjust_last_stmt, strlen_optimize_stmt): Use it. + 2016-06-10 Jakub Jelinek PR middle-end/71494 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5a7410725aad..89aa60849019 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,6 +1,11 @@ 2016-07-07 Jakub Jelinek Backported from mainline + 2016-06-21 Jakub Jelinek + + PR tree-optimization/71588 + * gcc.dg/pr71558.c: New test. + 2016-06-10 Jakub Jelinek PR middle-end/71494 diff --git a/gcc/testsuite/gcc.dg/pr71558.c b/gcc/testsuite/gcc.dg/pr71558.c new file mode 100644 index 000000000000..33a648e108c7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr71558.c @@ -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); +} diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c index 8d99a31d5df9..bd6cbe82e827 100644 --- a/gcc/tree-ssa-strlen.c +++ b/gcc/tree-ssa-strlen.c @@ -768,6 +768,49 @@ 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_STRCHR: + case BUILT_IN_STRLEN: + /* 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_MEMCPY: + case BUILT_IN_MEMCPY_CHK: + case BUILT_IN_MEMPCPY: + case BUILT_IN_MEMPCPY_CHK: + case BUILT_IN_STPCPY: + case BUILT_IN_STPCPY_CHK: + case BUILT_IN_STRCAT: + case BUILT_IN_STRCAT_CHK: + case BUILT_IN_STRCPY: + case BUILT_IN_STRCPY_CHK: + /* 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 @@ -842,7 +885,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); @@ -1827,7 +1870,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: