On 2026-10-20 2:04 p.m., Jeff Law wrote: > > > On 10/20/26 8:16 AM, John David Anglin wrote: >> >> 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. > Right. They're definitely not unique. > > What I remember was that you could mask off the low bit and dereference that > word (or some offset from that word) and you'd get the function's > real address, but that even that case wasn't handled consistently enough to > get to proper ANSI/ISO behavior. > >> >> 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.
I believe more correctly that if (_1 == 0B) will never be true when foo is not weak. In linking a final executable, the linker will generate an error if the function foo is not weak and it isn't resolved. It may be possible to override this linker behavior but I'm not sure one should expect the application to execute correctly when foo isn't resolved. If foo is weak, _1 may or may not be NULL. If _1 is not NULL, then __canonicalize_funcptr_for_compare will generally return the function's code address or on of the small special values. If the PLABEL bit isn't set, __canonicalize_funcptr_for_compare assumes the function pointer points directly to the function's code. > Given that a pdir pointing to location 0 has the magic low order bit off, > then canonicalizion shouldn't be needed and you can compare directly. > Or am I mis-remembering. What you are missing is the handling of lazy binding. Before binding, the function pointer in the descriptor doesn't point to the function. It points to trampoline code that sets up the descriptor. Thus, it's not possible to simply compare pointer values from the descriptors. __canonicalize_funcptr_for_compare calls the fixup routing in glibc when the descriptor hasn't been bound and then returns the function's code address. You are correct that when the PLABEL bit isn't set in a function pointer, then the pointer points directly to the function's code. But almost no code uses this feature as there is no support for shared libraries. I think clisp may be the only Debian package to use this. It is completely self sufficient. GCC is built assuming the PLABEL bit is set in function pointers. Canonicalization is disable on the 32-bit portable runtime. Currently, _1 is not canonicalized in comparisons with NULL. This is not obvious but it seems do_compare_and_jump isn't called in this case. I believe the exiting tree optimizations eliminate the comparison. We could change this to canonicalize _1 but then we lose the constant folding optimizations that we currently have. I haven't seen any issues with the current canonicalization. Possibly, Richard could delay canonicalization in the tree code until constant folding has been done? The last change to the canonicalize_funcptr_for_compare expander handled the canonicalization of SYMBOL_REFs that aren't function pointers. There was a testcase where this occurred. >>> 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. > That's my recollection as well. > > jeff Dave -- John David Anglin [email protected]
