Skip to content

Commit 2cae48c

Browse files
committed
Merge branch 'master' into windows-ci
2 parents c1564e3 + a121a80 commit 2cae48c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

105 files changed

+1368
-872
lines changed

.release-plz.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ publish_allow_dirty = true
77
[[package]]
88
name = "compiler_builtins"
99
semver_check = false
10+
changelog_include = ["libm"] # libm is included as part of builtins
1011

1112
[[package]]
1213
name = "libm"

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ members = [
66
"crates/libm-macros",
77
"crates/musl-math-sys",
88
"crates/panic-handler",
9+
"crates/symbol-check",
910
"crates/util",
1011
"libm",
1112
"libm-test",

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ This repository contains two main crates:
55
* `compiler-builtins`: symbols that the compiler expects to be available at
66
link time
77
* `libm`: a Rust implementation of C math libraries, used to provide
8-
implementations in `ocre`.
8+
implementations in `core`.
99

1010
More details are at [compiler-builtins/README.md](compiler-builtins/README.md)
1111
and [libm/README.md](libm/README.md).

builtins-test-intrinsics/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "builtins-test-intrinsics"
33
version = "0.1.0"
4-
edition = "2021"
4+
edition = "2024"
55
publish = false
66
license = "MIT OR Apache-2.0"
77

builtins-test-intrinsics/src/main.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,14 @@
1313
#![no_std]
1414
#![no_main]
1515

16+
// Ensure this `compiler_builtins` gets used, rather than the version injected from the sysroot.
17+
extern crate compiler_builtins;
1618
extern crate panic_handler;
1719

20+
// SAFETY: no definitions, only used for linking
1821
#[cfg(all(not(thumb), not(windows), not(target_arch = "wasm32")))]
1922
#[link(name = "c")]
20-
extern "C" {}
23+
unsafe extern "C" {}
2124

2225
// Every function in this module maps will be lowered to an intrinsic by LLVM, if the platform
2326
// doesn't have native support for the operation used in the function. ARM has a naming convention
@@ -651,22 +654,23 @@ fn something_with_a_dtor(f: &dyn Fn()) {
651654

652655
#[unsafe(no_mangle)]
653656
#[cfg(not(thumb))]
654-
fn main(_argc: core::ffi::c_int, _argv: *const *const u8) -> core::ffi::c_int {
657+
extern "C" fn main(_argc: core::ffi::c_int, _argv: *const *const u8) -> core::ffi::c_int {
655658
run();
656659
0
657660
}
658661

659662
#[unsafe(no_mangle)]
660663
#[cfg(thumb)]
661-
pub fn _start() -> ! {
664+
extern "C" fn _start() -> ! {
662665
run();
663666
loop {}
664667
}
665668

669+
// SAFETY: no definitions, only used for linking
666670
#[cfg(windows)]
667671
#[link(name = "kernel32")]
668672
#[link(name = "msvcrt")]
669-
extern "C" {}
673+
unsafe extern "C" {}
670674

671675
// ARM targets need these symbols
672676
#[unsafe(no_mangle)]

builtins-test/benches/float_cmp.rs

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,38 @@
11
#![cfg_attr(f128_enabled, feature(f128))]
22

33
use builtins_test::float_bench;
4-
use compiler_builtins::float::cmp;
4+
use compiler_builtins::float::cmp::{self, CmpResult};
55
use criterion::{Criterion, criterion_main};
66

77
/// `gt` symbols are allowed to return differing results, they just get compared
88
/// to 0.
9-
fn gt_res_eq(a: i32, b: i32) -> bool {
9+
fn gt_res_eq(mut a: CmpResult, mut b: CmpResult) -> bool {
10+
// FIXME: Our CmpResult used to be `i32`, but GCC/LLVM expect `isize`. on 64-bit platforms,
11+
// this means the top half of the word may be garbage if built with an old version of
12+
// `compiler-builtins`, so add a hack around this.
13+
//
14+
// This can be removed once a version of `compiler-builtins` with the return type fix makes
15+
// it upstream.
16+
if size_of::<CmpResult>() == 8 {
17+
a = a as i32 as CmpResult;
18+
b = b as i32 as CmpResult;
19+
}
20+
1021
let a_lt_0 = a <= 0;
1122
let b_lt_0 = b <= 0;
1223
(a_lt_0 && b_lt_0) || (!a_lt_0 && !b_lt_0)
1324
}
1425

1526
float_bench! {
1627
name: cmp_f32_gt,
17-
sig: (a: f32, b: f32) -> i32,
28+
sig: (a: f32, b: f32) -> CmpResult,
1829
crate_fn: cmp::__gtsf2,
1930
sys_fn: __gtsf2,
2031
sys_available: all(),
2132
output_eq: gt_res_eq,
2233
asm: [
2334
#[cfg(target_arch = "x86_64")] {
24-
let ret: i32;
35+
let ret: CmpResult;
2536
asm!(
2637
"xor {ret:e}, {ret:e}",
2738
"ucomiss {a}, {b}",
@@ -36,7 +47,7 @@ float_bench! {
3647
};
3748

3849
#[cfg(target_arch = "aarch64")] {
39-
let ret: i32;
50+
let ret: CmpResult;
4051
asm!(
4152
"fcmp {a:s}, {b:s}",
4253
"cset {ret:w}, gt",
@@ -53,13 +64,13 @@ float_bench! {
5364

5465
float_bench! {
5566
name: cmp_f32_unord,
56-
sig: (a: f32, b: f32) -> i32,
67+
sig: (a: f32, b: f32) -> CmpResult,
5768
crate_fn: cmp::__unordsf2,
5869
sys_fn: __unordsf2,
5970
sys_available: all(),
6071
asm: [
6172
#[cfg(target_arch = "x86_64")] {
62-
let ret: i32;
73+
let ret: CmpResult;
6374
asm!(
6475
"xor {ret:e}, {ret:e}",
6576
"ucomiss {a}, {b}",
@@ -74,7 +85,7 @@ float_bench! {
7485
};
7586

7687
#[cfg(target_arch = "aarch64")] {
77-
let ret: i32;
88+
let ret: CmpResult;
7889
asm!(
7990
"fcmp {a:s}, {b:s}",
8091
"cset {ret:w}, vs",
@@ -91,14 +102,14 @@ float_bench! {
91102

92103
float_bench! {
93104
name: cmp_f64_gt,
94-
sig: (a: f64, b: f64) -> i32,
105+
sig: (a: f64, b: f64) -> CmpResult,
95106
crate_fn: cmp::__gtdf2,
96107
sys_fn: __gtdf2,
97108
sys_available: all(),
98109
output_eq: gt_res_eq,
99110
asm: [
100111
#[cfg(target_arch = "x86_64")] {
101-
let ret: i32;
112+
let ret: CmpResult;
102113
asm!(
103114
"xor {ret:e}, {ret:e}",
104115
"ucomisd {a}, {b}",
@@ -113,7 +124,7 @@ float_bench! {
113124
};
114125

115126
#[cfg(target_arch = "aarch64")] {
116-
let ret: i32;
127+
let ret: CmpResult;
117128
asm!(
118129
"fcmp {a:d}, {b:d}",
119130
"cset {ret:w}, gt",
@@ -130,13 +141,13 @@ float_bench! {
130141

131142
float_bench! {
132143
name: cmp_f64_unord,
133-
sig: (a: f64, b: f64) -> i32,
144+
sig: (a: f64, b: f64) -> CmpResult,
134145
crate_fn: cmp::__unorddf2,
135146
sys_fn: __unorddf2,
136147
sys_available: all(),
137148
asm: [
138149
#[cfg(target_arch = "x86_64")] {
139-
let ret: i32;
150+
let ret: CmpResult;
140151
asm!(
141152
"xor {ret:e}, {ret:e}",
142153
"ucomisd {a}, {b}",
@@ -151,7 +162,7 @@ float_bench! {
151162
};
152163

153164
#[cfg(target_arch = "aarch64")] {
154-
let ret: i32;
165+
let ret: CmpResult;
155166
asm!(
156167
"fcmp {a:d}, {b:d}",
157168
"cset {ret:w}, vs",
@@ -168,7 +179,7 @@ float_bench! {
168179

169180
float_bench! {
170181
name: cmp_f128_gt,
171-
sig: (a: f128, b: f128) -> i32,
182+
sig: (a: f128, b: f128) -> CmpResult,
172183
crate_fn: cmp::__gttf2,
173184
crate_fn_ppc: cmp::__gtkf2,
174185
sys_fn: __gttf2,
@@ -180,7 +191,7 @@ float_bench! {
180191

181192
float_bench! {
182193
name: cmp_f128_unord,
183-
sig: (a: f128, b: f128) -> i32,
194+
sig: (a: f128, b: f128) -> CmpResult,
184195
crate_fn: cmp::__unordtf2,
185196
crate_fn_ppc: cmp::__unordkf2,
186197
sys_fn: __unordtf2,

builtins-test/src/bench.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -358,8 +358,8 @@ impl_testio!(float f16);
358358
impl_testio!(float f32, f64);
359359
#[cfg(f128_enabled)]
360360
impl_testio!(float f128);
361-
impl_testio!(int i16, i32, i64, i128);
362-
impl_testio!(int u16, u32, u64, u128);
361+
impl_testio!(int i8, i16, i32, i64, i128, isize);
362+
impl_testio!(int u8, u16, u32, u64, u128, usize);
363363
impl_testio!((float, int)(f32, i32));
364364
impl_testio!((float, int)(f64, i32));
365365
#[cfg(f128_enabled)]

builtins-test/src/lib.rs

Lines changed: 73 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,75 @@ pub const N: u32 = if cfg!(target_arch = "x86_64") && !cfg!(debug_assertions) {
4040
10_000
4141
};
4242

43+
/// Additional constants that determine how the integer gets fuzzed.
44+
trait FuzzInt: MinInt {
45+
/// LUT used for maximizing the space covered and minimizing the computational cost of fuzzing
46+
/// in `builtins-test`. For example, Self = u128 produces [0,1,2,7,8,15,16,31,32,63,64,95,96,
47+
/// 111,112,119,120,125,126,127].
48+
const FUZZ_LENGTHS: [u8; 20] = make_fuzz_lengths(Self::BITS);
49+
50+
/// The number of entries of `FUZZ_LENGTHS` actually used. The maximum is 20 for u128.
51+
const FUZZ_NUM: usize = {
52+
let log2 = Self::BITS.ilog2() as usize;
53+
if log2 == 3 {
54+
// case for u8
55+
6
56+
} else {
57+
// 3 entries on each extreme, 2 in the middle, and 4 for each scale of intermediate
58+
// boundaries.
59+
8 + (4 * (log2 - 4))
60+
}
61+
};
62+
}
63+
64+
impl<I> FuzzInt for I where I: MinInt {}
65+
66+
const fn make_fuzz_lengths(bits: u32) -> [u8; 20] {
67+
let mut v = [0u8; 20];
68+
v[0] = 0;
69+
v[1] = 1;
70+
v[2] = 2; // important for parity and the iX::MIN case when reversed
71+
let mut i = 3;
72+
73+
// No need for any more until the byte boundary, because there should be no algorithms
74+
// that are sensitive to anything not next to byte boundaries after 2. We also scale
75+
// in powers of two, which is important to prevent u128 corner tests from getting too
76+
// big.
77+
let mut l = 8;
78+
loop {
79+
if l >= ((bits / 2) as u8) {
80+
break;
81+
}
82+
// get both sides of the byte boundary
83+
v[i] = l - 1;
84+
i += 1;
85+
v[i] = l;
86+
i += 1;
87+
l *= 2;
88+
}
89+
90+
if bits != 8 {
91+
// add the lower side of the middle boundary
92+
v[i] = ((bits / 2) - 1) as u8;
93+
i += 1;
94+
}
95+
96+
// We do not want to jump directly from the Self::BITS/2 boundary to the Self::BITS
97+
// boundary because of algorithms that split the high part up. We reverse the scaling
98+
// as we go to Self::BITS.
99+
let mid = i;
100+
let mut j = 1;
101+
loop {
102+
v[i] = (bits as u8) - (v[mid - j]) - 1;
103+
if j == mid {
104+
break;
105+
}
106+
i += 1;
107+
j += 1;
108+
}
109+
v
110+
}
111+
43112
/// Random fuzzing step. When run several times, it results in excellent fuzzing entropy such as:
44113
/// 11110101010101011110111110011111
45114
/// 10110101010100001011101011001010
@@ -92,10 +161,9 @@ fn fuzz_step<I: Int>(rng: &mut Xoshiro128StarStar, x: &mut I) {
92161
macro_rules! edge_cases {
93162
($I:ident, $case:ident, $inner:block) => {
94163
for i0 in 0..$I::FUZZ_NUM {
95-
let mask_lo = (!$I::UnsignedInt::ZERO).wrapping_shr($I::FUZZ_LENGTHS[i0] as u32);
164+
let mask_lo = (!$I::Unsigned::ZERO).wrapping_shr($I::FUZZ_LENGTHS[i0] as u32);
96165
for i1 in i0..I::FUZZ_NUM {
97-
let mask_hi =
98-
(!$I::UnsignedInt::ZERO).wrapping_shl($I::FUZZ_LENGTHS[i1 - i0] as u32);
166+
let mask_hi = (!$I::Unsigned::ZERO).wrapping_shl($I::FUZZ_LENGTHS[i1 - i0] as u32);
99167
let $case = I::from_unsigned(mask_lo & mask_hi);
100168
$inner
101169
}
@@ -107,7 +175,7 @@ macro_rules! edge_cases {
107175
/// edge cases, followed by a more random fuzzer that runs `n` times.
108176
pub fn fuzz<I: Int, F: FnMut(I)>(n: u32, mut f: F)
109177
where
110-
<I as MinInt>::UnsignedInt: Int,
178+
<I as MinInt>::Unsigned: Int,
111179
{
112180
// edge case tester. Calls `f` 210 times for u128.
113181
// zero gets skipped by the loop
@@ -128,7 +196,7 @@ where
128196
/// The same as `fuzz`, except `f` has two inputs.
129197
pub fn fuzz_2<I: Int, F: Fn(I, I)>(n: u32, f: F)
130198
where
131-
<I as MinInt>::UnsignedInt: Int,
199+
<I as MinInt>::Unsigned: Int,
132200
{
133201
// Check cases where the first and second inputs are zero. Both call `f` 210 times for `u128`.
134202
edge_cases!(I, case, {

builtins-test/tests/aeabi_memclr.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ macro_rules! panic {
2424
};
2525
}
2626

27-
extern "C" {
27+
// SAFETY: defined in compiler-builtins
28+
unsafe extern "aapcs" {
2829
fn __aeabi_memclr4(dest: *mut u8, n: usize);
2930
fn __aeabi_memset4(dest: *mut u8, n: usize, c: u32);
3031
}

builtins-test/tests/aeabi_memcpy.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ macro_rules! panic {
2222
};
2323
}
2424

25-
extern "C" {
25+
// SAFETY: defined in compiler-builtins
26+
unsafe extern "aapcs" {
2627
fn __aeabi_memcpy(dest: *mut u8, src: *const u8, n: usize);
2728
fn __aeabi_memcpy4(dest: *mut u8, src: *const u8, n: usize);
2829
}

0 commit comments

Comments
 (0)