Skip to content
This repository was archived by the owner on Apr 28, 2025. It is now read-only.

Commit eb24e93

Browse files
committed
Add f16 and f128 configuration from compiler-builtins
In preparation of adding routines from these two types, duplicate the `compiler-builtins` configuration here.
1 parent 62d5a69 commit eb24e93

File tree

7 files changed

+109
-0
lines changed

7 files changed

+109
-0
lines changed

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ unstable = []
2222
# Used to prevent using any intrinsics or arch-specific code.
2323
force-soft-floats = []
2424

25+
# Workaround for codegen backends which haven't yet implemented `f16` and
26+
# `f128` support. Disabled any intrinsics which use those types.
27+
no-f16-f128 = []
28+
2529
[workspace]
2630
members = [
2731
"crates/compiler-builtins-smoke-test",

build.rs

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use std::env;
22

33
fn main() {
4+
let cfg = Target::from_env();
5+
46
println!("cargo:rerun-if-changed=build.rs");
57
println!("cargo::rustc-check-cfg=cfg(assert_no_panic)");
68
println!("cargo::rustc-check-cfg=cfg(feature, values(\"unstable\"))");
@@ -14,4 +16,97 @@ fn main() {
1416
println!("cargo:rustc-cfg=assert_no_panic");
1517
}
1618
}
19+
20+
configure_f16_f128(&cfg);
21+
}
22+
23+
#[derive(Debug)]
24+
#[allow(dead_code)]
25+
pub struct Target {
26+
pub triple: String,
27+
pub os: String,
28+
pub arch: String,
29+
pub vendor: String,
30+
pub env: String,
31+
pub pointer_width: u8,
32+
pub little_endian: bool,
33+
pub features: Vec<String>,
34+
}
35+
36+
impl Target {
37+
pub fn from_env() -> Self {
38+
let little_endian = match env::var("CARGO_CFG_TARGET_ENDIAN").unwrap().as_str() {
39+
"little" => true,
40+
"big" => false,
41+
x => panic!("unknown endian {x}"),
42+
};
43+
44+
Self {
45+
triple: env::var("TARGET").unwrap(),
46+
os: env::var("CARGO_CFG_TARGET_OS").unwrap(),
47+
arch: env::var("CARGO_CFG_TARGET_ARCH").unwrap(),
48+
vendor: env::var("CARGO_CFG_TARGET_VENDOR").unwrap(),
49+
env: env::var("CARGO_CFG_TARGET_ENV").unwrap(),
50+
pointer_width: env::var("CARGO_CFG_TARGET_POINTER_WIDTH")
51+
.unwrap()
52+
.parse()
53+
.unwrap(),
54+
little_endian,
55+
features: env::var("CARGO_CFG_TARGET_FEATURE")
56+
.unwrap_or_default()
57+
.split(",")
58+
.map(ToOwned::to_owned)
59+
.collect(),
60+
}
61+
}
62+
63+
#[allow(dead_code)]
64+
pub fn has_feature(&self, feature: &str) -> bool {
65+
self.features.iter().any(|f| f == feature)
66+
}
67+
}
68+
69+
/// Configure whether or not `f16` and `f128` support should be enabled.
70+
pub fn configure_f16_f128(target: &Target) {
71+
// Set whether or not `f16` and `f128` are supported at a basic level by LLVM. This only means
72+
// that the backend will not crash when using these types. This does not mean that the
73+
// backend does the right thing, or that the platform doesn't have ABI bugs.
74+
//
75+
// We do this here rather than in `rust-lang/rust` because configuring via cargo features is
76+
// not straightforward.
77+
//
78+
// Original source of this list:
79+
// <https://github.com/rust-lang/compiler-builtins/pull/652#issuecomment-2266151350>
80+
let (f16_ok, f128_ok) = match target.arch.as_str() {
81+
// `f16` and `f128` both crash <https://github.com/llvm/llvm-project/issues/94434>
82+
"arm64ec" => (false, false),
83+
// `f16` crashes <https://github.com/llvm/llvm-project/issues/50374>
84+
"s390x" => (false, true),
85+
// `f128` crashes <https://github.com/llvm/llvm-project/issues/96432>
86+
"mips64" | "mips64r6" => (true, false),
87+
// `f128` crashes <https://github.com/llvm/llvm-project/issues/101545>
88+
"powerpc64" if &target.os == "aix" => (true, false),
89+
// `f128` crashes <https://github.com/llvm/llvm-project/issues/41838>
90+
"sparc" | "sparcv9" => (true, false),
91+
// `f16` miscompiles <https://github.com/llvm/llvm-project/issues/96438>
92+
"wasm32" | "wasm64" => (false, true),
93+
// Most everything else works as of LLVM 19
94+
_ => (true, true),
95+
};
96+
97+
// If the no-f16-f128 feature is set, disable these types. The `unstable` feature is also
98+
// required.
99+
let disable_both = env::var_os("CARGO_FEATURE_NO_F16_F128").is_some()
100+
|| env::var_os("CARGO_FEATURE_UNSTABLE").is_none();
101+
102+
println!("cargo::rustc-check-cfg=cfg(f16_enabled)");
103+
println!("cargo::rustc-check-cfg=cfg(f128_enabled)");
104+
105+
if f16_ok && !disable_both {
106+
println!("cargo::rustc-cfg=f16_enabled");
107+
}
108+
109+
if f128_ok && !disable_both {
110+
println!("cargo::rustc-cfg=f128_enabled");
111+
}
17112
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
fn main() {
22
println!("cargo::rustc-check-cfg=cfg(assert_no_panic)");
3+
println!("cargo::rustc-check-cfg=cfg(f16_enabled)");
4+
println!("cargo::rustc-check-cfg=cfg(f128_enabled)");
35
}

crates/libm-test/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ publish = false
66

77
[features]
88
default = []
9+
no-f16-f128 = ["libm/no-f16-f128"]
910

1011
# Generate tests which are random inputs and the outputs are calculated with
1112
# musl libc.

crates/libm-test/build.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ mod musl_reference_tests {
6363
let files = fs::read_dir(math_src)
6464
.unwrap()
6565
.map(|f| f.unwrap().path())
66+
.filter(|f| f.is_dir())
6667
.collect::<Vec<_>>();
6768

6869
let mut math = Vec::new();

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#![no_std]
44
#![cfg_attr(feature = "unstable", allow(internal_features))]
55
#![cfg_attr(feature = "unstable", feature(core_intrinsics))]
6+
#![cfg_attr(f128_enabled, feature(f128))]
7+
#![cfg_attr(f16_enabled, feature(f16))]
68
#![allow(clippy::unreadable_literal)]
79
#![allow(clippy::many_single_char_names)]
810
#![allow(clippy::needless_return)]

src/math/traits/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,12 @@ macro_rules! float_impl {
171171
};
172172
}
173173

174+
#[cfg(f16_enabled)]
175+
float_impl!(f16, u16, i16, i8, 16, 10);
174176
float_impl!(f32, u32, i32, i16, 32, 23);
175177
float_impl!(f64, u64, i64, i16, 64, 52);
178+
#[cfg(f128_enabled)]
179+
float_impl!(f128, u128, i128, i16, 128, 112);
176180

177181
/// Minimal integer implementations needed on all integer types, including wide integers.
178182
#[allow(dead_code)]

0 commit comments

Comments
 (0)