Skip to content

Commit

Permalink
Configure which platforms get f16 and f128 enabled by default
Browse files Browse the repository at this point in the history
By moving the logic for which platforms get symbols to
`compiler_builtins` rather than rust-lang/rust, we can control where
symbols get enabled without relying on Cargo features. Using Cargo
features turned out to be a problem in [1].

This will help resolve errors like [2].

[1]: rust-lang/rust#128358
[2]: rust-lang/rust#128401
  • Loading branch information
tgross35 committed Aug 2, 2024
1 parent 91f8268 commit 309c50b
Showing 1 changed file with 48 additions and 4 deletions.
52 changes: 48 additions & 4 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ struct Target {

impl Target {
fn from_env() -> Self {
let little_endian = match env::var("CARGO_CFG_TARGET_LITTLE_ENDIAN").unwrap().as_str() {
let little_endian = match env::var("CARGO_CFG_TARGET_ENDIAN").unwrap().as_str() {
"little" => true,
"big" => false,
x => panic!("unknown endian {x}"),
Expand All @@ -31,7 +31,7 @@ impl Target {
.parse()
.unwrap(),
little_endian,
features: env::var("CARGO_CFG_TARGET_FEATURES")
features: env::var("CARGO_CFG_TARGET_FEATURE")
.unwrap()
.split(",")
.map(ToOwned::to_owned)
Expand All @@ -42,11 +42,12 @@ impl Target {

fn main() {
println!("cargo:rerun-if-changed=build.rs");
configure_check_cfg();

let target = Target::from_env();
let cwd = env::current_dir().unwrap();

configure_check_cfg();
configure_f16_f128(&target);

println!("cargo:compiler-rt={}", cwd.join("compiler-rt").display());

// Activate libm's unstable features to make full use of Nightly.
Expand Down Expand Up @@ -259,6 +260,49 @@ fn configure_check_cfg() {
println!("cargo::rustc-check-cfg=cfg(assert_no_panic)");
}

/// Configure whether or not `f16` and `f128` support should be enabled.
fn configure_f16_f128(target: &Target) {
// Set whether or not `f16` and `f128` are supported at a basic level by LLVM. This only means
// that the backend will not crash when using these types. This does not mean that the
// backend does the right thing, or that the platform doesn't have ABI bugs.
//
// We do this so symbols are provided when `long double` is `f128` which prevents linking
// errors on musl (musl makes use of `long double`).
//
// HACK: this logic should be in `rust-lang/rust` so changes only need to be done in one
// place. However, there is no straightforward way to do this, so we do it here.
let (f16_ok, f128_ok) = match target.arch.as_str() {
// No selection failures
"aarch64" | "x86" | "x86_64" | "riscv32" | "riscv64" | "mips" | "mips64" => (true, true),
// `f16` selection failure https://github.com/llvm/llvm-project/issues/93894
"loongarch" | "loongarch64" => (false, true),
// conversion selection failure. `f128` is needed because of `long double`, `f16` is more
// optional. <https://github.com/llvm/llvm-project/issues/92866>.
"powerpc" | "powerpc64" => (false, true),
// No `f16` support <https://github.com/llvm/llvm-project/issues/50374>
"s390x" => (false, true),
_ => (false, false),
};

// If the feature is set, disable these types.
let disable_both = env::var_os("CARGO_FEATURE_NO_F16_F128").is_some();

println!("cargo:warning=f16 {f16_ok} f128 {f128_ok} disable both {disable_both}");

println!("cargo::rustc-check-cfg=cfg(f16_enabled)");
println!("cargo::rustc-check-cfg=cfg(f128_enabled)");

if f16_ok && !disable_both {
println!("cargo::rustc-cfg=f16_enabled");
println!("cargo:warning=f16 enabled");
}

if f128_ok && !disable_both {
println!("cargo::rustc-cfg=f128_enabled");
println!("cargo:warning=f128 enabled");
}
}

#[cfg(feature = "c")]
mod c {
use std::collections::{BTreeMap, HashSet};
Expand Down

0 comments on commit 309c50b

Please sign in to comment.