Add f16 and f128 configuration from compiler-builtins
In preparation of adding routines from these two types, duplicate the `compiler-builtins` configuration here.
This commit is contained in:
committed by
Trevor Gross
parent
b9871da445
commit
f2e16b6ac1
@@ -21,7 +21,7 @@ arch = []
|
|||||||
|
|
||||||
# This tells the compiler to assume that a Nightly toolchain is being used and
|
# This tells the compiler to assume that a Nightly toolchain is being used and
|
||||||
# that it should activate any useful Nightly things accordingly.
|
# that it should activate any useful Nightly things accordingly.
|
||||||
unstable = ["unstable-intrinsics"]
|
unstable = ["unstable-intrinsics", "unstable-float"]
|
||||||
|
|
||||||
# Enable calls to functions in `core::intrinsics`
|
# Enable calls to functions in `core::intrinsics`
|
||||||
unstable-intrinsics = []
|
unstable-intrinsics = []
|
||||||
@@ -29,6 +29,9 @@ unstable-intrinsics = []
|
|||||||
# Make some internal things public for testing.
|
# Make some internal things public for testing.
|
||||||
unstable-test-support = []
|
unstable-test-support = []
|
||||||
|
|
||||||
|
# Enable the nightly-only `f16` and `f128`.
|
||||||
|
unstable-float = []
|
||||||
|
|
||||||
# Used to prevent using any intrinsics or arch-specific code.
|
# Used to prevent using any intrinsics or arch-specific code.
|
||||||
#
|
#
|
||||||
# HACK: this is a negative feature which is generally a bad idea in Cargo, but
|
# HACK: this is a negative feature which is generally a bad idea in Cargo, but
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
|
mod configure;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
let cfg = configure::Config::from_env();
|
||||||
|
|
||||||
println!("cargo:rerun-if-changed=build.rs");
|
println!("cargo:rerun-if-changed=build.rs");
|
||||||
println!("cargo:rustc-check-cfg=cfg(assert_no_panic)");
|
println!("cargo:rustc-check-cfg=cfg(assert_no_panic)");
|
||||||
|
|
||||||
@@ -14,29 +18,5 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
configure_intrinsics();
|
configure::emit_libm_config(&cfg);
|
||||||
configure_arch();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Simplify the feature logic for enabling intrinsics so code only needs to use
|
|
||||||
/// `cfg(intrinsics_enabled)`.
|
|
||||||
fn configure_intrinsics() {
|
|
||||||
println!("cargo:rustc-check-cfg=cfg(intrinsics_enabled)");
|
|
||||||
|
|
||||||
// Disabled by default; `unstable-intrinsics` enables again; `force-soft-floats` overrides
|
|
||||||
// to disable.
|
|
||||||
if cfg!(feature = "unstable-intrinsics") && !cfg!(feature = "force-soft-floats") {
|
|
||||||
println!("cargo:rustc-cfg=intrinsics_enabled");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Simplify the feature logic for enabling arch-specific features so code only needs to use
|
|
||||||
/// `cfg(arch_enabled)`.
|
|
||||||
fn configure_arch() {
|
|
||||||
println!("cargo:rustc-check-cfg=cfg(arch_enabled)");
|
|
||||||
|
|
||||||
// Enabled by default via the "arch" feature, `force-soft-floats` overrides to disable.
|
|
||||||
if cfg!(feature = "arch") && !cfg!(feature = "force-soft-floats") {
|
|
||||||
println!("cargo:rustc-cfg=arch_enabled");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
168
library/compiler-builtins/libm/configure.rs
Normal file
168
library/compiler-builtins/libm/configure.rs
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
// Configuration shared with both libm and libm-test
|
||||||
|
|
||||||
|
use std::env;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub struct Config {
|
||||||
|
pub manifest_dir: PathBuf,
|
||||||
|
pub out_dir: PathBuf,
|
||||||
|
pub opt_level: u8,
|
||||||
|
pub target_arch: String,
|
||||||
|
pub target_env: String,
|
||||||
|
pub target_family: Option<String>,
|
||||||
|
pub target_os: String,
|
||||||
|
pub target_string: String,
|
||||||
|
pub target_vendor: String,
|
||||||
|
pub target_features: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Config {
|
||||||
|
pub fn from_env() -> Self {
|
||||||
|
let target_features = env::var("CARGO_CFG_TARGET_FEATURE")
|
||||||
|
.map(|feats| feats.split(',').map(ToOwned::to_owned).collect())
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
Self {
|
||||||
|
manifest_dir: PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()),
|
||||||
|
out_dir: PathBuf::from(env::var("OUT_DIR").unwrap()),
|
||||||
|
opt_level: env::var("OPT_LEVEL").unwrap().parse().unwrap(),
|
||||||
|
target_arch: env::var("CARGO_CFG_TARGET_ARCH").unwrap(),
|
||||||
|
target_env: env::var("CARGO_CFG_TARGET_ENV").unwrap(),
|
||||||
|
target_family: env::var("CARGO_CFG_TARGET_FAMILY").ok(),
|
||||||
|
target_os: env::var("CARGO_CFG_TARGET_OS").unwrap(),
|
||||||
|
target_string: env::var("TARGET").unwrap(),
|
||||||
|
target_vendor: env::var("CARGO_CFG_TARGET_VENDOR").unwrap(),
|
||||||
|
target_features,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Libm gets most config options made available.
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn emit_libm_config(cfg: &Config) {
|
||||||
|
emit_intrinsics_cfg();
|
||||||
|
emit_arch_cfg();
|
||||||
|
emit_optimization_cfg(cfg);
|
||||||
|
emit_cfg_shorthands(cfg);
|
||||||
|
emit_f16_f128_cfg(cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Tests don't need most feature-related config.
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn emit_test_config(cfg: &Config) {
|
||||||
|
emit_optimization_cfg(cfg);
|
||||||
|
emit_cfg_shorthands(cfg);
|
||||||
|
emit_f16_f128_cfg(cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Simplify the feature logic for enabling intrinsics so code only needs to use
|
||||||
|
/// `cfg(intrinsics_enabled)`.
|
||||||
|
fn emit_intrinsics_cfg() {
|
||||||
|
println!("cargo:rustc-check-cfg=cfg(intrinsics_enabled)");
|
||||||
|
|
||||||
|
// Disabled by default; `unstable-intrinsics` enables again; `force-soft-floats` overrides
|
||||||
|
// to disable.
|
||||||
|
if cfg!(feature = "unstable-intrinsics") && !cfg!(feature = "force-soft-floats") {
|
||||||
|
println!("cargo:rustc-cfg=intrinsics_enabled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Simplify the feature logic for enabling arch-specific features so code only needs to use
|
||||||
|
/// `cfg(arch_enabled)`.
|
||||||
|
fn emit_arch_cfg() {
|
||||||
|
println!("cargo:rustc-check-cfg=cfg(arch_enabled)");
|
||||||
|
|
||||||
|
// Enabled by default via the "arch" feature, `force-soft-floats` overrides to disable.
|
||||||
|
if cfg!(feature = "arch") && !cfg!(feature = "force-soft-floats") {
|
||||||
|
println!("cargo:rustc-cfg=arch_enabled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Some tests are extremely slow. Emit a config option based on optimization level.
|
||||||
|
fn emit_optimization_cfg(cfg: &Config) {
|
||||||
|
println!("cargo:rustc-check-cfg=cfg(optimizations_enabled)");
|
||||||
|
|
||||||
|
if cfg.opt_level >= 2 {
|
||||||
|
println!("cargo:rustc-cfg=optimizations_enabled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Provide an alias for common longer config combinations.
|
||||||
|
fn emit_cfg_shorthands(cfg: &Config) {
|
||||||
|
println!("cargo:rustc-check-cfg=cfg(x86_no_sse)");
|
||||||
|
if cfg.target_arch == "x86" && !cfg.target_features.iter().any(|f| f == "sse") {
|
||||||
|
// Shorthand to detect i586 targets
|
||||||
|
println!("cargo:rustc-cfg=x86_no_sse");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Configure whether or not `f16` and `f128` support should be enabled.
|
||||||
|
fn emit_f16_f128_cfg(cfg: &Config) {
|
||||||
|
println!("cargo:rustc-check-cfg=cfg(f16_enabled)");
|
||||||
|
println!("cargo:rustc-check-cfg=cfg(f128_enabled)");
|
||||||
|
|
||||||
|
// `unstable-float` enables these features.
|
||||||
|
if !cfg!(feature = "unstable-float") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 and generates code that can be called
|
||||||
|
// without crashing (no infinite recursion). This does not mean that the platform doesn't have
|
||||||
|
// ABI or other bugs.
|
||||||
|
//
|
||||||
|
// We do this here rather than in `rust-lang/rust` because configuring via cargo features is
|
||||||
|
// not straightforward.
|
||||||
|
//
|
||||||
|
// Original source of this list:
|
||||||
|
// <https://github.com/rust-lang/compiler-builtins/pull/652#issuecomment-2266151350>
|
||||||
|
let f16_enabled = match cfg.target_arch.as_str() {
|
||||||
|
// Unsupported <https://github.com/llvm/llvm-project/issues/94434>
|
||||||
|
"arm64ec" => false,
|
||||||
|
// Selection failure <https://github.com/llvm/llvm-project/issues/50374>
|
||||||
|
"s390x" => false,
|
||||||
|
// Infinite recursion <https://github.com/llvm/llvm-project/issues/97981>
|
||||||
|
// FIXME(llvm): loongarch fixed by <https://github.com/llvm/llvm-project/pull/107791>
|
||||||
|
"csky" => false,
|
||||||
|
"hexagon" => false,
|
||||||
|
"loongarch64" => false,
|
||||||
|
"mips" | "mips64" | "mips32r6" | "mips64r6" => false,
|
||||||
|
"powerpc" | "powerpc64" => false,
|
||||||
|
"sparc" | "sparc64" => false,
|
||||||
|
"wasm32" | "wasm64" => false,
|
||||||
|
// Most everything else works as of LLVM 19
|
||||||
|
_ => true,
|
||||||
|
};
|
||||||
|
|
||||||
|
let f128_enabled = match cfg.target_arch.as_str() {
|
||||||
|
// Unsupported (libcall is not supported) <https://github.com/llvm/llvm-project/issues/121122>
|
||||||
|
"amdgpu" => false,
|
||||||
|
// Unsupported <https://github.com/llvm/llvm-project/issues/94434>
|
||||||
|
"arm64ec" => false,
|
||||||
|
// Selection failure <https://github.com/llvm/llvm-project/issues/96432>
|
||||||
|
"mips64" | "mips64r6" => false,
|
||||||
|
// Selection failure <https://github.com/llvm/llvm-project/issues/95471>
|
||||||
|
"nvptx64" => false,
|
||||||
|
// Selection failure <https://github.com/llvm/llvm-project/issues/101545>
|
||||||
|
"powerpc64" if &cfg.target_os == "aix" => false,
|
||||||
|
// Selection failure <https://github.com/llvm/llvm-project/issues/41838>
|
||||||
|
"sparc" => false,
|
||||||
|
// Most everything else works as of LLVM 19
|
||||||
|
_ => true,
|
||||||
|
};
|
||||||
|
|
||||||
|
// If the feature is set, disable these types.
|
||||||
|
let disable_both = env::var_os("CARGO_FEATURE_NO_F16_F128").is_some();
|
||||||
|
|
||||||
|
println!("cargo:rustc-check-cfg=cfg(f16_enabled)");
|
||||||
|
println!("cargo:rustc-check-cfg=cfg(f128_enabled)");
|
||||||
|
|
||||||
|
if f16_enabled && !disable_both {
|
||||||
|
println!("cargo:rustc-cfg=f16_enabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
if f128_enabled && !disable_both {
|
||||||
|
println!("cargo:rustc-cfg=f128_enabled");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,5 +21,7 @@ force-soft-floats = []
|
|||||||
unexpected_cfgs = { level = "warn", check-cfg = [
|
unexpected_cfgs = { level = "warn", check-cfg = [
|
||||||
"cfg(arch_enabled)",
|
"cfg(arch_enabled)",
|
||||||
"cfg(assert_no_panic)",
|
"cfg(assert_no_panic)",
|
||||||
|
"cfg(f128_enabled)",
|
||||||
|
"cfg(f16_enabled)",
|
||||||
"cfg(intrinsics_enabled)",
|
"cfg(intrinsics_enabled)",
|
||||||
] }
|
] }
|
||||||
|
|||||||
@@ -12,3 +12,10 @@ heck = "0.5.0"
|
|||||||
proc-macro2 = "1.0.88"
|
proc-macro2 = "1.0.88"
|
||||||
quote = "1.0.37"
|
quote = "1.0.37"
|
||||||
syn = { version = "2.0.79", features = ["full", "extra-traits", "visit-mut"] }
|
syn = { version = "2.0.79", features = ["full", "extra-traits", "visit-mut"] }
|
||||||
|
|
||||||
|
[lints.rust]
|
||||||
|
# Values used during testing
|
||||||
|
unexpected_cfgs = { level = "warn", check-cfg = [
|
||||||
|
'cfg(f16_enabled)',
|
||||||
|
'cfg(f128_enabled)',
|
||||||
|
] }
|
||||||
|
|||||||
@@ -5,7 +5,10 @@ edition = "2021"
|
|||||||
publish = false
|
publish = false
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = ["unstable-float"]
|
||||||
|
|
||||||
|
# Propagated from libm because this affects which functions we test.
|
||||||
|
unstable-float = ["libm/unstable-float"]
|
||||||
|
|
||||||
# Generate tests which are random inputs and the outputs are calculated with
|
# Generate tests which are random inputs and the outputs are calculated with
|
||||||
# musl libc.
|
# musl libc.
|
||||||
@@ -44,3 +47,9 @@ criterion = { version = "0.5.1", default-features = false, features = ["cargo_be
|
|||||||
[[bench]]
|
[[bench]]
|
||||||
name = "random"
|
name = "random"
|
||||||
harness = false
|
harness = false
|
||||||
|
|
||||||
|
[lints.rust]
|
||||||
|
# Values from the chared config.rs used by `libm` but not the test crate
|
||||||
|
unexpected_cfgs = { level = "warn", check-cfg = [
|
||||||
|
'cfg(feature, values("arch", "force-soft-floats", "unstable-intrinsics"))',
|
||||||
|
] }
|
||||||
|
|||||||
@@ -1,66 +1,16 @@
|
|||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
use std::path::PathBuf;
|
use std::fs;
|
||||||
use std::{env, fs};
|
|
||||||
|
#[path = "../../configure.rs"]
|
||||||
|
mod configure;
|
||||||
|
use configure::Config;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let cfg = Config::from_env();
|
let cfg = Config::from_env();
|
||||||
|
|
||||||
emit_optimization_cfg(&cfg);
|
|
||||||
emit_cfg_shorthands(&cfg);
|
|
||||||
list_all_tests(&cfg);
|
list_all_tests(&cfg);
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
configure::emit_test_config(&cfg);
|
||||||
struct Config {
|
|
||||||
manifest_dir: PathBuf,
|
|
||||||
out_dir: PathBuf,
|
|
||||||
opt_level: u8,
|
|
||||||
target_arch: String,
|
|
||||||
target_env: String,
|
|
||||||
target_family: Option<String>,
|
|
||||||
target_os: String,
|
|
||||||
target_string: String,
|
|
||||||
target_vendor: String,
|
|
||||||
target_features: Vec<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Config {
|
|
||||||
fn from_env() -> Self {
|
|
||||||
let target_features = env::var("CARGO_CFG_TARGET_FEATURE")
|
|
||||||
.map(|feats| feats.split(',').map(ToOwned::to_owned).collect())
|
|
||||||
.unwrap_or_default();
|
|
||||||
|
|
||||||
Self {
|
|
||||||
manifest_dir: PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()),
|
|
||||||
out_dir: PathBuf::from(env::var("OUT_DIR").unwrap()),
|
|
||||||
opt_level: env::var("OPT_LEVEL").unwrap().parse().unwrap(),
|
|
||||||
target_arch: env::var("CARGO_CFG_TARGET_ARCH").unwrap(),
|
|
||||||
target_env: env::var("CARGO_CFG_TARGET_ENV").unwrap(),
|
|
||||||
target_family: env::var("CARGO_CFG_TARGET_FAMILY").ok(),
|
|
||||||
target_os: env::var("CARGO_CFG_TARGET_OS").unwrap(),
|
|
||||||
target_string: env::var("TARGET").unwrap(),
|
|
||||||
target_vendor: env::var("CARGO_CFG_TARGET_VENDOR").unwrap(),
|
|
||||||
target_features,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Some tests are extremely slow. Emit a config option based on optimization level.
|
|
||||||
fn emit_optimization_cfg(cfg: &Config) {
|
|
||||||
println!("cargo::rustc-check-cfg=cfg(optimizations_enabled)");
|
|
||||||
|
|
||||||
if cfg.opt_level >= 2 {
|
|
||||||
println!("cargo::rustc-cfg=optimizations_enabled");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Provide an alias for common longer config combinations.
|
|
||||||
fn emit_cfg_shorthands(cfg: &Config) {
|
|
||||||
println!("cargo::rustc-check-cfg=cfg(x86_no_sse)");
|
|
||||||
if cfg.target_arch == "x86" && !cfg.target_features.iter().any(|f| f == "sse") {
|
|
||||||
// Shorthand to detect i586 targets
|
|
||||||
println!("cargo::rustc-cfg=x86_no_sse");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a list of all source files in an array. This can be used for making sure that
|
/// Create a list of all source files in an array. This can be used for making sure that
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![cfg_attr(intrinsics_enabled, allow(internal_features))]
|
#![cfg_attr(intrinsics_enabled, allow(internal_features))]
|
||||||
#![cfg_attr(intrinsics_enabled, feature(core_intrinsics))]
|
#![cfg_attr(intrinsics_enabled, feature(core_intrinsics))]
|
||||||
|
#![cfg_attr(f128_enabled, feature(f128))]
|
||||||
|
#![cfg_attr(f16_enabled, feature(f16))]
|
||||||
#![allow(clippy::assign_op_pattern)]
|
#![allow(clippy::assign_op_pattern)]
|
||||||
#![allow(clippy::deprecated_cfg_attr)]
|
#![allow(clippy::deprecated_cfg_attr)]
|
||||||
#![allow(clippy::eq_op)]
|
#![allow(clippy::eq_op)]
|
||||||
|
|||||||
@@ -219,5 +219,9 @@ macro_rules! float_impl {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(f16_enabled)]
|
||||||
|
float_impl!(f16, u16, i16, i8, 16, 10);
|
||||||
float_impl!(f32, u32, i32, i16, 32, 23);
|
float_impl!(f32, u32, i32, i16, 32, 23);
|
||||||
float_impl!(f64, u64, i64, i16, 64, 52);
|
float_impl!(f64, u64, i64, i16, 64, 52);
|
||||||
|
#[cfg(f128_enabled)]
|
||||||
|
float_impl!(f128, u128, i128, i16, 128, 112);
|
||||||
|
|||||||
Reference in New Issue
Block a user