https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128185
Richard Biener <rguenth at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |hubicka at gcc dot gnu.org,
| |rguenth at gcc dot gnu.org
--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
OK, so the issue is that IPA modref does not record any kills for A::A(),
instead we just have
loads:
stores:
Base 0: alias set 0
Ref 0: alias set 0
access: Parm 0 param offset:0 offset:0 size:-1 max_size:8192
Side effects
Nondeterministic
parm 0 flags: no_indirect_clobber no_direct_escape no_indirect_escape
no_indirect_read
otherwise it should work. modref sees
__attribute__((noinline))
void A::A (struct A * const this)
{
char[1024] * _1;
<bb 2> [local count: 1073741824]:
_1 = &this_2(D)->buf;
__builtin_memset (_1, 120, 1024);
return;
}
I'm not sure why for the store size is -1 even. Analyzing does
- Analyzing call:__builtin_memset (_1, 120, 1024);
- Function availability <= AVAIL_INTERPOSABLE.
and fnspec does not provide more specifics.
The following fixes it, but I suppose a "size specified by arg" fnspec
might be better. In theory 'a'...'i' would be still available for that...
Oh, and fnspec only says the argument _might_ be written(?) ...
diff --git a/gcc/ipa-modref.cc b/gcc/ipa-modref.cc
index 7883a90bcdd..8a1d5ec0079 100644
--- a/gcc/ipa-modref.cc
+++ b/gcc/ipa-modref.cc
@@ -1491,6 +1491,38 @@ modref_access_analysis::process_fnspec (gcall *call)
if (flags & (ECF_CONST | ECF_NOVOPS))
return;
+ if (gimple_call_builtin_p (call, BUILT_IN_MEMSET))
+ {
+ modref_parm_map map = parm_map_for_ptr (gimple_call_arg (call, 0));
+ if (map.parm_index == MODREF_LOCAL_MEMORY_PARM)
+ ;
+ else if (map.parm_index == MODREF_UNKNOWN_PARM)
+ record_unknown_store ();
+ else
+ {
+ modref_access_node a
+ = { 0, -1, -1, map.parm_offset, map.parm_index,
+ map.parm_offset_known, 0 };
+ tree size = gimple_call_arg (call, 2);
+ poly_int64 size_hwi;
+ if (poly_int_tree_p (size, &size_hwi))
+ a.size = a.max_size = size_hwi << LOG2_BITS_PER_UNIT;
+ if (m_summary)
+ m_summary->stores->insert (current_function_decl, 0, 0, a, false);
+ if (m_summary_lto)
+ m_summary_lto->stores->insert (current_function_decl,
+ 0, 0, a, false);
+ if (m_always_executed && a.useful_for_kill_p ())
+ {
+ if (m_summary)
+ modref_access_node::insert_kill (m_summary->kills, a, false);
+ if (m_summary_lto)
+ modref_access_node::insert_kill (m_summary_lto->kills, a,
false);
+ }
+ }
+ return;
+ }
+
attr_fnspec fnspec = gimple_call_fnspec (call);
/* If there is no fnpec we know nothing about loads & stores. */
if (!fnspec.known_p ())