On 2026-10-20 7:27 a.m., Richard Biener wrote:
> So this is
> 
>   /* Two definitions are always different unless they can be interposed.  
> */
>   if (!__builtin_constant_p (def_fn0 == def_fn1))
>     abort();
> 
> and likely similar to the analyzer warnings which do
> 
>  __analyzer_eval (fn_ptr == calls_free); /* { dg-warning "TRUE" } */
> 
> and gcc.dg/pr44024.c which does
> 
>   if (foo == (void *)0)
>     link_error ();
> 
> are missed constant foldings.  We see
> 
>   _1 = .CANONICALIZE_FUNCPTR_FOR_COMPARE (foo);
>   if (_1 == 0B)
> 
> while I see that hppas canonicalization special-cases page zero
> and thus NULL, the documentation of canonicalize_funcptr_for_compare
> does not say that NULL is canonical.

I would say NULL is canonical.  The handling of canonicalization on hppa-linux
was copied from the hpux SOM target.  However, the SOM target didn't support
undefined weak functions.  As you noted, __canonicalize_funcptr_for_compare
returns 0 if passed a NULL function pointer.

A function pointer on 32-bit hppa points to a function descriptor.  
Unfortunately,
function descriptors aren't unique and it's complicated to determine the actual
address of the function when lazy binding is in effect.

There is definitely confusion on this issue.  The tree-ssa/pr22051-1.c
test currently fails on hppa-linux because NULL is not canonicalized.

This has been the case for a long time, so I don't think we want to
change the current behavior.

If foo is defined, if (_1 == 0B) will never be true as function descriptors 
never
reside in page 0.  If you don't have that information, then we will have to give
up on the constant folding optimization.

> The equality is properly folded, but the analyzer doesn't know,
> 
> Inequality of two different decls is a missed optimization.
> 
> In general, can we elide canonicalization when comparing two
> decls?  That is, when does &function yield a canonical address?

I don't think it does in general because function descriptors are
not unique.  All we have is when a function is defined, function pointers
to its descriptors will be non NULL.

> 
> The way it is implemented now is that such comparisons are folded
> ignoring canonicalization which to me means that
> 
> (simplify
>  (tcc_comparison (.CANONICALIZE_FUNCPTR_FOR_COMPARE @0)
>   (.CANONICALIZE_FUNCPTR_FOR_COMPARE @1))
> 
> can be simplified if @0 @1 simplifies via address_compare?
> 
> I do wonder whether the not strict specification requires this to
> be target specific folding?  Did we ever have another port than pa
> to require this?

This is definitely specific to 32-bit pa although the use of function
descriptors isn't.
> Thanks for any hint,
> Richard.

Dave
-- 
John David Anglin  [email protected]

Reply via email to