https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67170
--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> --- Corrected variant, we hit the assert I put in the first one. Index: gcc/tree-ssa-alias.c =================================================================== --- gcc/tree-ssa-alias.c (revision 226852) +++ gcc/tree-ssa-alias.c (working copy) @@ -2153,6 +2153,37 @@ call_may_clobber_ref_p_1 (gcall *call, a return false; } + /* If the base of an indirect access is a parameter which by means + of the fnspec of ourselves not clobbered by us then it is surely + not modified by calls we do. */ + tree base_ptr; + tree fnspec; + if (TREE_CODE (base) == MEM_REF + && (base_ptr = TREE_OPERAND (base, 0)) + && TREE_CODE (base_ptr) == SSA_NAME + && SSA_NAME_IS_DEFAULT_DEF (base_ptr) + && SSA_NAME_VAR (base_ptr) + && TREE_CODE (SSA_NAME_VAR (base_ptr)) == PARM_DECL + && (fnspec = lookup_attribute ("fn spec", + TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl))))) + { + unsigned i = 0; + tree arg; + for (arg = DECL_ARGUMENTS (cfun->decl); + arg && arg != SSA_NAME_VAR (base_ptr); arg = DECL_CHAIN (arg), ++i) + ; + /* The static chain is a PARM_DECL as well for example so we may + not be able to find base_ptr in the list of arguments. */ + if (arg == SSA_NAME_VAR (base_ptr)) + { + fnspec = TREE_VALUE (TREE_VALUE (fnspec)); + if ((unsigned) TREE_STRING_LENGTH (fnspec) > i + 1 + && (TREE_STRING_POINTER (fnspec)[i + 1] == 'R' + || TREE_STRING_POINTER (fnspec)[i + 1] == 'r')) + return false; + } + } + /* Check if the base variable is call-clobbered. */ if (DECL_P (base)) return pt_solution_includes (gimple_call_clobber_set (call), base);