public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug tree-optimization/114959] New: incorrect TBAA for drived types involving function types
@ 2024-05-06 11:19 muecker at gwdg dot de
  2024-05-06 11:42 ` [Bug tree-optimization/114959] " rguenth at gcc dot gnu.org
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: muecker at gwdg dot de @ 2024-05-06 11:19 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114959

            Bug ID: 114959
           Summary: incorrect TBAA for drived types involving function
                    types
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: muecker at gwdg dot de
  Target Milestone: ---

The  example below shows that aliasing analysis treats some derived types as
incompatible even though they are derived from compatible types char (*)[1] and
char (*)[] and should then be compatible themselves.


The effect type rules are defined in "6.5 Expressions" and allows accesses with 

— a type compatible with the effective type of the object,
— a qualified version of a type compatible with the effective type of the
object,
— a type that is the signed or unsigned type corresponding to the effective
type of the object,
— a type that is the signed or unsigned type corresponding to a qualified
version of the effective type of the object,
— an aggregate or union type that includes one of the aforementioned types
among its members
(including, recursively, a member of a subaggregate or contained union), or
— a character type.

The relevant condition is the first which refers to type compatibility.
Type compatibility rules are defined in "6.2.7 Type compatibility and composite
type"

"Two types are compatible types if they are the same. Additional rules for
determining whether two types are compatible are described in 6.7.2 for type
specifiers, in 6.7.3 for type qualifiers, and in 6.7.6 for declarators.58)
Moreover, two complete structure, union, or enumerated types declared..."

In 6.7.6 we then have

"For two pointer types to be compatible, both shall be identically qualified
and both shall be pointers to compatible types."

"For two array types to be compatible, both shall have compatible element
types, and if both size specifiers are present, and are integer constant
expressions, then both size specifiers shall have the same constant value."

"For two function types to be compatible, both shall specify compatible return
types. Moreover, the parameter type lists shall agree in the number of
parameters and in use of the final ellipsis; corresponding parameters shall
have compatible types. In the determination of type compatibility and of a
composite type, each parameter declared with function or array type is taken as
having the adjusted type and each parameter declared with qualified type is
taken as having the unqualified version of its declared type."


So type compatibility builds up recursively and types derived in the same way
from different but compatible types are compatible.



Example:


https://godbolt.org/z/rTsE3PhKc


#define COMPAT

typedef char (*(*t0)())[];
typedef char (*(*t1)())[1];
#ifdef COMPAT
typedef char (*(*t2)())[/*2*/];
#else
typedef char (*(*t2)())[2];
#endif

//[[gnu::noinline]]
t0 foo(t0 *x, t0 *y, t0 u, t0 v)
{
    t1 *a = x;
    t2 *b = y;
#ifdef COMPAT
    _Static_assert(_Generic(*b, typeof(*a): 1, default: 0), "");
#endif
    (*a) = u;
    // since *a and *b alias and the types are compatible,
    // this should overwrite the result
    (*b) = v;   
    return *a;
}


char (*(a()))[1] { return 0; }
char (*(b()))[2] { return 0; }

int main()
{
    t0 t;
    return &a == foo(&t, &t, &a, &b);
}

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug tree-optimization/114959] incorrect TBAA for drived types involving function types
  2024-05-06 11:19 [Bug tree-optimization/114959] New: incorrect TBAA for drived types involving function types muecker at gwdg dot de
@ 2024-05-06 11:42 ` rguenth at gcc dot gnu.org
  2024-05-06 15:02 ` muecker at gwdg dot de
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: rguenth at gcc dot gnu.org @ 2024-05-06 11:42 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114959

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Version|unknown                     |14.0
           Keywords|                            |wrong-code
                 CC|                            |hubicka at gcc dot gnu.org

--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
alias.c does

  /* See if the language has special handling for this type.  */
  set = lang_hooks.get_alias_set (t);
  if (set != -1)
    return set;

  /* There are no objects of FUNCTION_TYPE, so there's no point in
     using up an alias set for them.  (There are, of course, pointers
     and references to functions, but that's different.)  */
  else if (TREE_CODE (t) == FUNCTION_TYPE || TREE_CODE (t) == METHOD_TYPE)
    set = 0;

but when handling pointer-to-function we simply create a new alias-set
for each distinct (according to TYPE_CANONICAL (TYPE_MAIN_VARIANT ())))
pointed-to type.

It's going to be difficult to canonicalize return and argument types
here, so the answer is probably tree.cc:maybe_canonicalize_argtypes
and thus reflecting this in the TYPE_CANONICAL of the function type.

Note this is also how we handle pointer to structure types, but as
structures are real objects those already have TYPE_CANONICAL set up
appropriately.  So I wonder whether the C frontend doesn't need to do
the same for FUNCTION_TYPEs rather than putting the burden on the
middle-end here?

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug tree-optimization/114959] incorrect TBAA for drived types involving function types
  2024-05-06 11:19 [Bug tree-optimization/114959] New: incorrect TBAA for drived types involving function types muecker at gwdg dot de
  2024-05-06 11:42 ` [Bug tree-optimization/114959] " rguenth at gcc dot gnu.org
@ 2024-05-06 15:02 ` muecker at gwdg dot de
  2024-05-07  6:47 ` rguenth at gcc dot gnu.org
  2024-05-07 12:05 ` hubicka at ucw dot cz
  3 siblings, 0 replies; 5+ messages in thread
From: muecker at gwdg dot de @ 2024-05-06 15:02 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114959

--- Comment #2 from Martin Uecker <muecker at gwdg dot de> ---

The GCC FE has all the necessary logic to compute type compatibility and this
could easily be adapted to compute equivalence classes and then set a
TYPE_CANONICAL. All function types in the same class would get the same
TYPE_CANONICAL even if a little bit different, i.e. return pointers to
compatible but slightly different array types.   I think function arguments we
need to ignore completely, because 

T (*f)();

is compatible with all pointers to functions with the same return type. (this
is gone in C23 though) Or we special case such functions.

What is unclear to me whether function types are the only remaining issue or
whether this should then be done for all types (pointers, arrays, etc)?

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug tree-optimization/114959] incorrect TBAA for drived types involving function types
  2024-05-06 11:19 [Bug tree-optimization/114959] New: incorrect TBAA for drived types involving function types muecker at gwdg dot de
  2024-05-06 11:42 ` [Bug tree-optimization/114959] " rguenth at gcc dot gnu.org
  2024-05-06 15:02 ` muecker at gwdg dot de
@ 2024-05-07  6:47 ` rguenth at gcc dot gnu.org
  2024-05-07 12:05 ` hubicka at ucw dot cz
  3 siblings, 0 replies; 5+ messages in thread
From: rguenth at gcc dot gnu.org @ 2024-05-07  6:47 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114959

--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Martin Uecker from comment #2)
> The GCC FE has all the necessary logic to compute type compatibility and
> this could easily be adapted to compute equivalence classes and then set a
> TYPE_CANONICAL. All function types in the same class would get the same
> TYPE_CANONICAL even if a little bit different, i.e. return pointers to
> compatible but slightly different array types.   I think function arguments
> we need to ignore completely, because 
> 
> T (*f)();
> 
> is compatible with all pointers to functions with the same return type.
> (this is gone in C23 though) Or we special case such functions.
> 
> What is unclear to me whether function types are the only remaining issue or
> whether this should then be done for all types (pointers, arrays, etc)?

I think function types are somewhat special in that they do not denote
objects in the classical sense.  They are also most complex and probably
target-dependent to handle.

Note there's LTO where we glob all pointers to a single equivalence class
because of Fortran where C_PTR inter-operates with all pointer types.  But
LTO would compute FUNCTION_TYPE TYPE_CANONICAL in a less conservative way
than required for the above rule for C.  That said, we do not stream
TYPE_CANONICAL into the LTO IL but instead attempt to recompute it
(for the sole purpose of TBAA) in a way compatible with all language frontends
(without considering possible knowledge of frontends involved in the link).

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug tree-optimization/114959] incorrect TBAA for drived types involving function types
  2024-05-06 11:19 [Bug tree-optimization/114959] New: incorrect TBAA for drived types involving function types muecker at gwdg dot de
                   ` (2 preceding siblings ...)
  2024-05-07  6:47 ` rguenth at gcc dot gnu.org
@ 2024-05-07 12:05 ` hubicka at ucw dot cz
  3 siblings, 0 replies; 5+ messages in thread
From: hubicka at ucw dot cz @ 2024-05-07 12:05 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114959

--- Comment #4 from Jan Hubicka <hubicka at ucw dot cz> ---
> 
> I think function types are somewhat special in that they do not denote
> objects in the classical sense.  They are also most complex and probably
> target-dependent to handle.
> 
> Note there's LTO where we glob all pointers to a single equivalence class
> because of Fortran where C_PTR inter-operates with all pointer types.  But

We special case void * to alias with all other pointer types and look
through pointers in alias.cc, so accesses through pointers are not
necessarily fully globbed.

I plan to look into unglobbing pointers when Fortran C_PTR can not clash
since this is relatively important piece of TBAA information.

Honza

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2024-05-07 12:05 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-05-06 11:19 [Bug tree-optimization/114959] New: incorrect TBAA for drived types involving function types muecker at gwdg dot de
2024-05-06 11:42 ` [Bug tree-optimization/114959] " rguenth at gcc dot gnu.org
2024-05-06 15:02 ` muecker at gwdg dot de
2024-05-07  6:47 ` rguenth at gcc dot gnu.org
2024-05-07 12:05 ` hubicka at ucw dot cz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).