https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103182
--- Comment #5 from Jan Hubicka <hubicka at gcc dot gnu.org> --- What happens here is that we optimize the loop to memcpy and memcpy EAF flags coming from fnspec are quite interesting. The copied argument is marked as escaping but used only directly. This is correct but not what modref expects since it generally punts on tracking anything stored in memory, so it needs to give up on all other flags which it doesn't. diff --git a/gcc/ipa-modref.c b/gcc/ipa-modref.c index e999c2c5d1e..c705a67daf7 100644 --- a/gcc/ipa-modref.c +++ b/gcc/ipa-modref.c @@ -1888,19 +1888,18 @@ callee_to_caller_flags (int call_flags, bool ignore_stores, that is not the same as caller returning it. */ call_flags |= EAF_NOT_RETURNED_DIRECTLY | EAF_NOT_RETURNED_INDIRECTLY; - /* TODO: We miss return value propagation. - Be conservative and if value escapes to memory - also mark it as escaping. */ if (!ignore_stores && !(call_flags & EAF_UNUSED)) { + /* If value escapes we are no longer able to track what happens + with it because we can read it from the escaped location + anytime. */ if (!(call_flags & EAF_NO_DIRECT_ESCAPE)) - lattice.merge (~(EAF_NOT_RETURNED_DIRECTLY - | EAF_NOT_RETURNED_INDIRECTLY - | EAF_NO_DIRECT_READ - | EAF_UNUSED)); - if (!(call_flags & EAF_NO_INDIRECT_ESCAPE)) + lattice.merge (0); + else if (!(call_flags & EAF_NO_INDIRECT_ESCAPE)) lattice.merge (~(EAF_NOT_RETURNED_INDIRECTLY | EAF_NO_DIRECT_READ + | EAF_NO_INDIRECT_READ + | EAF_NO_INDIRECT_CLOBBER | EAF_UNUSED)); } else