Skip to content

Commit 7f9209d

Browse files
authored
Merge pull request #665 from kleisauke/wasm-f16-f128-feature
Configure `f16` and `f128` support for WebAssembly
2 parents 3ad4d9c + 35c5554 commit 7f9209d

17 files changed

+262
-181
lines changed

build.rs

+2-79
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,8 @@
11
use std::{collections::BTreeMap, env, path::PathBuf, sync::atomic::Ordering};
22

3-
#[allow(dead_code)]
4-
struct Target {
5-
triple: String,
6-
os: String,
7-
arch: String,
8-
vendor: String,
9-
env: String,
10-
pointer_width: u8,
11-
little_endian: bool,
12-
features: Vec<String>,
13-
}
14-
15-
impl Target {
16-
fn from_env() -> Self {
17-
let little_endian = match env::var("CARGO_CFG_TARGET_ENDIAN").unwrap().as_str() {
18-
"little" => true,
19-
"big" => false,
20-
x => panic!("unknown endian {x}"),
21-
};
3+
mod configure;
224

23-
Self {
24-
triple: env::var("TARGET").unwrap(),
25-
os: env::var("CARGO_CFG_TARGET_OS").unwrap(),
26-
arch: env::var("CARGO_CFG_TARGET_ARCH").unwrap(),
27-
vendor: env::var("CARGO_CFG_TARGET_VENDOR").unwrap(),
28-
env: env::var("CARGO_CFG_TARGET_ENV").unwrap(),
29-
pointer_width: env::var("CARGO_CFG_TARGET_POINTER_WIDTH")
30-
.unwrap()
31-
.parse()
32-
.unwrap(),
33-
little_endian,
34-
features: env::var("CARGO_CFG_TARGET_FEATURE")
35-
.unwrap_or_default()
36-
.split(",")
37-
.map(ToOwned::to_owned)
38-
.collect(),
39-
}
40-
}
41-
}
5+
use configure::{configure_f16_f128, Target};
426

437
fn main() {
448
println!("cargo:rerun-if-changed=build.rs");
@@ -261,47 +225,6 @@ fn configure_check_cfg() {
261225
println!("cargo::rustc-check-cfg=cfg(assert_no_panic)");
262226
}
263227

264-
/// Configure whether or not `f16` and `f128` support should be enabled.
265-
fn configure_f16_f128(target: &Target) {
266-
// Set whether or not `f16` and `f128` are supported at a basic level by LLVM. This only means
267-
// that the backend will not crash when using these types. This does not mean that the
268-
// backend does the right thing, or that the platform doesn't have ABI bugs.
269-
//
270-
// We do this here rather than in `rust-lang/rust` because configuring via cargo features is
271-
// not straightforward.
272-
//
273-
// Original source of this list:
274-
// <https://github.com/rust-lang/compiler-builtins/pull/652#issuecomment-2266151350>
275-
let (f16_ok, f128_ok) = match target.arch.as_str() {
276-
// `f16` and `f128` both crash <https://github.com/llvm/llvm-project/issues/94434>
277-
"arm64ec" => (false, false),
278-
// `f16` crashes <https://github.com/llvm/llvm-project/issues/50374>
279-
"s390x" => (false, true),
280-
// `f128` crashes <https://github.com/llvm/llvm-project/issues/96432>
281-
"mips64" | "mips64r6" => (true, false),
282-
// `f128` crashes <https://github.com/llvm/llvm-project/issues/101545>
283-
"powerpc64" if &target.os == "aix" => (true, false),
284-
// `f128` crashes <https://github.com/llvm/llvm-project/issues/41838>
285-
"sparc" | "sparcv9" => (true, false),
286-
// Most everything else works as of LLVM 19
287-
_ => (true, true),
288-
};
289-
290-
// If the feature is set, disable these types.
291-
let disable_both = env::var_os("CARGO_FEATURE_NO_F16_F128").is_some();
292-
293-
println!("cargo::rustc-check-cfg=cfg(f16_enabled)");
294-
println!("cargo::rustc-check-cfg=cfg(f128_enabled)");
295-
296-
if f16_ok && !disable_both {
297-
println!("cargo::rustc-cfg=f16_enabled");
298-
}
299-
300-
if f128_ok && !disable_both {
301-
println!("cargo::rustc-cfg=f128_enabled");
302-
}
303-
}
304-
305228
#[cfg(feature = "c")]
306229
mod c {
307230
use std::collections::{BTreeMap, HashSet};

configure.rs

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// Configuration that is shared between `compiler_builtins` and `testcrate`.
2+
3+
use std::env;
4+
5+
#[allow(dead_code)]
6+
pub struct Target {
7+
pub triple: String,
8+
pub os: String,
9+
pub arch: String,
10+
pub vendor: String,
11+
pub env: String,
12+
pub pointer_width: u8,
13+
pub little_endian: bool,
14+
pub features: Vec<String>,
15+
}
16+
17+
impl Target {
18+
pub fn from_env() -> Self {
19+
let little_endian = match env::var("CARGO_CFG_TARGET_ENDIAN").unwrap().as_str() {
20+
"little" => true,
21+
"big" => false,
22+
x => panic!("unknown endian {x}"),
23+
};
24+
25+
Self {
26+
triple: env::var("TARGET").unwrap(),
27+
os: env::var("CARGO_CFG_TARGET_OS").unwrap(),
28+
arch: env::var("CARGO_CFG_TARGET_ARCH").unwrap(),
29+
vendor: env::var("CARGO_CFG_TARGET_VENDOR").unwrap(),
30+
env: env::var("CARGO_CFG_TARGET_ENV").unwrap(),
31+
pointer_width: env::var("CARGO_CFG_TARGET_POINTER_WIDTH")
32+
.unwrap()
33+
.parse()
34+
.unwrap(),
35+
little_endian,
36+
features: env::var("CARGO_CFG_TARGET_FEATURE")
37+
.unwrap_or_default()
38+
.split(",")
39+
.map(ToOwned::to_owned)
40+
.collect(),
41+
}
42+
}
43+
}
44+
45+
/// Configure whether or not `f16` and `f128` support should be enabled.
46+
pub fn configure_f16_f128(target: &Target) {
47+
// Set whether or not `f16` and `f128` are supported at a basic level by LLVM. This only means
48+
// that the backend will not crash when using these types. This does not mean that the
49+
// backend does the right thing, or that the platform doesn't have ABI bugs.
50+
//
51+
// We do this here rather than in `rust-lang/rust` because configuring via cargo features is
52+
// not straightforward.
53+
//
54+
// Original source of this list:
55+
// <https://github.com/rust-lang/compiler-builtins/pull/652#issuecomment-2266151350>
56+
let (f16_ok, f128_ok) = match target.arch.as_str() {
57+
// `f16` and `f128` both crash <https://github.com/llvm/llvm-project/issues/94434>
58+
"arm64ec" => (false, false),
59+
// `f16` crashes <https://github.com/llvm/llvm-project/issues/50374>
60+
"s390x" => (false, true),
61+
// `f128` crashes <https://github.com/llvm/llvm-project/issues/96432>
62+
"mips64" | "mips64r6" => (true, false),
63+
// `f128` crashes <https://github.com/llvm/llvm-project/issues/101545>
64+
"powerpc64" if &target.os == "aix" => (true, false),
65+
// `f128` crashes <https://github.com/llvm/llvm-project/issues/41838>
66+
"sparc" | "sparcv9" => (true, false),
67+
// `f16` miscompiles <https://github.com/llvm/llvm-project/issues/96438>
68+
"wasm32" | "wasm64" => (false, true),
69+
// Most everything else works as of LLVM 19
70+
_ => (true, true),
71+
};
72+
73+
// If the feature is set, disable these types.
74+
let disable_both = env::var_os("CARGO_FEATURE_NO_F16_F128").is_some();
75+
76+
println!("cargo::rustc-check-cfg=cfg(f16_enabled)");
77+
println!("cargo::rustc-check-cfg=cfg(f128_enabled)");
78+
79+
if f16_ok && !disable_both {
80+
println!("cargo::rustc-cfg=f16_enabled");
81+
}
82+
83+
if f128_ok && !disable_both {
84+
println!("cargo::rustc-cfg=f128_enabled");
85+
}
86+
}

testcrate/benches/float_add.rs

+15-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
#![feature(f128)]
1+
#![cfg_attr(f128_enabled, feature(f128))]
22

33
use compiler_builtins::float::add;
4-
use criterion::{criterion_group, criterion_main, Criterion};
4+
use criterion::{criterion_main, Criterion};
55
use testcrate::float_bench;
66

77
float_bench! {
@@ -66,6 +66,7 @@ float_bench! {
6666
],
6767
}
6868

69+
#[cfg(f128_enabled)]
6970
float_bench! {
7071
name: add_f128,
7172
sig: (a: f128, b: f128) -> f128,
@@ -77,5 +78,16 @@ float_bench! {
7778
asm: []
7879
}
7980

80-
criterion_group!(float_add, add_f32, add_f64, add_f128);
81+
pub fn float_add() {
82+
let mut criterion = Criterion::default().configure_from_args();
83+
84+
add_f32(&mut criterion);
85+
add_f64(&mut criterion);
86+
87+
#[cfg(f128_enabled)]
88+
{
89+
add_f128(&mut criterion);
90+
}
91+
}
92+
8193
criterion_main!(float_add);

testcrate/benches/float_cmp.rs

+17-11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
#![feature(f128)]
1+
#![cfg_attr(f128_enabled, feature(f128))]
22

3-
use criterion::{criterion_group, criterion_main, Criterion};
3+
use criterion::{criterion_main, Criterion};
44
use testcrate::float_bench;
55

66
use compiler_builtins::float::cmp;
@@ -190,13 +190,19 @@ float_bench! {
190190
asm: []
191191
}
192192

193-
criterion_group!(
194-
float_cmp,
195-
cmp_f32_gt,
196-
cmp_f32_unord,
197-
cmp_f64_gt,
198-
cmp_f64_unord,
199-
cmp_f128_gt,
200-
cmp_f128_unord
201-
);
193+
pub fn float_cmp() {
194+
let mut criterion = Criterion::default().configure_from_args();
195+
196+
cmp_f32_gt(&mut criterion);
197+
cmp_f32_unord(&mut criterion);
198+
cmp_f64_gt(&mut criterion);
199+
cmp_f64_unord(&mut criterion);
200+
201+
#[cfg(f128_enabled)]
202+
{
203+
cmp_f128_gt(&mut criterion);
204+
cmp_f128_unord(&mut criterion);
205+
}
206+
}
207+
202208
criterion_main!(float_cmp);

testcrate/benches/float_conv.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
#![feature(f128)]
21
#![allow(improper_ctypes)]
32

43
use compiler_builtins::float::conv;

testcrate/benches/float_div.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#![feature(f128)]
2-
31
use compiler_builtins::float::div;
42
use criterion::{criterion_group, criterion_main, Criterion};
53
use testcrate::float_bench;

testcrate/benches/float_extend.rs

+29-20
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
#![allow(unused_variables)] // "unused" f16 registers
2-
#![feature(f128)]
3-
#![feature(f16)]
2+
#![cfg_attr(f128_enabled, feature(f128))]
3+
#![cfg_attr(f16_enabled, feature(f16))]
44

55
use compiler_builtins::float::extend;
6-
use criterion::{criterion_group, criterion_main, Criterion};
6+
use criterion::{criterion_main, Criterion};
77
use testcrate::float_bench;
88

9+
#[cfg(f16_enabled)]
910
float_bench! {
1011
name: extend_f16_f32,
1112
sig: (a: f16) -> f32,
@@ -28,6 +29,7 @@ float_bench! {
2829
],
2930
}
3031

32+
#[cfg(all(f16_enabled, f128_enabled))]
3133
float_bench! {
3234
name: extend_f16_f128,
3335
sig: (a: f16) -> f128,
@@ -60,6 +62,7 @@ float_bench! {
6062
],
6163
}
6264

65+
#[cfg(f128_enabled)]
6366
float_bench! {
6467
name: extend_f32_f128,
6568
sig: (a: f32) -> f128,
@@ -71,6 +74,7 @@ float_bench! {
7174
asm: [],
7275
}
7376

77+
#[cfg(f128_enabled)]
7478
float_bench! {
7579
name: extend_f64_f128,
7680
sig: (a: f64) -> f128,
@@ -82,23 +86,28 @@ float_bench! {
8286
asm: [],
8387
}
8488

85-
#[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))]
86-
criterion_group!(
87-
float_extend,
88-
extend_f16_f32,
89-
extend_f16_f128,
90-
extend_f32_f64,
91-
extend_f32_f128,
92-
extend_f64_f128,
93-
);
89+
pub fn float_extend() {
90+
let mut criterion = Criterion::default().configure_from_args();
9491

95-
// FIXME(#655): `f16` tests disabled until we can bootstrap symbols
96-
#[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))]
97-
criterion_group!(
98-
float_extend,
99-
extend_f32_f64,
100-
extend_f32_f128,
101-
extend_f64_f128,
102-
);
92+
// FIXME(#655): `f16` tests disabled until we can bootstrap symbols
93+
#[cfg(f16_enabled)]
94+
#[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))]
95+
{
96+
extend_f16_f32(&mut criterion);
97+
98+
#[cfg(f128_enabled)]
99+
{
100+
extend_f16_f128(&mut criterion);
101+
}
102+
}
103+
104+
extend_f32_f64(&mut criterion);
105+
106+
#[cfg(f128_enabled)]
107+
{
108+
extend_f32_f128(&mut criterion);
109+
extend_f64_f128(&mut criterion);
110+
}
111+
}
103112

104113
criterion_main!(float_extend);

testcrate/benches/float_mul.rs

+15-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
#![feature(f128)]
1+
#![cfg_attr(f128_enabled, feature(f128))]
22

33
use compiler_builtins::float::mul;
4-
use criterion::{criterion_group, criterion_main, Criterion};
4+
use criterion::{criterion_main, Criterion};
55
use testcrate::float_bench;
66

77
float_bench! {
@@ -66,6 +66,7 @@ float_bench! {
6666
],
6767
}
6868

69+
#[cfg(f128_enabled)]
6970
float_bench! {
7071
name: mul_f128,
7172
sig: (a: f128, b: f128) -> f128,
@@ -77,5 +78,16 @@ float_bench! {
7778
asm: []
7879
}
7980

80-
criterion_group!(float_mul, mul_f32, mul_f64, mul_f128);
81+
pub fn float_mul() {
82+
let mut criterion = Criterion::default().configure_from_args();
83+
84+
mul_f32(&mut criterion);
85+
mul_f64(&mut criterion);
86+
87+
#[cfg(f128_enabled)]
88+
{
89+
mul_f128(&mut criterion);
90+
}
91+
}
92+
8193
criterion_main!(float_mul);

0 commit comments

Comments
 (0)