https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94313
--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> --- This is likely because points-to computes the result of the string functions, for example in g1 it computes s_5 = { NULL STRING } and somehow ref_maybe_used_by_stmt_p computes false for *s and f(s). That's from if (pt_solutions_intersect (gimple_call_use_set (call), &pi->pt)) return true; where the points-to set for s_5 demotes to $8 = {anything = 0, nonlocal = 0, escaped = 0, ipa_escaped = 0, null = 1, vars_contains_nonlocal = 0, vars_contains_escaped = 0, vars_contains_escaped_heap = 0, vars_contains_restrict = 0, vars_contains_interposable = 0, vars = 0x7ffff6d7c520} so we dropped STRING which we do as follows: else if (vi->id == string_id) /* Nobody cares - STRING_CSTs are read-only entities. */ ; which is of course true, since nothing can modify STRING_CSTs we can technically ignore uses of appearant modifications. Now the inconsistency is that we treat MEM[(char *)"abc"] = 120; f ("abc"); [tail call] differently - a missed optimization(?). Note that before one of my recent fixes we didn't even treat such stmts as stores (now we do). So I see nothing inherently wrong here.