https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121814
Richard Biener <rguenth at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Ever confirmed|0 |1
Status|UNCONFIRMED |NEW
CC| |hubicka at gcc dot gnu.org,
| |rguenth at gcc dot gnu.org
Keywords| |wrong-code
Last reconfirmed| |2025-09-08
--- Comment #13 from Richard Biener <rguenth at gcc dot gnu.org> ---
So we have
ESCAPED, points-to non-local, points-to NULL, points-to const-pool, points-to
vars: { D.43798 D.54465 D.58783 } (nonlocal, escaped, escaped heap,
interposable)
# PT = nonlocal escaped null { D.54465 } (escaped)
pi_13 = tmpD.54466;
if (&iD.54461 != pi_13)
and for
putD.54384 (&ss_01D.54465, &iD.54461);
we generate the constraints
callescape(13) = NONLOCAL
CALLUSED(14) = callescape(13)
callarg(16) = &ss_01.0+64
callarg(16) = callarg(16) + UNKNOWN
callarg(16) = *callarg(16) + UNKNOWN
CALLUSED(14) = callarg(16)
*callarg(16) = callescape(13)
CALLCLOBBERED(15) = callarg(16)
callescape(13) = callarg(16)
ESCAPED = &ss_01.0+64
'put's only use of the 2nd arg is
<bb 2> :
__v_11 = (long unsigned intD.16) __vv_10(D);
and modref computes for this argument
parm 1 flags: no_direct_clobber no_indirect_clobber no_direct_escape
no_indirect_escape no_direct_read no_indirect_read
I'll note this is inconsistent with what points-to itself would compute
when inlining 'put', since we'd track the pointer through the transform
to a string.
I'm not sure where modref stops tracking - the most precise answer would
be that parameter 1 escapes to what parameter 0 points to? For simple
testcases this works fine, "simple" as in as complicated as
void foo (unsigned long *p, int *q)
{
for (int i = 0; i < 8; ++i)
((char *)p)[i] = (unsigned long)q >> (i * 8);
}
With -fno-ipa-modref we inline stuff (but not 'put') and then end up with
# PT = nonlocal null
__ul.4_45 = (voidD.54 *) __result_44;
__begD.58822 ={v} {CLOBBER(eos)};
if (&iD.54461 != __ul.4_45)
somewhere the 'escaped' gets lost. The issue is the pointer tracking
through equivalences here:
if (_53 == &MEM <const charD.10[16]> [(voidD.54 *)&s_in_atomsD.56708 + 16B])
goto <bb 13>; [5.50%]
else
goto <bb 9>; [94.50%]
<bb 9> [local count: 1014686025]:
_34 = _53 - &s_in_atomsD.56708;
__digit_35 = (intD.9) _34;
basically we track pointers as you store them piecewise, but when you then
extract them by if (p == q) .. use q .., then we lose the association.
This is a known issue, there's duplicates of this. And the modref issue
is exactly the same.
In principle for the constraint-based points-to any equality compare
would need a unification constraint. Likewise modref would need to
handle things this way.