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

--- Comment #7 from Robin Dapp <rdapp at gcc dot gnu.org> ---
After a lot of staring and experimenting my theory is that it's not LTO itself
but a very general issue in how we serialize builtin functions in our backend.

The streamed function code is current size of the array/vector
"registered_functions".  What (and when something) gets added to this array
depends on the current -march string.

The failing ncnn for example builds some objects with
-march=rv64gc_xtheadvector, others with -march=rv64gcv or with
-march=rv64gc.

When specifying xtheadvector (which conflicts with the regular vector
extension) we obviously register different and fewer builtins than we would
with "v".
This leads to inconsistent function codes between translation units that
only become obvious in the final linking step.

Always registering all functions is not easily possible as xtheadvector and
vector conflict and are currently mutually exclusive.  I think they don't need
to be mutually exclusive at that level and I believe we could
always register everything and make the distinction later at expand time. 
That's not a small fix, though, and I don't see it as in scope for this
regression.

My current idea is to use a different encoding for the builtin functions:
As the function names are unique we can hash them and use the hash value as
function code.  This works for streaming out as well as in and ensures
consistency.  If functions names stop being unique in the future we can add
discriminators to the hashing function.

With my local proof of concept I managed to build ncnn.  Going to do some more
tests and post a patch later today.

Reply via email to