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

Commit 400e196

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 c447e5f commit 400e196

File tree

9 files changed

+208
-83
lines changed

9 files changed

+208
-83
lines changed

Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,17 @@ arch = []
2121

2222
# This tells the compiler to assume that a Nightly toolchain is being used and
2323
# that it should activate any useful Nightly things accordingly.
24-
unstable = ["unstable-intrinsics"]
24+
unstable = ["unstable-intrinsics", "unstable-float"]
2525

2626
# Enable calls to functions in `core::intrinsics`
2727
unstable-intrinsics = []
2828

2929
# Make some internal things public for testing.
3030
unstable-test-support = []
3131

32+
# Enable the nightly-only `f16` and `f128`.
33+
unstable-float = []
34+
3235
# Used to prevent using any intrinsics or arch-specific code.
3336
#
3437
# HACK: this is a negative feature which is generally a bad idea in Cargo, but

build.rs

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
use std::env;
22

3+
mod configure;
4+
35
fn main() {
6+
let cfg = configure::Config::from_env();
7+
48
println!("cargo:rerun-if-changed=build.rs");
59
println!("cargo:rustc-check-cfg=cfg(assert_no_panic)");
610

@@ -14,29 +18,5 @@ fn main() {
1418
}
1519
}
1620

17-
configure_intrinsics();
18-
configure_arch();
19-
}
20-
21-
/// Simplify the feature logic for enabling intrinsics so code only needs to use
22-
/// `cfg(intrinsics_enabled)`.
23-
fn configure_intrinsics() {
24-
println!("cargo:rustc-check-cfg=cfg(intrinsics_enabled)");
25-
26-
// Disabled by default; `unstable-intrinsics` enables again; `force-soft-floats` overrides
27-
// to disable.
28-
if cfg!(feature = "unstable-intrinsics") && !cfg!(feature = "force-soft-floats") {
29-
println!("cargo:rustc-cfg=intrinsics_enabled");
30-
}
31-
}
32-
33-
/// Simplify the feature logic for enabling arch-specific features so code only needs to use
34-
/// `cfg(arch_enabled)`.
35-
fn configure_arch() {
36-
println!("cargo:rustc-check-cfg=cfg(arch_enabled)");
37-
38-
// Enabled by default via the "arch" feature, `force-soft-floats` overrides to disable.
39-
if cfg!(feature = "arch") && !cfg!(feature = "force-soft-floats") {
40-
println!("cargo:rustc-cfg=arch_enabled");
41-
}
21+
configure::emit_libm_config(&cfg);
4222
}

configure.rs

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
// Configuration shared with both libm and libm-test
2+
3+
use std::env;
4+
use std::path::PathBuf;
5+
6+
#[allow(dead_code)]
7+
pub struct Config {
8+
pub manifest_dir: PathBuf,
9+
pub out_dir: PathBuf,
10+
pub opt_level: u8,
11+
pub target_arch: String,
12+
pub target_env: String,
13+
pub target_family: Option<String>,
14+
pub target_os: String,
15+
pub target_string: String,
16+
pub target_vendor: String,
17+
pub target_features: Vec<String>,
18+
}
19+
20+
impl Config {
21+
pub fn from_env() -> Self {
22+
let target_features = env::var("CARGO_CFG_TARGET_FEATURE")
23+
.map(|feats| feats.split(',').map(ToOwned::to_owned).collect())
24+
.unwrap_or_default();
25+
26+
Self {
27+
manifest_dir: PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()),
28+
out_dir: PathBuf::from(env::var("OUT_DIR").unwrap()),
29+
opt_level: env::var("OPT_LEVEL").unwrap().parse().unwrap(),
30+
target_arch: env::var("CARGO_CFG_TARGET_ARCH").unwrap(),
31+
target_env: env::var("CARGO_CFG_TARGET_ENV").unwrap(),
32+
target_family: env::var("CARGO_CFG_TARGET_FAMILY").ok(),
33+
target_os: env::var("CARGO_CFG_TARGET_OS").unwrap(),
34+
target_string: env::var("TARGET").unwrap(),
35+
target_vendor: env::var("CARGO_CFG_TARGET_VENDOR").unwrap(),
36+
target_features,
37+
}
38+
}
39+
}
40+
41+
/// Libm gets most config options made available.
42+
#[allow(dead_code)]
43+
pub fn emit_libm_config(cfg: &Config) {
44+
emit_intrinsics_cfg();
45+
emit_arch_cfg();
46+
emit_optimization_cfg(cfg);
47+
emit_cfg_shorthands(cfg);
48+
emit_f16_f128_cfg(cfg);
49+
}
50+
51+
/// Tests don't need most feature-related config.
52+
#[allow(dead_code)]
53+
pub fn emit_test_config(cfg: &Config) {
54+
emit_optimization_cfg(cfg);
55+
emit_cfg_shorthands(cfg);
56+
emit_f16_f128_cfg(cfg);
57+
}
58+
59+
/// Simplify the feature logic for enabling intrinsics so code only needs to use
60+
/// `cfg(intrinsics_enabled)`.
61+
fn emit_intrinsics_cfg() {
62+
println!("cargo:rustc-check-cfg=cfg(intrinsics_enabled)");
63+
64+
// Disabled by default; `unstable-intrinsics` enables again; `force-soft-floats` overrides
65+
// to disable.
66+
if cfg!(feature = "unstable-intrinsics") && !cfg!(feature = "force-soft-floats") {
67+
println!("cargo:rustc-cfg=intrinsics_enabled");
68+
}
69+
}
70+
71+
/// Simplify the feature logic for enabling arch-specific features so code only needs to use
72+
/// `cfg(arch_enabled)`.
73+
fn emit_arch_cfg() {
74+
println!("cargo:rustc-check-cfg=cfg(arch_enabled)");
75+
76+
// Enabled by default via the "arch" feature, `force-soft-floats` overrides to disable.
77+
if cfg!(feature = "arch") && !cfg!(feature = "force-soft-floats") {
78+
println!("cargo:rustc-cfg=arch_enabled");
79+
}
80+
}
81+
82+
/// Some tests are extremely slow. Emit a config option based on optimization level.
83+
fn emit_optimization_cfg(cfg: &Config) {
84+
println!("cargo:rustc-check-cfg=cfg(optimizations_enabled)");
85+
86+
if cfg.opt_level >= 2 {
87+
println!("cargo:rustc-cfg=optimizations_enabled");
88+
}
89+
}
90+
91+
/// Provide an alias for common longer config combinations.
92+
fn emit_cfg_shorthands(cfg: &Config) {
93+
println!("cargo:rustc-check-cfg=cfg(x86_no_sse)");
94+
if cfg.target_arch == "x86" && !cfg.target_features.iter().any(|f| f == "sse") {
95+
// Shorthand to detect i586 targets
96+
println!("cargo:rustc-cfg=x86_no_sse");
97+
}
98+
}
99+
100+
/// Configure whether or not `f16` and `f128` support should be enabled.
101+
fn emit_f16_f128_cfg(cfg: &Config) {
102+
println!("cargo:rustc-check-cfg=cfg(f16_enabled)");
103+
println!("cargo:rustc-check-cfg=cfg(f128_enabled)");
104+
105+
// `unstable-float` enables these features.
106+
if !cfg!(feature = "unstable-float") {
107+
return;
108+
}
109+
110+
// Set whether or not `f16` and `f128` are supported at a basic level by LLVM. This only means
111+
// that the backend will not crash when using these types and generates code that can be called
112+
// without crashing (no infinite recursion). This does not mean that the platform doesn't have
113+
// ABI or other bugs.
114+
//
115+
// We do this here rather than in `rust-lang/rust` because configuring via cargo features is
116+
// not straightforward.
117+
//
118+
// Original source of this list:
119+
// <https://github.com/rust-lang/compiler-builtins/pull/652#issuecomment-2266151350>
120+
let f16_enabled = match cfg.target_arch.as_str() {
121+
// Unsupported <https://github.com/llvm/llvm-project/issues/94434>
122+
"arm64ec" => false,
123+
// Selection failure <https://github.com/llvm/llvm-project/issues/50374>
124+
"s390x" => false,
125+
// Infinite recursion <https://github.com/llvm/llvm-project/issues/97981>
126+
// FIXME(llvm): loongarch fixed by <https://github.com/llvm/llvm-project/pull/107791>
127+
"csky" => false,
128+
"hexagon" => false,
129+
"loongarch64" => false,
130+
"mips" | "mips64" | "mips32r6" | "mips64r6" => false,
131+
"powerpc" | "powerpc64" => false,
132+
"sparc" | "sparc64" => false,
133+
"wasm32" | "wasm64" => false,
134+
// Most everything else works as of LLVM 19
135+
_ => true,
136+
};
137+
138+
let f128_enabled = match cfg.target_arch.as_str() {
139+
// Unsupported (libcall is not supported) <https://github.com/llvm/llvm-project/issues/121122>
140+
"amdgpu" => false,
141+
// Unsupported <https://github.com/llvm/llvm-project/issues/94434>
142+
"arm64ec" => false,
143+
// Selection failure <https://github.com/llvm/llvm-project/issues/96432>
144+
"mips64" | "mips64r6" => false,
145+
// Selection failure <https://github.com/llvm/llvm-project/issues/95471>
146+
"nvptx64" => false,
147+
// Selection failure <https://github.com/llvm/llvm-project/issues/101545>
148+
"powerpc64" if &cfg.target_os == "aix" => false,
149+
// Selection failure <https://github.com/llvm/llvm-project/issues/41838>
150+
"sparc" => false,
151+
// Most everything else works as of LLVM 19
152+
_ => true,
153+
};
154+
155+
// If the feature is set, disable these types.
156+
let disable_both = env::var_os("CARGO_FEATURE_NO_F16_F128").is_some();
157+
158+
println!("cargo:rustc-check-cfg=cfg(f16_enabled)");
159+
println!("cargo:rustc-check-cfg=cfg(f128_enabled)");
160+
161+
if f16_enabled && !disable_both {
162+
println!("cargo:rustc-cfg=f16_enabled");
163+
}
164+
165+
if f128_enabled && !disable_both {
166+
println!("cargo:rustc-cfg=f128_enabled");
167+
}
168+
}

crates/compiler-builtins-smoke-test/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,7 @@ force-soft-floats = []
2121
unexpected_cfgs = { level = "warn", check-cfg = [
2222
"cfg(arch_enabled)",
2323
"cfg(assert_no_panic)",
24+
"cfg(f128_enabled)",
25+
"cfg(f16_enabled)",
2426
"cfg(intrinsics_enabled)",
2527
] }

crates/libm-macros/Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,10 @@ heck = "0.5.0"
1212
proc-macro2 = "1.0.88"
1313
quote = "1.0.37"
1414
syn = { version = "2.0.79", features = ["full", "extra-traits", "visit-mut"] }
15+
16+
[lints.rust]
17+
# Values used during testing
18+
unexpected_cfgs = { level = "warn", check-cfg = [
19+
'cfg(f16_enabled)',
20+
'cfg(f128_enabled)',
21+
] }

crates/libm-test/Cargo.toml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ edition = "2021"
55
publish = false
66

77
[features]
8-
default = []
8+
default = ["unstable-float"]
9+
10+
# Propagated from libm because this affects which functions we test.
11+
unstable-float = ["libm/unstable-float"]
912

1013
# Generate tests which are random inputs and the outputs are calculated with
1114
# musl libc.
@@ -44,3 +47,9 @@ criterion = { version = "0.5.1", default-features = false, features = ["cargo_be
4447
[[bench]]
4548
name = "random"
4649
harness = false
50+
51+
[lints.rust]
52+
# Values from the chared config.rs used by `libm` but not the test crate
53+
unexpected_cfgs = { level = "warn", check-cfg = [
54+
'cfg(feature, values("arch", "force-soft-floats", "unstable-intrinsics"))',
55+
] }

crates/libm-test/build.rs

Lines changed: 6 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,16 @@
11
use std::fmt::Write;
2-
use std::path::PathBuf;
3-
use std::{env, fs};
2+
use std::fs;
3+
4+
#[path = "../../configure.rs"]
5+
mod configure;
6+
use configure::Config;
47

58
fn main() {
69
let cfg = Config::from_env();
710

8-
emit_optimization_cfg(&cfg);
9-
emit_cfg_shorthands(&cfg);
1011
list_all_tests(&cfg);
11-
}
12-
13-
#[allow(dead_code)]
14-
struct Config {
15-
manifest_dir: PathBuf,
16-
out_dir: PathBuf,
17-
opt_level: u8,
18-
target_arch: String,
19-
target_env: String,
20-
target_family: Option<String>,
21-
target_os: String,
22-
target_string: String,
23-
target_vendor: String,
24-
target_features: Vec<String>,
25-
}
26-
27-
impl Config {
28-
fn from_env() -> Self {
29-
let target_features = env::var("CARGO_CFG_TARGET_FEATURE")
30-
.map(|feats| feats.split(',').map(ToOwned::to_owned).collect())
31-
.unwrap_or_default();
32-
33-
Self {
34-
manifest_dir: PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()),
35-
out_dir: PathBuf::from(env::var("OUT_DIR").unwrap()),
36-
opt_level: env::var("OPT_LEVEL").unwrap().parse().unwrap(),
37-
target_arch: env::var("CARGO_CFG_TARGET_ARCH").unwrap(),
38-
target_env: env::var("CARGO_CFG_TARGET_ENV").unwrap(),
39-
target_family: env::var("CARGO_CFG_TARGET_FAMILY").ok(),
40-
target_os: env::var("CARGO_CFG_TARGET_OS").unwrap(),
41-
target_string: env::var("TARGET").unwrap(),
42-
target_vendor: env::var("CARGO_CFG_TARGET_VENDOR").unwrap(),
43-
target_features,
44-
}
45-
}
46-
}
4712

48-
/// Some tests are extremely slow. Emit a config option based on optimization level.
49-
fn emit_optimization_cfg(cfg: &Config) {
50-
println!("cargo::rustc-check-cfg=cfg(optimizations_enabled)");
51-
52-
if cfg.opt_level >= 2 {
53-
println!("cargo::rustc-cfg=optimizations_enabled");
54-
}
55-
}
56-
57-
/// Provide an alias for common longer config combinations.
58-
fn emit_cfg_shorthands(cfg: &Config) {
59-
println!("cargo::rustc-check-cfg=cfg(x86_no_sse)");
60-
if cfg.target_arch == "x86" && !cfg.target_features.iter().any(|f| f == "sse") {
61-
// Shorthand to detect i586 targets
62-
println!("cargo::rustc-cfg=x86_no_sse");
63-
}
13+
configure::emit_test_config(&cfg);
6414
}
6515

6616
/// Create a list of all source files in an array. This can be used for making sure that

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
#![no_std]
33
#![cfg_attr(intrinsics_enabled, allow(internal_features))]
44
#![cfg_attr(intrinsics_enabled, feature(core_intrinsics))]
5+
#![cfg_attr(f128_enabled, feature(f128))]
6+
#![cfg_attr(f16_enabled, feature(f16))]
57
#![allow(clippy::assign_op_pattern)]
68
#![allow(clippy::deprecated_cfg_attr)]
79
#![allow(clippy::eq_op)]

src/math/support/float_traits.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,5 +219,9 @@ macro_rules! float_impl {
219219
};
220220
}
221221

222+
#[cfg(f16_enabled)]
223+
float_impl!(f16, u16, i16, i8, 16, 10);
222224
float_impl!(f32, u32, i32, i16, 32, 23);
223225
float_impl!(f64, u64, i64, i16, 64, 52);
226+
#[cfg(f128_enabled)]
227+
float_impl!(f128, u128, i128, i16, 128, 112);

0 commit comments

Comments
 (0)