Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Excess object in staticlib archive eventually causing link error #125619

Closed
XrXr opened this issue May 27, 2024 · 6 comments · Fixed by #133254
Closed

Excess object in staticlib archive eventually causing link error #125619

XrXr opened this issue May 27, 2024 · 6 comments · Fixed by #133254
Labels
A-linkage Area: linking into static, shared libraries and binaries A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-bug Category: This is a bug. C-external-bug Category: issue that is caused by bugs in software beyond our control llvm-fixed-upstream Issue expected to be fixed by the next major LLVM upgrade, or backported fixes O-AArch64 Armv8-A or later processors in AArch64 mode O-musl Target: The musl libc regression-from-stable-to-stable Performance or correctness regression from one stable version to another. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@XrXr
Copy link
Contributor

XrXr commented May 27, 2024

I tried this code:

$ # on aarch64-unknown-linux-gnu
$ rustc --crate-type staticlib -C lto=thin -O /dev/null
$ ar x libnull.a
$ nm *multc3.o

I expected to see this happen:

The nm output shouldn't say U __builtin_copysignq, since that's an x86 intrinsic unavailable on aarch64-unknown-linux-gnu

Instead, this happened:

$ nm *multc3.o
                 U __addtf3
                 U __builtin_copysignq
                 U __floatsitf
                 U __letf2
0000000000000000 T __multc3
                 U __multf3
                 U __subtf3
                 U __unordtf2

Over in Ruby, because we consume the static archive by partial linking it into an .o file first, we've been getting reports of link errors due to this unused object in the archive:

partial linking yjit/target/release/libyjit.a into yjit/target/release/libyjit.o
linking miniruby
/usr/bin/ld: yjit/target/release/libyjit.o: in function `__multc3':
/cargo/registry/src/index.crates.io-6f17d22bba15001f/compiler_builtins-0.1.108/./lib/builtins/multc3.c:33:(.text.__multc3+0x30c): undefined reference to `__builtin_copysignq'
/usr/bin/ld: /cargo/registry/src/index.crates.io-6f17d22bba15001f/compiler_builtins-0.1.108/./lib/builtins/multc3.c:34:(.text.__multc3+0x394): undefined reference to `__builtin_copysignq'
/usr/bin/ld: /cargo/registry/src/index.crates.io-6f17d22bba15001f/compiler_builtins-0.1.108/./lib/builtins/multc3.c:42:(.text.__multc3+0x7f4): undefined reference to `__builtin_copysignq'
/usr/bin/ld: /cargo/registry/src/index.crates.io-6f17d22bba15001f/compiler_builtins-0.1.108/./lib/builtins/multc3.c:43:(.text.__multc3+0x864): undefined reference to `__builtin_copysignq'
/usr/bin/ld: /cargo/registry/src/index.crates.io-6f17d22bba15001f/compiler_builtins-0.1.108/./lib/builtins/multc3.c:47:(.text.__multc3+0x8c4): undefined reference to `__builtin_copysignq'
/usr/bin/ld: yjit/target/release/libyjit.o:/cargo/registry/src/index.crates.io-6f17d22bba15001f/compiler_builtins-0.1.108/./lib/builtins/multc3.c:38: more undefined references to `__builtin_copysignq' follow
collect2: error: ld returned 1 exit status

It looks like this particular intrinsic comes from a file that isn't included for ARM Windows targets:

https://github.com/rust-lang/compiler-builtins/blob/c04eb9e1afb72bdf943f5e5d77b3812f40526602/build.rs#L537-L539

so in fact it should be completely unused. In the README for compiler-builtins, the file is listed under "Unimplemented" and seemingly with no plan for usage:

These builtins involve floating-point types ("f80" and complex numbers) that are not supported by Rust.

I'm wondering if rust could stop including this object in the archive.

Meta

This is regression that started in 1.78.0. With 1.77.0 the nm output is:

$ nm *multc3.o
                 U __addtf3
                 U __floatsitf
                 U __letf2
0000000000000000 T __multc3
                 U __multf3
                 U __subtf3
                 U __unordtf2

and it works fine for ruby.

Issue exists in latest nightly.

rustc --version --verbose:

rustc 1.80.0-nightly (bdbbb6c6a 2024-05-26)
binary: rustc
commit-hash: bdbbb6c6a718d4d196131aa16bafb60e850311d9
commit-date: 2024-05-26
host: aarch64-unknown-linux-gnu
release: 1.80.0-nightly
LLVM version: 18.1.6
@XrXr XrXr added the C-bug Category: This is a bug. label May 27, 2024
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label May 27, 2024
@XrXr
Copy link
Contributor Author

XrXr commented May 27, 2024

@rustbot modify labels: +regression-from-stable-to-stable +A-linkage

@rustbot rustbot added A-linkage Area: linking into static, shared libraries and binaries regression-from-stable-to-stable Performance or correctness regression from one stable version to another. I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels May 27, 2024
XrXr added a commit to XrXr/compiler-builtins that referenced this issue May 27, 2024
This C file doesn't seem to be compiled correctly, as it creates a reference to the x86 specific `__builtin_copysignq` on ARM. This intrinsic is unused and unavailable on Windows because it's for complex numbers Rust doesn't support, so it should be fine to remove.

The inclusion of the file seems to be the cause of some downstream link errors: rust-lang/rust#125619
@XrXr
Copy link
Contributor Author

XrXr commented May 28, 2024

I was able to test rust-lang/compiler-builtins#623 on a local rust build using [patch.crates-io] and confirm that it solves the link error for ruby. So I'm now more confident to offer it as a potential solution. I'm not sure about the policy around bumping the compiler-builtins dependency, though.

Also, the change removes one object file from staticlib outputs, so it gives a small file size benefit even if people are not hitting the link error. 😛

XrXr added a commit to XrXr/compiler-builtins that referenced this issue May 30, 2024
To prevent fail-fast in situations like
rust-lang/rust#125619, where an upstream
source compiles but creates a link error way downstream.
@jieyouxu jieyouxu added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Jun 4, 2024
XrXr added a commit to XrXr/rust that referenced this issue Jun 4, 2024
I'm proposing this GCC upgrade since it addresses bug rust-lang#125619. The regression
in question affects stable release consumers who tend to have no experience
dealing with Rust build tools, so if at all possible, I would like to have it
resolved in the next stable release. I have tried to fix the bug in
`compiler-builtins`, which led to submitting a PR for `compiler-rt` in upstream
LLVM, but it may take a long time before these upstreams address this
regression.

A summary of why upgrading GCC solves the regression follows. `__multc3()` is a
builtin function `compiler-builtins` exposes for specifically aarch64,
non-Windows targets [1]. The object file for it is included in `staticlib`
archives through `libstd`. The implementation for `__multc3()` is from
`multc3.c`, part of LLVM's `compiler-rt`. Upstream `compiler-rt` normally
builds the C file using the Clang that's from the same LLVM version. On the
other hand, `compiler-builtins` builds the C file using GCC, outside of the
usual LLVM build system. The upstream implementation doesn't have
feature detection which works for GCC version older than 10, and ends up
producing an unlinkable object.

Upstream LLVM might be slow to respond to this issue as they might deem
`compiler-builtin` as doing something out of the ordinary from their
perspective. They might reasonably assume everyone to build `compiler-rt` using
LLVM's build system.

I have done the following to test this change:
 - verified that a local build without this patch exhibits the regression.
 - verified that with this patch, the object for `__multc3()` has no reference
   to undefined functions in the symbol table.
 - verified that with this patch, `rustc` is usable to build Ruby with YJIT,
   and that the reported regression is resolved.

[1]: https://github.com/rust-lang/compiler-builtins/blob/c04eb9e1afb72bdf943f5e5d77b3812f40526602/build.rs#L524-L539
XrXr added a commit to XrXr/rust that referenced this issue Jun 4, 2024
I'm proposing this GCC upgrade since it addresses bug rust-lang#125619. The regression
in question affects stable release consumers who tend to have no experience
dealing with Rust build tools, so if at all possible, I would like to have it
resolved in the next stable release. I have tried to fix the bug in
`compiler-builtins`, which led to submitting a PR for `compiler-rt` in upstream
LLVM, but it may take a long time before these upstreams address this
regression.

A summary of why upgrading GCC solves the regression follows. `__multc3()` is a
builtin function `compiler-builtins` exposes for specifically aarch64,
non-Windows targets [1]. The object file for it is included in `staticlib`
archives through `libstd`. The implementation for `__multc3()` is from
`multc3.c`, part of LLVM's `compiler-rt`. Upstream `compiler-rt` normally
builds the C file using the Clang from the same LLVM version. On the
other hand, `compiler-builtins` builds the C file using GCC, outside of the
usual LLVM build system. The upstream implementation doesn't have
feature detection which works for GCC version older than 10, and ends up
producing an unlinkable object.

Upstream LLVM might be slow to respond to this issue as they might deem
`compiler-builtin` as doing something out of the ordinary from their
perspective. They might reasonably assume everyone to build `compiler-rt` using
LLVM's build system.

I have done the following to test this change:
 - verified that a local build without this patch exhibits the regression.
 - verified that with this patch, the object for `__multc3()` has no reference
   to undefined functions in the symbol table.
 - verified that with this patch, `rustc` is usable to build Ruby with YJIT,
   and that the reported regression is resolved.

[1]: https://github.com/rust-lang/compiler-builtins/blob/c04eb9e1afb72bdf943f5e5d77b3812f40526602/build.rs#L524-L539
XrXr added a commit to XrXr/rust that referenced this issue Jun 4, 2024
I'm proposing this GCC upgrade since it addresses bug rust-lang#125619. The regression
in question affects stable release consumers who tend to have no experience
dealing with Rust build tools, so if at all possible, I would like to have it
resolved in the next stable release. I have tried to fix the bug in
`compiler-builtins`, which led to submitting a PR for `compiler-rt` in upstream
LLVM, but it may take a long time before these upstreams address this
regression.

A summary of why upgrading GCC solves the regression follows. `__multc3()` is a
builtin function `compiler-builtins` exposes for specifically aarch64,
non-Windows targets [1]. The object file for it is included in `staticlib`
archives through `libstd`. The implementation for `__multc3()` is from
`multc3.c`, part of LLVM's `compiler-rt`. Upstream `compiler-rt` normally
builds the C file using the Clang from the same LLVM version. On the
other hand, `compiler-builtins` builds the C file using GCC, outside of the
usual LLVM build system. The upstream implementation doesn't have
feature detection which works for GCC version older than 10, and ends up
producing an unlinkable object.

Upstream LLVM might be slow to respond to this issue as they might deem
`compiler-builtin` as doing something out of the ordinary from their
perspective. They might reasonably assume everyone to build `compiler-rt` using
LLVM's build system.

I have done the following to test this change:
 - verified that a local build without this patch exhibits the regression.
 - verified that with this patch, the object for `__multc3()` has no reference
   to undefined functions in the symbol table.
 - verified that with this patch, `rustc` is usable to build Ruby with YJIT,
   and that the reported regression is resolved.

[1]: https://github.com/rust-lang/compiler-builtins/blob/c04eb9e1afb72bdf943f5e5d77b3812f40526602/build.rs#L524-L539
XrXr added a commit to XrXr/rust that referenced this issue Jun 4, 2024
I'm proposing this GCC upgrade since it addresses bug rust-lang#125619. The regression
in question affects stable release consumers who tend to have no experience
dealing with Rust build tools, so if at all possible, I would like to have it
resolved in the next stable release. I have tried to fix the bug in
`compiler-builtins`, which led to submitting a PR for `compiler-rt` in upstream
LLVM, but it may take a long time before these upstreams to address this
regression.

A summary of why upgrading GCC solves the regression follows. `__multc3()` is a
builtin function `compiler-builtins` exposes for specifically aarch64,
non-Windows targets [1]. The object file for it is included in `staticlib`
archives through `libstd`. The implementation for `__multc3()` is from
`multc3.c`, part of LLVM's `compiler-rt`. Upstream `compiler-rt` normally
builds the C file using the Clang from the same LLVM version. On the
other hand, `compiler-builtins` builds the C file using GCC, outside of the
usual LLVM build system. The upstream implementation doesn't have
feature detection which works for GCC version older than 10, and ends up
producing an unlinkable object.

Upstream LLVM might be slow to respond to this issue as they might deem
`compiler-builtin` as doing something out of the ordinary from their
perspective. They might reasonably assume everyone to build `compiler-rt` using
LLVM's build system.

I have done the following to test this change:
 - verified that a local build without this patch exhibits the regression.
 - verified that with this patch, the object for `__multc3()` has no reference
   to undefined functions in the symbol table.
 - verified that with this patch, `rustc` is usable to build Ruby with YJIT,
   and that the reported regression is resolved.

[1]: https://github.com/rust-lang/compiler-builtins/blob/c04eb9e1afb72bdf943f5e5d77b3812f40526602/build.rs#L524-L539
XrXr added a commit to XrXr/rust that referenced this issue Jun 4, 2024
I'm proposing this GCC upgrade since it addresses bug rust-lang#125619. The
regression in question affects stable release consumers who tend to have
no exposure to Rust build tools, so if at all possible, I would like to
have it resolved in the next stable release. I have tried to fix the bug
in `compiler-builtins`, which led to submitting a PR for `compiler-rt`
in upstream LLVM, but it may take a long time before these upstreams to
address this regression.

A summary of why upgrading GCC solves the regression follows.
`__multc3()` is a builtin function `compiler-builtins` exposes for
specifically aarch64, non-Windows targets [1]. The object file for it is
included in `staticlib` archives through `libstd`. The implementation
for `__multc3()` is from `multc3.c`, part of LLVM's `compiler-rt`.
Upstream `compiler-rt` normally builds the C file using the Clang
from the same LLVM version. On the other hand, `compiler-builtins`
builds the C file using GCC, outside of the usual LLVM build system.
The upstream implementation doesn't have feature detection which
works for GCC version older than 10, and ends up producing an
unlinkable object.

Upstream LLVM might be slow to respond to this issue as they might deem
`compiler-builtin` as doing something out of the ordinary from their
perspective. They might reasonably assume everyone to build
`compiler-rt` using LLVM's build system.

I have done the following to test this change:
 - verified that a local build without this patch exhibits the
   regression.
 - verified that with this patch, the object for `__multc3()` has no
   reference to undefined functions in the symbol table.
 - verified that with this patch, `rustc` is usable to build Ruby with
   YJIT, and that the reported regression is resolved.

[1]: https://github.com/rust-lang/compiler-builtins/blob/c04eb9e1afb72bdf943f5e5d77b3812f40526602/build.rs#L524-L539
XrXr added a commit to XrXr/rust that referenced this issue Jun 4, 2024
I'm proposing this GCC upgrade since it addresses bug rust-lang#125619. The
regression in question affects stable release consumers who tend to have
no exposure to Rust build tools, so if at all possible, I would like to
have it resolved in the next stable release. I have tried to fix the bug
in `compiler-builtins`, which led to submitting a PR for `compiler-rt`
in upstream LLVM, but it may take a long time before these upstreams
address this regression.

A summary of why upgrading GCC solves the regression follows.
`__multc3()` is a builtin function `compiler-builtins` exposes for
specifically aarch64, non-Windows targets [1]. The object file for it is
included in `staticlib` archives through `libstd`. The implementation
for `__multc3()` is from `multc3.c`, part of LLVM's `compiler-rt`.
Upstream `compiler-rt` normally builds the C file using the Clang
from the same LLVM version. On the other hand, `compiler-builtins`
builds the C file using GCC, outside of the usual LLVM build system.
The upstream implementation doesn't have feature detection which
works for GCC version older than 10, and ends up producing an
unlinkable object.

Upstream LLVM might be slow to respond to this issue as they might deem
`compiler-builtin` as doing something out of the ordinary from their
perspective. They might reasonably assume everyone to build
`compiler-rt` using LLVM's build system.

I have done the following to test this change:
 - verified that a local build without this patch exhibits the
   regression.
 - verified that with this patch, the object for `__multc3()` has no
   reference to undefined functions in the symbol table.
 - verified that with this patch, `rustc` is usable to build Ruby with
   YJIT, and that the reported regression is resolved.

[1]: https://github.com/rust-lang/compiler-builtins/blob/c04eb9e1afb72bdf943f5e5d77b3812f40526602/build.rs#L524-L539
XrXr added a commit to XrXr/rust that referenced this issue Jun 4, 2024
I'm proposing this GCC upgrade since it addresses bug rust-lang#125619. The
regression in question affects stable release consumers who tend to have
no exposure to Rust build tools, so if at all possible, I would like to
have it resolved in the next stable release. I have tried to fix the bug
in `compiler-builtins`, which led to submitting a PR for `compiler-rt`
in upstream LLVM, but it may take a long time before these upstreams
address this regression.

A summary of why upgrading GCC solves the regression follows.
`__multc3()` is a builtin function `compiler-builtins` exposes for
specifically aarch64, non-Windows targets [1]. The object file for it is
included in `staticlib` archives through `libstd`. The implementation
for `__multc3()` is from `multc3.c`, part of LLVM's `compiler-rt`.
Upstream `compiler-rt` normally builds the C file using the Clang
from the same LLVM version. On the other hand, `compiler-builtins`
builds the C file using GCC, outside of the usual LLVM build system.
The upstream implementation doesn't have feature detection which
works for GCC version older than 10, and ends up producing an
unlinkable object.

Upstream LLVM might be slow to respond to this issue as they might deem
`compiler-builtin` as doing something out of the ordinary from their
perspective. They might reasonably assume everyone builds `compiler-rt`
through LLVM's build system.

I have done the following to test this change:
 - verified that a local build without this patch exhibits the
   regression.
 - verified that with this patch, the object for `__multc3()` has no
   reference to undefined functions in the symbol table.
 - verified that with this patch, `rustc` is usable to build Ruby with
   YJIT, and that the reported regression is resolved.

[1]: https://github.com/rust-lang/compiler-builtins/blob/c04eb9e1afb72bdf943f5e5d77b3812f40526602/build.rs#L524-L539
bors added a commit to rust-lang-ci/rust that referenced this issue Jun 6, 2024
ci: use GCC 13 as cross compiler in `dist-aarch64-linux`

I'm proposing this GCC upgrade since it addresses bug rust-lang#125619. The
regression in question affects stable release consumers who tend to have
no exposure to Rust build tools, so if at all possible, I would like to
have it resolved in the next stable release. I have tried to fix the bug
in `compiler-builtins`, which led to submitting a PR for `compiler-rt`
in upstream LLVM, but it may take a long time before these upstreams
address this regression.

A summary of why upgrading GCC solves the regression follows.
`__multc3()` is a builtin function `compiler-builtins` exposes for
specifically aarch64, non-Windows targets [1]. The object file for it is
included in `staticlib` archives through `libstd`. The implementation
for `__multc3()` is from `multc3.c`, part of LLVM's `compiler-rt`.
Upstream `compiler-rt` normally builds the C file using the Clang
from the same LLVM version. On the other hand, `compiler-builtins`
builds the C file using GCC, outside of the usual LLVM build system.
The upstream implementation doesn't have feature detection which
works for GCC version older than 10, and ends up producing an
unlinkable object.

Upstream LLVM might be slow to respond to this issue as they might deem
`compiler-builtin` as doing something out of the ordinary from their
perspective. They might reasonably assume everyone builds `compiler-rt`
through LLVM's build system.

I have done the following to test this change:
 - verified that a local build without this patch exhibits the
   regression.
 - verified that with this patch, the object for `__multc3()` has no
   reference to undefined functions in the symbol table.
 - verified that with this patch, `rustc` is usable to build Ruby with
   YJIT, and that the reported regression is resolved.

Since `loongarch64-linux-gnu` already uses GCC 13.2.0, I hope we can upgrade without issues.

try-job: dist-aarch64-linux

[1]: https://github.com/rust-lang/compiler-builtins/blob/c04eb9e1afb72bdf943f5e5d77b3812f40526602/build.rs#L524-L539
bors added a commit to rust-lang-ci/rust that referenced this issue Jun 9, 2024
ci: use GCC 13 as cross compiler in `dist-aarch64-linux`

I'm proposing this GCC upgrade since it addresses bug rust-lang#125619. The
regression in question affects stable release consumers who tend to have
no exposure to Rust build tools, so if at all possible, I would like to
have it resolved in the next stable release. I have tried to fix the bug
in `compiler-builtins`, which led to submitting a PR for `compiler-rt`
in upstream LLVM, but it may take a long time before these upstreams
address this regression.

A summary of why upgrading GCC solves the regression follows.
`__multc3()` is a builtin function `compiler-builtins` exposes for
specifically aarch64, non-Windows targets [1]. The object file for it is
included in `staticlib` archives through `libstd`. The implementation
for `__multc3()` is from `multc3.c`, part of LLVM's `compiler-rt`.
Upstream `compiler-rt` normally builds the C file using the Clang
from the same LLVM version. On the other hand, `compiler-builtins`
builds the C file using GCC, outside of the usual LLVM build system.
The upstream implementation doesn't have feature detection which
works for GCC version older than 10, and ends up producing an
unlinkable object.

Upstream LLVM might be slow to respond to this issue as they might deem
`compiler-builtin` as doing something out of the ordinary from their
perspective. They might reasonably assume everyone builds `compiler-rt`
through LLVM's build system.

I have done the following to test this change:
 - verified that a local build without this patch exhibits the
   regression.
 - verified that with this patch, the object for `__multc3()` has no
   reference to undefined functions in the symbol table.
 - verified that with this patch, `rustc` is usable to build Ruby with
   YJIT, and that the reported regression is resolved.

Since `loongarch64-linux-gnu` already uses GCC 13.2.0, I hope we can upgrade without issues.

try-job: dist-aarch64-linux

[1]: https://github.com/rust-lang/compiler-builtins/blob/c04eb9e1afb72bdf943f5e5d77b3812f40526602/build.rs#L524-L539
RalfJung pushed a commit to RalfJung/miri that referenced this issue Jun 11, 2024
ci: use GCC 13 as cross compiler in `dist-aarch64-linux`

I'm proposing this GCC upgrade since it addresses bug rust-lang/rust#125619. The
regression in question affects stable release consumers who tend to have
no exposure to Rust build tools, so if at all possible, I would like to
have it resolved in the next stable release. I have tried to fix the bug
in `compiler-builtins`, which led to submitting a PR for `compiler-rt`
in upstream LLVM, but it may take a long time before these upstreams
address this regression.

A summary of why upgrading GCC solves the regression follows.
`__multc3()` is a builtin function `compiler-builtins` exposes for
specifically aarch64, non-Windows targets [1]. The object file for it is
included in `staticlib` archives through `libstd`. The implementation
for `__multc3()` is from `multc3.c`, part of LLVM's `compiler-rt`.
Upstream `compiler-rt` normally builds the C file using the Clang
from the same LLVM version. On the other hand, `compiler-builtins`
builds the C file using GCC, outside of the usual LLVM build system.
The upstream implementation doesn't have feature detection which
works for GCC version older than 10, and ends up producing an
unlinkable object.

Upstream LLVM might be slow to respond to this issue as they might deem
`compiler-builtin` as doing something out of the ordinary from their
perspective. They might reasonably assume everyone builds `compiler-rt`
through LLVM's build system.

I have done the following to test this change:
 - verified that a local build without this patch exhibits the
   regression.
 - verified that with this patch, the object for `__multc3()` has no
   reference to undefined functions in the symbol table.
 - verified that with this patch, `rustc` is usable to build Ruby with
   YJIT, and that the reported regression is resolved.

Since `loongarch64-linux-gnu` already uses GCC 13.2.0, I hope we can upgrade without issues.

try-job: dist-aarch64-linux

[1]: https://github.com/rust-lang/compiler-builtins/blob/c04eb9e1afb72bdf943f5e5d77b3812f40526602/build.rs#L524-L539
lcnr pushed a commit to lcnr/rust that referenced this issue Jun 12, 2024
I'm proposing this GCC upgrade since it addresses bug rust-lang#125619. The
regression in question affects stable release consumers who tend to have
no exposure to Rust build tools, so if at all possible, I would like to
have it resolved in the next stable release. I have tried to fix the bug
in `compiler-builtins`, which led to submitting a PR for `compiler-rt`
in upstream LLVM, but it may take a long time before these upstreams
address this regression.

A summary of why upgrading GCC solves the regression follows.
`__multc3()` is a builtin function `compiler-builtins` exposes for
specifically aarch64, non-Windows targets [1]. The object file for it is
included in `staticlib` archives through `libstd`. The implementation
for `__multc3()` is from `multc3.c`, part of LLVM's `compiler-rt`.
Upstream `compiler-rt` normally builds the C file using the Clang
from the same LLVM version. On the other hand, `compiler-builtins`
builds the C file using GCC, outside of the usual LLVM build system.
The upstream implementation doesn't have feature detection which
works for GCC version older than 10, and ends up producing an
unlinkable object.

Upstream LLVM might be slow to respond to this issue as they might deem
`compiler-builtin` as doing something out of the ordinary from their
perspective. They might reasonably assume everyone builds `compiler-rt`
through LLVM's build system.

I have done the following to test this change:
 - verified that a local build without this patch exhibits the
   regression.
 - verified that with this patch, the object for `__multc3()` has no
   reference to undefined functions in the symbol table.
 - verified that with this patch, `rustc` is usable to build Ruby with
   YJIT, and that the reported regression is resolved.

[1]: https://github.com/rust-lang/compiler-builtins/blob/c04eb9e1afb72bdf943f5e5d77b3812f40526602/build.rs#L524-L539
flip1995 pushed a commit to flip1995/rust-clippy that referenced this issue Jun 28, 2024
ci: use GCC 13 as cross compiler in `dist-aarch64-linux`

I'm proposing this GCC upgrade since it addresses bug rust-lang/rust#125619. The
regression in question affects stable release consumers who tend to have
no exposure to Rust build tools, so if at all possible, I would like to
have it resolved in the next stable release. I have tried to fix the bug
in `compiler-builtins`, which led to submitting a PR for `compiler-rt`
in upstream LLVM, but it may take a long time before these upstreams
address this regression.

A summary of why upgrading GCC solves the regression follows.
`__multc3()` is a builtin function `compiler-builtins` exposes for
specifically aarch64, non-Windows targets [1]. The object file for it is
included in `staticlib` archives through `libstd`. The implementation
for `__multc3()` is from `multc3.c`, part of LLVM's `compiler-rt`.
Upstream `compiler-rt` normally builds the C file using the Clang
from the same LLVM version. On the other hand, `compiler-builtins`
builds the C file using GCC, outside of the usual LLVM build system.
The upstream implementation doesn't have feature detection which
works for GCC version older than 10, and ends up producing an
unlinkable object.

Upstream LLVM might be slow to respond to this issue as they might deem
`compiler-builtin` as doing something out of the ordinary from their
perspective. They might reasonably assume everyone builds `compiler-rt`
through LLVM's build system.

I have done the following to test this change:
 - verified that a local build without this patch exhibits the
   regression.
 - verified that with this patch, the object for `__multc3()` has no
   reference to undefined functions in the symbol table.
 - verified that with this patch, `rustc` is usable to build Ruby with
   YJIT, and that the reported regression is resolved.

Since `loongarch64-linux-gnu` already uses GCC 13.2.0, I hope we can upgrade without issues.

try-job: dist-aarch64-linux

[1]: https://github.com/rust-lang/compiler-builtins/blob/c04eb9e1afb72bdf943f5e5d77b3812f40526602/build.rs#L524-L539
statham-arm pushed a commit to llvm/llvm-project that referenced this issue Aug 16, 2024
Previously, building `multc3.c` on A64 with GCC 7 or up but 9 and lower
will attempt to reference `__builtin_copysignq`, an [x86-specific
intrinsic][1]:

```
$ gcc -c multc3.c
In file included from fp_lib.h:24,
                 from multc3.c:14:
multc3.c: In function '__multc3':
int_math.h:71:32: warning: implicit declaration of function '__builtin_copysignq'; did you mean '__builtin_copysign'? [-Wimplicit-function-declaration]
 #define crt_copysignf128(x, y) __builtin_copysignq((x), (y))
                                ^~~~~~~~~~~~~~~~~~~
```

This is because `__has_builtin` is from GCC 10, and defined to 0 at the
top of int_math.h for affected GCC versions, so the fallback definition
is used. But `__builtin_copysignq` is unavailable on A64.

Use version detection to find `__builtin_copysignf128` instead. It's
available since GCC 7 and [available][2] on both x86 and A64, given this
macro is only used when `CRT_HAS_IEEE_TF`.

---

I realize this is fixing a problem for an out-of-tree build
configuration, but help would be greatly appreciated. Rust
[builds](https://github.com/rust-lang/compiler-builtins) `multc3.c` with
GCC 8 and this mis-selection is causing [build
issues](rust-lang/rust#125619) way downstream.

ref: d2ce3e9

[1]: https://gcc.gnu.org/onlinedocs/gcc/x86-Built-in-Functions.html
[2]: https://gcc.gnu.org/gcc-7/changes.html
XrXr added a commit to XrXr/compiler-builtins that referenced this issue Oct 2, 2024
To prevent fail-fast in situations like
rust-lang/rust#125619, where an upstream
source compiles but creates a link error way downstream.
tgross35 pushed a commit to XrXr/compiler-builtins that referenced this issue Oct 3, 2024
To prevent fail-fast in situations like
rust-lang/rust#125619, where an upstream
source compiles but creates a link error way downstream.
tezoslibrarian pushed a commit to tezos/tezos-mirror that referenced this issue Oct 18, 2024
Rust 1.78 and above are subjected to a [bug] leading Arm64 foreign archives to
contain x86 builtins. It looks like we are now triggering this very bug, which
prevents building on Arm64 hardware.

The simplest way to move forward is to downgrade our recommended version of
Rust to 1.77, and wait for a release containing the [fix] to be merged.

[bug]: rust-lang/rust#125619
[fix]: rust-lang/rust#131221

Co-authored-by: Ole Krüger <[email protected]>
llvmbot pushed a commit to llvmbot/llvm-project that referenced this issue Nov 5, 2024
Previously, building `multc3.c` on A64 with GCC 7 or up but 9 and lower
will attempt to reference `__builtin_copysignq`, an [x86-specific
intrinsic][1]:

```
$ gcc -c multc3.c
In file included from fp_lib.h:24,
                 from multc3.c:14:
multc3.c: In function '__multc3':
int_math.h:71:32: warning: implicit declaration of function '__builtin_copysignq'; did you mean '__builtin_copysign'? [-Wimplicit-function-declaration]
 #define crt_copysignf128(x, y) __builtin_copysignq((x), (y))
                                ^~~~~~~~~~~~~~~~~~~
```

This is because `__has_builtin` is from GCC 10, and defined to 0 at the
top of int_math.h for affected GCC versions, so the fallback definition
is used. But `__builtin_copysignq` is unavailable on A64.

Use version detection to find `__builtin_copysignf128` instead. It's
available since GCC 7 and [available][2] on both x86 and A64, given this
macro is only used when `CRT_HAS_IEEE_TF`.

---

I realize this is fixing a problem for an out-of-tree build
configuration, but help would be greatly appreciated. Rust
[builds](https://github.com/rust-lang/compiler-builtins) `multc3.c` with
GCC 8 and this mis-selection is causing [build
issues](rust-lang/rust#125619) way downstream.

ref: d2ce3e9

[1]: https://gcc.gnu.org/onlinedocs/gcc/x86-Built-in-Functions.html
[2]: https://gcc.gnu.org/gcc-7/changes.html

(cherry picked from commit 8aa9d62)
@jieyouxu
Copy link
Member

jieyouxu commented Nov 8, 2024

Triage: @XrXr is this issue still a problem?

@XrXr
Copy link
Contributor Author

XrXr commented Nov 8, 2024

Yes. Specifically it still happens on aarch64-unknown-linux-musl. LLVM fix is going through the backport process: llvm/llvm-project#115006

@jieyouxu jieyouxu added A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. O-musl Target: The musl libc O-AArch64 Armv8-A or later processors in AArch64 mode C-external-bug Category: issue that is caused by bugs in software beyond our control labels Nov 8, 2024
tru pushed a commit to llvmbot/llvm-project that referenced this issue Nov 12, 2024
Previously, building `multc3.c` on A64 with GCC 7 or up but 9 and lower
will attempt to reference `__builtin_copysignq`, an [x86-specific
intrinsic][1]:

```
$ gcc -c multc3.c
In file included from fp_lib.h:24,
                 from multc3.c:14:
multc3.c: In function '__multc3':
int_math.h:71:32: warning: implicit declaration of function '__builtin_copysignq'; did you mean '__builtin_copysign'? [-Wimplicit-function-declaration]
 #define crt_copysignf128(x, y) __builtin_copysignq((x), (y))
                                ^~~~~~~~~~~~~~~~~~~
```

This is because `__has_builtin` is from GCC 10, and defined to 0 at the
top of int_math.h for affected GCC versions, so the fallback definition
is used. But `__builtin_copysignq` is unavailable on A64.

Use version detection to find `__builtin_copysignf128` instead. It's
available since GCC 7 and [available][2] on both x86 and A64, given this
macro is only used when `CRT_HAS_IEEE_TF`.

---

I realize this is fixing a problem for an out-of-tree build
configuration, but help would be greatly appreciated. Rust
[builds](https://github.com/rust-lang/compiler-builtins) `multc3.c` with
GCC 8 and this mis-selection is causing [build
issues](rust-lang/rust#125619) way downstream.

ref: d2ce3e9

[1]: https://gcc.gnu.org/onlinedocs/gcc/x86-Built-in-Functions.html
[2]: https://gcc.gnu.org/gcc-7/changes.html

(cherry picked from commit 8aa9d62)
@apiraino apiraino removed the I-prioritize Issue: Indicates that prioritization has been requested for this issue. label Nov 12, 2024
tru pushed a commit to llvmbot/llvm-project that referenced this issue Nov 15, 2024
Previously, building `multc3.c` on A64 with GCC 7 or up but 9 and lower
will attempt to reference `__builtin_copysignq`, an [x86-specific
intrinsic][1]:

```
$ gcc -c multc3.c
In file included from fp_lib.h:24,
                 from multc3.c:14:
multc3.c: In function '__multc3':
int_math.h:71:32: warning: implicit declaration of function '__builtin_copysignq'; did you mean '__builtin_copysign'? [-Wimplicit-function-declaration]
 #define crt_copysignf128(x, y) __builtin_copysignq((x), (y))
                                ^~~~~~~~~~~~~~~~~~~
```

This is because `__has_builtin` is from GCC 10, and defined to 0 at the
top of int_math.h for affected GCC versions, so the fallback definition
is used. But `__builtin_copysignq` is unavailable on A64.

Use version detection to find `__builtin_copysignf128` instead. It's
available since GCC 7 and [available][2] on both x86 and A64, given this
macro is only used when `CRT_HAS_IEEE_TF`.

---

I realize this is fixing a problem for an out-of-tree build
configuration, but help would be greatly appreciated. Rust
[builds](https://github.com/rust-lang/compiler-builtins) `multc3.c` with
GCC 8 and this mis-selection is causing [build
issues](rust-lang/rust#125619) way downstream.

ref: d2ce3e9

[1]: https://gcc.gnu.org/onlinedocs/gcc/x86-Built-in-Functions.html
[2]: https://gcc.gnu.org/gcc-7/changes.html

(cherry picked from commit 8aa9d62)
tru pushed a commit to llvmbot/llvm-project that referenced this issue Nov 15, 2024
Previously, building `multc3.c` on A64 with GCC 7 or up but 9 and lower
will attempt to reference `__builtin_copysignq`, an [x86-specific
intrinsic][1]:

```
$ gcc -c multc3.c
In file included from fp_lib.h:24,
                 from multc3.c:14:
multc3.c: In function '__multc3':
int_math.h:71:32: warning: implicit declaration of function '__builtin_copysignq'; did you mean '__builtin_copysign'? [-Wimplicit-function-declaration]
 #define crt_copysignf128(x, y) __builtin_copysignq((x), (y))
                                ^~~~~~~~~~~~~~~~~~~
```

This is because `__has_builtin` is from GCC 10, and defined to 0 at the
top of int_math.h for affected GCC versions, so the fallback definition
is used. But `__builtin_copysignq` is unavailable on A64.

Use version detection to find `__builtin_copysignf128` instead. It's
available since GCC 7 and [available][2] on both x86 and A64, given this
macro is only used when `CRT_HAS_IEEE_TF`.

---

I realize this is fixing a problem for an out-of-tree build
configuration, but help would be greatly appreciated. Rust
[builds](https://github.com/rust-lang/compiler-builtins) `multc3.c` with
GCC 8 and this mis-selection is causing [build
issues](rust-lang/rust#125619) way downstream.

ref: d2ce3e9

[1]: https://gcc.gnu.org/onlinedocs/gcc/x86-Built-in-Functions.html
[2]: https://gcc.gnu.org/gcc-7/changes.html

(cherry picked from commit 8aa9d62)
@DianQK DianQK added the llvm-fixed-upstream Issue expected to be fixed by the next major LLVM upgrade, or backported fixes label Nov 20, 2024
nikic pushed a commit to rust-lang/llvm-project that referenced this issue Nov 20, 2024
Previously, building `multc3.c` on A64 with GCC 7 or up but 9 and lower
will attempt to reference `__builtin_copysignq`, an [x86-specific
intrinsic][1]:

```
$ gcc -c multc3.c
In file included from fp_lib.h:24,
                 from multc3.c:14:
multc3.c: In function '__multc3':
int_math.h:71:32: warning: implicit declaration of function '__builtin_copysignq'; did you mean '__builtin_copysign'? [-Wimplicit-function-declaration]
 #define crt_copysignf128(x, y) __builtin_copysignq((x), (y))
                                ^~~~~~~~~~~~~~~~~~~
```

This is because `__has_builtin` is from GCC 10, and defined to 0 at the
top of int_math.h for affected GCC versions, so the fallback definition
is used. But `__builtin_copysignq` is unavailable on A64.

Use version detection to find `__builtin_copysignf128` instead. It's
available since GCC 7 and [available][2] on both x86 and A64, given this
macro is only used when `CRT_HAS_IEEE_TF`.

---

I realize this is fixing a problem for an out-of-tree build
configuration, but help would be greatly appreciated. Rust
[builds](https://github.com/rust-lang/compiler-builtins) `multc3.c` with
GCC 8 and this mis-selection is causing [build
issues](rust-lang/rust#125619) way downstream.

ref: d2ce3e9

[1]: https://gcc.gnu.org/onlinedocs/gcc/x86-Built-in-Functions.html
[2]: https://gcc.gnu.org/gcc-7/changes.html

(cherry picked from commit 8aa9d62)
@bors bors closed this as completed in 318f96a Nov 21, 2024
github-actions bot pushed a commit to rust-lang/miri that referenced this issue Nov 22, 2024
@zaq7434
Copy link

zaq7434 commented Nov 30, 2024

How to avoid this problem with rust 1.79 ?Must I upgrade the rust version or llvm?
aarch64-unknown-linux-gnu

Yes. Specifically it still happens on aarch64-unknown-linux-musl. LLVM fix is going through the backport process: llvm/llvm-project#115006

@bjorn3
Copy link
Member

bjorn3 commented Nov 30, 2024

Looks like the fix will be in Rust 1.84.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-linkage Area: linking into static, shared libraries and binaries A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-bug Category: This is a bug. C-external-bug Category: issue that is caused by bugs in software beyond our control llvm-fixed-upstream Issue expected to be fixed by the next major LLVM upgrade, or backported fixes O-AArch64 Armv8-A or later processors in AArch64 mode O-musl Target: The musl libc regression-from-stable-to-stable Performance or correctness regression from one stable version to another. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants