Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configure f16 and f128 support for WebAssembly #665

Merged
merged 2 commits into from
Aug 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 2 additions & 79 deletions build.rs
Original file line number Diff line number Diff line change
@@ -1,44 +1,8 @@
use std::{collections::BTreeMap, env, path::PathBuf, sync::atomic::Ordering};

#[allow(dead_code)]
struct Target {
triple: String,
os: String,
arch: String,
vendor: String,
env: String,
pointer_width: u8,
little_endian: bool,
features: Vec<String>,
}

impl Target {
fn from_env() -> Self {
let little_endian = match env::var("CARGO_CFG_TARGET_ENDIAN").unwrap().as_str() {
"little" => true,
"big" => false,
x => panic!("unknown endian {x}"),
};
mod configure;

Self {
triple: env::var("TARGET").unwrap(),
os: env::var("CARGO_CFG_TARGET_OS").unwrap(),
arch: env::var("CARGO_CFG_TARGET_ARCH").unwrap(),
vendor: env::var("CARGO_CFG_TARGET_VENDOR").unwrap(),
env: env::var("CARGO_CFG_TARGET_ENV").unwrap(),
pointer_width: env::var("CARGO_CFG_TARGET_POINTER_WIDTH")
.unwrap()
.parse()
.unwrap(),
little_endian,
features: env::var("CARGO_CFG_TARGET_FEATURE")
.unwrap_or_default()
.split(",")
.map(ToOwned::to_owned)
.collect(),
}
}
}
use configure::{configure_f16_f128, Target};

fn main() {
println!("cargo:rerun-if-changed=build.rs");
Expand Down Expand Up @@ -261,47 +225,6 @@ 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 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_ok, f128_ok) = match target.arch.as_str() {
// `f16` and `f128` both crash <https://github.com/llvm/llvm-project/issues/94434>
"arm64ec" => (false, false),
// `f16` crashes <https://github.com/llvm/llvm-project/issues/50374>
"s390x" => (false, true),
// `f128` crashes <https://github.com/llvm/llvm-project/issues/96432>
"mips64" | "mips64r6" => (true, false),
// `f128` crashes <https://github.com/llvm/llvm-project/issues/101545>
"powerpc64" if &target.os == "aix" => (true, false),
// `f128` crashes <https://github.com/llvm/llvm-project/issues/41838>
"sparc" | "sparcv9" => (true, false),
// Most everything else works as of LLVM 19
_ => (true, 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_ok && !disable_both {
println!("cargo::rustc-cfg=f16_enabled");
}

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

#[cfg(feature = "c")]
mod c {
use std::collections::{BTreeMap, HashSet};
Expand Down
86 changes: 86 additions & 0 deletions configure.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Configuration that is shared between `compiler_builtins` and `testcrate`.

use std::env;
kleisauke marked this conversation as resolved.
Show resolved Hide resolved

#[allow(dead_code)]
pub struct Target {
pub triple: String,
pub os: String,
pub arch: String,
pub vendor: String,
pub env: String,
pub pointer_width: u8,
pub little_endian: bool,
pub features: Vec<String>,
}

impl Target {
pub fn from_env() -> Self {
let little_endian = match env::var("CARGO_CFG_TARGET_ENDIAN").unwrap().as_str() {
"little" => true,
"big" => false,
x => panic!("unknown endian {x}"),
};

Self {
triple: env::var("TARGET").unwrap(),
os: env::var("CARGO_CFG_TARGET_OS").unwrap(),
arch: env::var("CARGO_CFG_TARGET_ARCH").unwrap(),
vendor: env::var("CARGO_CFG_TARGET_VENDOR").unwrap(),
env: env::var("CARGO_CFG_TARGET_ENV").unwrap(),
pointer_width: env::var("CARGO_CFG_TARGET_POINTER_WIDTH")
.unwrap()
.parse()
.unwrap(),
little_endian,
features: env::var("CARGO_CFG_TARGET_FEATURE")
.unwrap_or_default()
.split(",")
.map(ToOwned::to_owned)
.collect(),
}
}
}

/// Configure whether or not `f16` and `f128` support should be enabled.
pub 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 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_ok, f128_ok) = match target.arch.as_str() {
// `f16` and `f128` both crash <https://github.com/llvm/llvm-project/issues/94434>
"arm64ec" => (false, false),
// `f16` crashes <https://github.com/llvm/llvm-project/issues/50374>
"s390x" => (false, true),
// `f128` crashes <https://github.com/llvm/llvm-project/issues/96432>
"mips64" | "mips64r6" => (true, false),
// `f128` crashes <https://github.com/llvm/llvm-project/issues/101545>
"powerpc64" if &target.os == "aix" => (true, false),
// `f128` crashes <https://github.com/llvm/llvm-project/issues/41838>
"sparc" | "sparcv9" => (true, false),
// `f16` miscompiles <https://github.com/llvm/llvm-project/issues/96438>
"wasm32" | "wasm64" => (false, true),
// Most everything else works as of LLVM 19
_ => (true, 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_ok && !disable_both {
println!("cargo::rustc-cfg=f16_enabled");
}

if f128_ok && !disable_both {
println!("cargo::rustc-cfg=f128_enabled");
}
}
18 changes: 15 additions & 3 deletions testcrate/benches/float_add.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![feature(f128)]
#![cfg_attr(f128_enabled, feature(f128))]

use compiler_builtins::float::add;
use criterion::{criterion_group, criterion_main, Criterion};
use criterion::{criterion_main, Criterion};
use testcrate::float_bench;

float_bench! {
Expand Down Expand Up @@ -66,6 +66,7 @@ float_bench! {
],
}

#[cfg(f128_enabled)]
float_bench! {
name: add_f128,
sig: (a: f128, b: f128) -> f128,
Expand All @@ -77,5 +78,16 @@ float_bench! {
asm: []
}

criterion_group!(float_add, add_f32, add_f64, add_f128);
pub fn float_add() {
let mut criterion = Criterion::default().configure_from_args();

add_f32(&mut criterion);
add_f64(&mut criterion);

#[cfg(f128_enabled)]
{
add_f128(&mut criterion);
}
}

criterion_main!(float_add);
28 changes: 17 additions & 11 deletions testcrate/benches/float_cmp.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![feature(f128)]
#![cfg_attr(f128_enabled, feature(f128))]

use criterion::{criterion_group, criterion_main, Criterion};
use criterion::{criterion_main, Criterion};
use testcrate::float_bench;

use compiler_builtins::float::cmp;
Expand Down Expand Up @@ -190,13 +190,19 @@ float_bench! {
asm: []
}

criterion_group!(
float_cmp,
cmp_f32_gt,
cmp_f32_unord,
cmp_f64_gt,
cmp_f64_unord,
cmp_f128_gt,
cmp_f128_unord
);
pub fn float_cmp() {
let mut criterion = Criterion::default().configure_from_args();

cmp_f32_gt(&mut criterion);
cmp_f32_unord(&mut criterion);
cmp_f64_gt(&mut criterion);
cmp_f64_unord(&mut criterion);

#[cfg(f128_enabled)]
{
cmp_f128_gt(&mut criterion);
cmp_f128_unord(&mut criterion);
}
}

criterion_main!(float_cmp);
1 change: 0 additions & 1 deletion testcrate/benches/float_conv.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#![feature(f128)]
#![allow(improper_ctypes)]

use compiler_builtins::float::conv;
Expand Down
2 changes: 0 additions & 2 deletions testcrate/benches/float_div.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#![feature(f128)]

use compiler_builtins::float::div;
use criterion::{criterion_group, criterion_main, Criterion};
use testcrate::float_bench;
Expand Down
49 changes: 29 additions & 20 deletions testcrate/benches/float_extend.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
#![allow(unused_variables)] // "unused" f16 registers
#![feature(f128)]
#![feature(f16)]
#![cfg_attr(f128_enabled, feature(f128))]
#![cfg_attr(f16_enabled, feature(f16))]

use compiler_builtins::float::extend;
use criterion::{criterion_group, criterion_main, Criterion};
use criterion::{criterion_main, Criterion};
use testcrate::float_bench;

#[cfg(f16_enabled)]
float_bench! {
name: extend_f16_f32,
sig: (a: f16) -> f32,
Expand All @@ -28,6 +29,7 @@ float_bench! {
],
}

#[cfg(all(f16_enabled, f128_enabled))]
float_bench! {
name: extend_f16_f128,
sig: (a: f16) -> f128,
Expand Down Expand Up @@ -60,6 +62,7 @@ float_bench! {
],
}

#[cfg(f128_enabled)]
float_bench! {
name: extend_f32_f128,
sig: (a: f32) -> f128,
Expand All @@ -71,6 +74,7 @@ float_bench! {
asm: [],
}

#[cfg(f128_enabled)]
float_bench! {
name: extend_f64_f128,
sig: (a: f64) -> f128,
Expand All @@ -82,23 +86,28 @@ float_bench! {
asm: [],
}

#[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))]
criterion_group!(
float_extend,
extend_f16_f32,
extend_f16_f128,
extend_f32_f64,
extend_f32_f128,
extend_f64_f128,
);
pub fn float_extend() {
let mut criterion = Criterion::default().configure_from_args();

// FIXME(#655): `f16` tests disabled until we can bootstrap symbols
#[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))]
criterion_group!(
float_extend,
extend_f32_f64,
extend_f32_f128,
extend_f64_f128,
);
// FIXME(#655): `f16` tests disabled until we can bootstrap symbols
#[cfg(f16_enabled)]
#[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))]
{
extend_f16_f32(&mut criterion);

#[cfg(f128_enabled)]
{
extend_f16_f128(&mut criterion);
}
}

extend_f32_f64(&mut criterion);

#[cfg(f128_enabled)]
{
extend_f32_f128(&mut criterion);
extend_f64_f128(&mut criterion);
}
}

criterion_main!(float_extend);
18 changes: 15 additions & 3 deletions testcrate/benches/float_mul.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![feature(f128)]
#![cfg_attr(f128_enabled, feature(f128))]

use compiler_builtins::float::mul;
use criterion::{criterion_group, criterion_main, Criterion};
use criterion::{criterion_main, Criterion};
use testcrate::float_bench;

float_bench! {
Expand Down Expand Up @@ -66,6 +66,7 @@ float_bench! {
],
}

#[cfg(f128_enabled)]
float_bench! {
name: mul_f128,
sig: (a: f128, b: f128) -> f128,
Expand All @@ -77,5 +78,16 @@ float_bench! {
asm: []
}

criterion_group!(float_mul, mul_f32, mul_f64, mul_f128);
pub fn float_mul() {
let mut criterion = Criterion::default().configure_from_args();

mul_f32(&mut criterion);
mul_f64(&mut criterion);

#[cfg(f128_enabled)]
{
mul_f128(&mut criterion);
}
}

criterion_main!(float_mul);
Loading
Loading