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
|
||||
# that it should activate any useful Nightly things accordingly.
|
||||
unstable = ["unstable-intrinsics"]
|
||||
unstable = ["unstable-intrinsics", "unstable-float"]
|
||||
|
||||
# Enable calls to functions in `core::intrinsics`
|
||||
unstable-intrinsics = []
|
||||
@@ -29,6 +29,9 @@ unstable-intrinsics = []
|
||||
# Make some internal things public for testing.
|
||||
unstable-test-support = []
|
||||
|
||||
# Enable the nightly-only `f16` and `f128`.
|
||||
unstable-float = []
|
||||
|
||||
# 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
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
use std::env;
|
||||
|
||||
mod configure;
|
||||
|
||||
fn main() {
|
||||
let cfg = configure::Config::from_env();
|
||||
|
||||
println!("cargo:rerun-if-changed=build.rs");
|
||||
println!("cargo:rustc-check-cfg=cfg(assert_no_panic)");
|
||||
|
||||
@@ -14,29 +18,5 @@ fn main() {
|
||||
}
|
||||
}
|
||||
|
||||
configure_intrinsics();
|
||||
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");
|
||||
}
|
||||
configure::emit_libm_config(&cfg);
|
||||
}
|
||||
|
||||
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 = [
|
||||
"cfg(arch_enabled)",
|
||||
"cfg(assert_no_panic)",
|
||||
"cfg(f128_enabled)",
|
||||
"cfg(f16_enabled)",
|
||||
"cfg(intrinsics_enabled)",
|
||||
] }
|
||||
|
||||
@@ -12,3 +12,10 @@ heck = "0.5.0"
|
||||
proc-macro2 = "1.0.88"
|
||||
quote = "1.0.37"
|
||||
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
|
||||
|
||||
[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
|
||||
# musl libc.
|
||||
@@ -44,3 +47,9 @@ criterion = { version = "0.5.1", default-features = false, features = ["cargo_be
|
||||
[[bench]]
|
||||
name = "random"
|
||||
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::path::PathBuf;
|
||||
use std::{env, fs};
|
||||
use std::fs;
|
||||
|
||||
#[path = "../../configure.rs"]
|
||||
mod configure;
|
||||
use configure::Config;
|
||||
|
||||
fn main() {
|
||||
let cfg = Config::from_env();
|
||||
|
||||
emit_optimization_cfg(&cfg);
|
||||
emit_cfg_shorthands(&cfg);
|
||||
list_all_tests(&cfg);
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
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");
|
||||
}
|
||||
configure::emit_test_config(&cfg);
|
||||
}
|
||||
|
||||
/// Create a list of all source files in an array. This can be used for making sure that
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
#![no_std]
|
||||
#![cfg_attr(intrinsics_enabled, allow(internal_features))]
|
||||
#![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::deprecated_cfg_attr)]
|
||||
#![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!(f64, u64, i64, i16, 64, 52);
|
||||
#[cfg(f128_enabled)]
|
||||
float_impl!(f128, u128, i128, i16, 128, 112);
|
||||
|
||||
Reference in New Issue
Block a user