https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87627
--- Comment #6 from Alexander Monakov <amonakov at gcc dot gnu.org> --- FWIW the following CSE enhancement cleans this up, but I'm unhappy with this patch because it's too narrowly targeted; in particular, won't clean up void g(int a, int *b, int c); void f(int a, int *b, int c) { if (a) *b = c; g(a, b, c); } Had to special-case for PARM_DECL because, in general, automatic variables that are not address-taken on GIMPLE can become addressable on RTL when ABI requires passing a large argument by reference. --- a/gcc/cse.c +++ b/gcc/cse.c @@ -2232,6 +2232,15 @@ hash_rtx_string (const char *ps) return hash; } +static bool +mem_escapes_p (const_rtx x) +{ + tree decl = MEM_EXPR (x); + if (!decl || TREE_CODE (decl) != PARM_DECL) + return true; + return may_be_aliased (decl); +} + /* Same as hash_rtx, but call CB on each rtx if it is not NULL. When the callback returns true, we continue with the new rtx. */ @@ -2421,7 +2430,8 @@ hash_rtx_cb (const_rtx x, machine_mode mode, return 0; } if (hash_arg_in_memory_p && !MEM_READONLY_P (x)) - *hash_arg_in_memory_p = 1; + if (*hash_arg_in_memory_p != 1) + *hash_arg_in_memory_p = mem_escapes_p (x) ? 1 : 2; /* Now that we have already found this special case, might as well speed it up as much as possible. */ @@ -6127,7 +6137,7 @@ invalidate_memory (void) for (p = table[i]; p; p = next) { next = p->next_same_hash; - if (p->in_memory) + if (p->in_memory == 1) remove_from_table (p, i); } }