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);