From 35270f855720c700b9b064d0c07e2edcd0d5ad60 Mon Sep 17 00:00:00 2001 From: The rustc-josh-sync Cronjob Bot Date: Thu, 4 Sep 2025 04:07:46 +0000 Subject: [PATCH 01/12] Prepare for merging from rust-lang/rust This updates the rust-version file to 9385c64c95d971329e62917adc4349c8ccdbafe0. --- library/compiler-builtins/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/compiler-builtins/rust-version b/library/compiler-builtins/rust-version index 8489eacfcda2..7420b6200967 100644 --- a/library/compiler-builtins/rust-version +++ b/library/compiler-builtins/rust-version @@ -1 +1 @@ -d36f964125163c2e698de5559efefb8217b8b7f0 +9385c64c95d971329e62917adc4349c8ccdbafe0 From 04909ba40ab9bb7982c6009a21fb3b500c04c41b Mon Sep 17 00:00:00 2001 From: quaternic <57393910+quaternic@users.noreply.github.com> Date: Fri, 5 Sep 2025 12:54:37 +0300 Subject: [PATCH 02/12] libm: define and implement `trait NarrowingDiv` for unsigned integer division New utility in `libm::support`: - `trait NarrowingDiv` for dividing `u2N / uN` when the quotient fits in `uN` - a reasonable implementation of that for primitives up to `u256 / u128` This is the inverse operation of unsigned widening multiplication: let xy: u256 = u128::widen_mul(x, y); assert_eq!(xy.checked_narrowing_div_rem(y), Some((x, 0))); // unless y == 0 The trait API is based on x86's `div`-instruction: quotient overflow happens exactly when the high half of the dividend is greater or equal to the divisor, which includes division by zero. --- .../libm-test/benches/icount.rs | 13 +- .../libm/src/math/support/big/tests.rs | 26 +++ .../libm/src/math/support/int_traits.rs | 3 + .../math/support/int_traits/narrowing_div.rs | 176 ++++++++++++++++++ .../libm/src/math/support/mod.rs | 3 +- 5 files changed, 219 insertions(+), 2 deletions(-) create mode 100644 library/compiler-builtins/libm/src/math/support/int_traits/narrowing_div.rs diff --git a/library/compiler-builtins/libm-test/benches/icount.rs b/library/compiler-builtins/libm-test/benches/icount.rs index 02ee13f804f1..0b85771225dd 100644 --- a/library/compiler-builtins/libm-test/benches/icount.rs +++ b/library/compiler-builtins/libm-test/benches/icount.rs @@ -111,6 +111,17 @@ fn icount_bench_u128_widen_mul(cases: Vec<(u128, u128)>) { } } +#[library_benchmark] +#[bench::linspace(setup_u128_mul())] +fn icount_bench_u256_narrowing_div(cases: Vec<(u128, u128)>) { + use libm::support::NarrowingDiv; + for (x, y) in cases.iter().copied() { + let x = black_box(x.widen_hi()); + let y = black_box(y); + black_box(x.checked_narrowing_div_rem(y)); + } +} + #[library_benchmark] #[bench::linspace(setup_u256_add())] fn icount_bench_u256_add(cases: Vec<(u256, u256)>) { @@ -145,7 +156,7 @@ fn icount_bench_u256_shr(cases: Vec<(u256, u32)>) { library_benchmark_group!( name = icount_bench_u128_group; - benchmarks = icount_bench_u128_widen_mul, icount_bench_u256_add, icount_bench_u256_sub, icount_bench_u256_shl, icount_bench_u256_shr + benchmarks = icount_bench_u128_widen_mul, icount_bench_u256_narrowing_div, icount_bench_u256_add, icount_bench_u256_sub, icount_bench_u256_shl, icount_bench_u256_shr ); #[library_benchmark] diff --git a/library/compiler-builtins/libm/src/math/support/big/tests.rs b/library/compiler-builtins/libm/src/math/support/big/tests.rs index d54706c72607..0c32f445c136 100644 --- a/library/compiler-builtins/libm/src/math/support/big/tests.rs +++ b/library/compiler-builtins/libm/src/math/support/big/tests.rs @@ -3,6 +3,7 @@ use std::string::String; use std::{eprintln, format}; use super::{HInt, MinInt, i256, u256}; +use crate::support::{Int as _, NarrowingDiv}; const LOHI_SPLIT: u128 = 0xaaaaaaaaaaaaaaaaffffffffffffffff; @@ -336,3 +337,28 @@ fn i256_shifts() { x = y; } } +#[test] +fn div_u256_by_u128() { + for j in i8::MIN..=i8::MAX { + let y: u128 = (j as i128).rotate_right(4).unsigned(); + if y == 0 { + continue; + } + for i in i8::MIN..=i8::MAX { + let x: u128 = (i as i128).rotate_right(4).unsigned(); + let xy = x.widen_mul(y); + assert_eq!(xy.checked_narrowing_div_rem(y), Some((x, 0))); + if y != 1 { + assert_eq!((xy + u256::ONE).checked_narrowing_div_rem(y), Some((x, 1))); + } + if x != 0 { + assert_eq!( + (xy - u256::ONE).checked_narrowing_div_rem(y), + Some((x - 1, y - 1)) + ); + } + let r = ((y as f64) * 0.12345) as u128; + assert_eq!((xy + r.widen()).checked_narrowing_div_rem(y), Some((x, r))); + } + } +} diff --git a/library/compiler-builtins/libm/src/math/support/int_traits.rs b/library/compiler-builtins/libm/src/math/support/int_traits.rs index 9d8826dfed3f..f1aa1e5b9b4d 100644 --- a/library/compiler-builtins/libm/src/math/support/int_traits.rs +++ b/library/compiler-builtins/libm/src/math/support/int_traits.rs @@ -1,5 +1,8 @@ use core::{cmp, fmt, ops}; +mod narrowing_div; +pub use narrowing_div::NarrowingDiv; + /// Minimal integer implementations needed on all integer types, including wide integers. #[allow(dead_code)] // Some constants are only used with tests pub trait MinInt: diff --git a/library/compiler-builtins/libm/src/math/support/int_traits/narrowing_div.rs b/library/compiler-builtins/libm/src/math/support/int_traits/narrowing_div.rs new file mode 100644 index 000000000000..3da0843cc540 --- /dev/null +++ b/library/compiler-builtins/libm/src/math/support/int_traits/narrowing_div.rs @@ -0,0 +1,176 @@ +/* SPDX-License-Identifier: MIT OR Apache-2.0 */ +use crate::support::{CastInto, DInt, HInt, Int, MinInt, u256}; + +/// Trait for unsigned division of a double-wide integer +/// when the quotient doesn't overflow. +/// +/// This is the inverse of widening multiplication: +/// - for any `x` and nonzero `y`: `x.widen_mul(y).checked_narrowing_div_rem(y) == Some((x, 0))`, +/// - and for any `r in 0..y`: `x.carrying_mul(y, r).checked_narrowing_div_rem(y) == Some((x, r))`, +#[allow(dead_code)] +pub trait NarrowingDiv: DInt + MinInt { + /// Computes `(self / n, self % n))` + /// + /// # Safety + /// The caller must ensure that `self.hi() < n`, or equivalently, + /// that the quotient does not overflow. + unsafe fn unchecked_narrowing_div_rem(self, n: Self::H) -> (Self::H, Self::H); + + /// Returns `Some((self / n, self % n))` when `self.hi() < n`. + fn checked_narrowing_div_rem(self, n: Self::H) -> Option<(Self::H, Self::H)> { + if self.hi() < n { + Some(unsafe { self.unchecked_narrowing_div_rem(n) }) + } else { + None + } + } +} + +// For primitive types we can just use the standard +// division operators in the double-wide type. +macro_rules! impl_narrowing_div_primitive { + ($D:ident) => { + impl NarrowingDiv for $D { + unsafe fn unchecked_narrowing_div_rem(self, n: Self::H) -> (Self::H, Self::H) { + if self.hi() >= n { + unsafe { core::hint::unreachable_unchecked() } + } + ((self / n.widen()).cast(), (self % n.widen()).cast()) + } + } + }; +} + +// Extend division from `u2N / uN` to `u4N / u2N` +// This is not the most efficient algorithm, but it is +// relatively simple. +macro_rules! impl_narrowing_div_recurse { + ($D:ident) => { + impl NarrowingDiv for $D { + unsafe fn unchecked_narrowing_div_rem(self, n: Self::H) -> (Self::H, Self::H) { + if self.hi() >= n { + unsafe { core::hint::unreachable_unchecked() } + } + + // Normalize the divisor by shifting the most significant one + // to the leading position. `n != 0` is implied by `self.hi() < n` + let lz = n.leading_zeros(); + let a = self << lz; + let b = n << lz; + + let ah = a.hi(); + let (a0, a1) = a.lo().lo_hi(); + // SAFETY: For both calls, `b.leading_zeros() == 0` by the above shift. + // SAFETY: `ah < b` follows from `self.hi() < n` + let (q1, r) = unsafe { div_three_digits_by_two(a1, ah, b) }; + // SAFETY: `r < b` is given as the postcondition of the previous call + let (q0, r) = unsafe { div_three_digits_by_two(a0, r, b) }; + + // Undo the earlier normalization for the remainder + (Self::H::from_lo_hi(q0, q1), r >> lz) + } + } + }; +} + +impl_narrowing_div_primitive!(u16); +impl_narrowing_div_primitive!(u32); +impl_narrowing_div_primitive!(u64); +impl_narrowing_div_primitive!(u128); +impl_narrowing_div_recurse!(u256); + +/// Implement `u3N / u2N`-division on top of `u2N / uN`-division. +/// +/// Returns the quotient and remainder of `(a * R + a0) / n`, +/// where `R = (1 << U::BITS)` is the digit size. +/// +/// # Safety +/// Requires that `n.leading_zeros() == 0` and `a < n`. +unsafe fn div_three_digits_by_two(a0: U, a: U::D, n: U::D) -> (U, U::D) +where + U: HInt, + U::D: Int + NarrowingDiv, +{ + if n.leading_zeros() > 0 || a >= n { + unsafe { core::hint::unreachable_unchecked() } + } + + // n = n1R + n0 + let (n0, n1) = n.lo_hi(); + // a = a2R + a1 + let (a1, a2) = a.lo_hi(); + + let mut q; + let mut r; + let mut wrap; + // `a < n` is guaranteed by the caller, but `a2 == n1 && a1 < n0` is possible + if let Some((q0, r1)) = a.checked_narrowing_div_rem(n1) { + q = q0; + // a = qn1 + r1, where 0 <= r1 < n1 + + // Include the remainder with the low bits: + // r = a0 + r1R + r = U::D::from_lo_hi(a0, r1); + + // Subtract the contribution of the divisor low bits with the estimated quotient + let d = q.widen_mul(n0); + (r, wrap) = r.overflowing_sub(d); + + // Since `q` is the quotient of dividing with a slightly smaller divisor, + // it may be an overapproximation, but is never too small, and similarly, + // `r` is now either the correct remainder ... + if !wrap { + return (q, r); + } + // ... or the remainder went "negative" (by as much as `d = qn0 < RR`) + // and we have to adjust. + q -= U::ONE; + } else { + debug_assert!(a2 == n1 && a1 < n0); + // Otherwise, `a2 == n1`, and the estimated quotient would be + // `R + (a1 % n1)`, but the correct quotient can't overflow. + // We'll start from `q = R = (1 << U::BITS)`, + // so `r = aR + a0 - qn = (a - n)R + a0` + r = U::D::from_lo_hi(a0, a1.wrapping_sub(n0)); + // Since `a < n`, the first decrement is always needed: + q = U::MAX; /* R - 1 */ + } + + (r, wrap) = r.overflowing_add(n); + if wrap { + return (q, r); + } + + // If the remainder still didn't wrap, we need another step. + q -= U::ONE; + (r, wrap) = r.overflowing_add(n); + // Since `n >= RR/2`, at least one of the two `r += n` must have wrapped. + debug_assert!(wrap, "estimated quotient should be off by at most two"); + (q, r) +} + +#[cfg(test)] +mod test { + use super::{HInt, NarrowingDiv}; + + #[test] + fn inverse_mul() { + for x in 0..=u8::MAX { + for y in 1..=u8::MAX { + let xy = x.widen_mul(y); + assert_eq!(xy.checked_narrowing_div_rem(y), Some((x, 0))); + assert_eq!( + (xy + (y - 1) as u16).checked_narrowing_div_rem(y), + Some((x, y - 1)) + ); + if y > 1 { + assert_eq!((xy + 1).checked_narrowing_div_rem(y), Some((x, 1))); + assert_eq!( + (xy + (y - 2) as u16).checked_narrowing_div_rem(y), + Some((x, y - 2)) + ); + } + } + } + } +} diff --git a/library/compiler-builtins/libm/src/math/support/mod.rs b/library/compiler-builtins/libm/src/math/support/mod.rs index b2d7bd8d5567..7b529eb760b7 100644 --- a/library/compiler-builtins/libm/src/math/support/mod.rs +++ b/library/compiler-builtins/libm/src/math/support/mod.rs @@ -28,7 +28,8 @@ pub use hex_float::hf16; pub use hex_float::hf128; #[allow(unused_imports)] pub use hex_float::{hf32, hf64}; -pub use int_traits::{CastFrom, CastInto, DInt, HInt, Int, MinInt}; +#[allow(unused_imports)] +pub use int_traits::{CastFrom, CastInto, DInt, HInt, Int, MinInt, NarrowingDiv}; /// Hint to the compiler that the current path is cold. pub fn cold_path() { From 641fc3f0926672c670be847f93152ef65402af4b Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Fri, 30 May 2025 02:01:41 +0000 Subject: [PATCH 03/12] symcheck: Allow checking a standalone archive Provide an option to check without invoking Cargo first. --- .../crates/symbol-check/src/main.rs | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/library/compiler-builtins/crates/symbol-check/src/main.rs b/library/compiler-builtins/crates/symbol-check/src/main.rs index 4e94552331a0..3f45c77f006e 100644 --- a/library/compiler-builtins/crates/symbol-check/src/main.rs +++ b/library/compiler-builtins/crates/symbol-check/src/main.rs @@ -24,6 +24,10 @@ Cargo will get invoked with `CARGO_ARGS` and the specified target. All output `compiler_builtins*.rlib` files will be checked. If TARGET is not specified, the host target is used. + + check ARCHIVE_PATHS ... + +Run the same checks on the given set of paths, without invoking Cargo. "; fn main() { @@ -33,12 +37,14 @@ fn main() { match &args_ref[1..] { ["build-and-check", target, "--", args @ ..] if !args.is_empty() => { - check_cargo_args(args); run_build_and_check(target, args); } ["build-and-check", "--", args @ ..] if !args.is_empty() => { - check_cargo_args(args); - run_build_and_check(&host_target(), args); + let target = &host_target(); + run_build_and_check(target, args); + } + ["check", paths @ ..] if !paths.is_empty() => { + check_paths(paths); } _ => { println!("{USAGE}"); @@ -47,22 +53,25 @@ fn main() { } } -/// Make sure `--target` isn't passed to avoid confusion (since it should be proivded only once, -/// positionally). -fn check_cargo_args(args: &[&str]) { +fn run_build_and_check(target: &str, args: &[&str]) { + // Make sure `--target` isn't passed to avoid confusion (since it should be + // proivded only once, positionally). for arg in args { assert!( !arg.contains("--target"), "target must be passed positionally. {USAGE}" ); } + + let paths = exec_cargo_with_args(target, args); + check_paths(&paths); } -fn run_build_and_check(target: &str, args: &[&str]) { - let paths = exec_cargo_with_args(target, args); +fn check_paths>(paths: &[P]) { for path in paths { + let path = path.as_ref(); println!("Checking {}", path.display()); - let archive = Archive::from_path(&path); + let archive = Archive::from_path(path); verify_no_duplicates(&archive); verify_core_symbols(&archive); From b2aa2200aab4d77b73ea40374a7090886d80d7ec Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sun, 7 Sep 2025 04:42:44 -0400 Subject: [PATCH 04/12] symcheck: Support both archives and object files If parsing as an archive is unsuccessful, try parsing as an object instead before erroring out. --- .../crates/symbol-check/src/main.rs | 80 ++++++++++++------- 1 file changed, 53 insertions(+), 27 deletions(-) diff --git a/library/compiler-builtins/crates/symbol-check/src/main.rs b/library/compiler-builtins/crates/symbol-check/src/main.rs index 3f45c77f006e..7d0b7e90addb 100644 --- a/library/compiler-builtins/crates/symbol-check/src/main.rs +++ b/library/compiler-builtins/crates/symbol-check/src/main.rs @@ -7,9 +7,10 @@ use std::io::{BufRead, BufReader}; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; -use object::read::archive::{ArchiveFile, ArchiveMember}; +use object::read::archive::ArchiveFile; use object::{ - File as ObjFile, Object, ObjectSection, ObjectSymbol, Symbol, SymbolKind, SymbolScope, + File as ObjFile, Object, ObjectSection, ObjectSymbol, Result as ObjResult, Symbol, SymbolKind, + SymbolScope, }; use serde_json::Value; @@ -25,9 +26,10 @@ Cargo will get invoked with `CARGO_ARGS` and the specified target. All output If TARGET is not specified, the host target is used. - check ARCHIVE_PATHS ... + check PATHS ... -Run the same checks on the given set of paths, without invoking Cargo. +Run the same checks on the given set of paths, without invoking Cargo. Paths +may be either archives or object files. "; fn main() { @@ -71,7 +73,7 @@ fn check_paths>(paths: &[P]) { for path in paths { let path = path.as_ref(); println!("Checking {}", path.display()); - let archive = Archive::from_path(path); + let archive = BinFile::from_path(path); verify_no_duplicates(&archive); verify_core_symbols(&archive); @@ -174,7 +176,7 @@ struct SymInfo { } impl SymInfo { - fn new(sym: &Symbol, obj: &ObjFile, member: &ArchiveMember) -> Self { + fn new(sym: &Symbol, obj: &ObjFile, obj_path: &str) -> Self { // Include the section name if possible. Fall back to the `Section` debug impl if not. let section = sym.section(); let section_name = sym @@ -196,7 +198,7 @@ impl SymInfo { is_weak: sym.is_weak(), is_common: sym.is_common(), address: sym.address(), - object: String::from_utf8_lossy(member.name()).into_owned(), + object: obj_path.to_owned(), } } } @@ -206,7 +208,7 @@ impl SymInfo { /// Note that this will also locate cases where a symbol is weakly defined in more than one place. /// Technically there are no linker errors that will come from this, but it keeps our binary more /// straightforward and saves some distribution size. -fn verify_no_duplicates(archive: &Archive) { +fn verify_no_duplicates(archive: &BinFile) { let mut syms = BTreeMap::::new(); let mut dups = Vec::new(); let mut found_any = false; @@ -263,7 +265,7 @@ fn verify_no_duplicates(archive: &Archive) { } /// Ensure that there are no references to symbols from `core` that aren't also (somehow) defined. -fn verify_core_symbols(archive: &Archive) { +fn verify_core_symbols(archive: &BinFile) { let mut defined = BTreeSet::new(); let mut undefined = Vec::new(); let mut has_symbols = false; @@ -298,39 +300,63 @@ fn verify_core_symbols(archive: &Archive) { } /// Thin wrapper for owning data used by `object`. -struct Archive { +struct BinFile { + path: PathBuf, data: Vec, } -impl Archive { +impl BinFile { fn from_path(path: &Path) -> Self { Self { + path: path.to_owned(), data: fs::read(path).expect("reading file failed"), } } - fn file(&self) -> ArchiveFile<'_> { - ArchiveFile::parse(self.data.as_slice()).expect("archive parse failed") + fn as_archive_file(&self) -> ObjResult> { + ArchiveFile::parse(self.data.as_slice()) } - /// For a given archive, do something with each object file. - fn for_each_object(&self, mut f: impl FnMut(ObjFile, &ArchiveMember)) { - let archive = self.file(); + fn as_obj_file(&self) -> ObjResult> { + ObjFile::parse(self.data.as_slice()) + } - for member in archive.members() { - let member = member.expect("failed to access member"); - let obj_data = member - .data(self.data.as_slice()) - .expect("failed to access object"); - let obj = ObjFile::parse(obj_data).expect("failed to parse object"); - f(obj, &member); + /// For a given archive, do something with each object file. For an object file, do + /// something once. + fn for_each_object(&self, mut f: impl FnMut(ObjFile, &str)) { + // Try as an archive first. + let as_archive = self.as_archive_file(); + if let Ok(archive) = as_archive { + for member in archive.members() { + let member = member.expect("failed to access member"); + let obj_data = member + .data(self.data.as_slice()) + .expect("failed to access object"); + let obj = ObjFile::parse(obj_data).expect("failed to parse object"); + f(obj, &String::from_utf8_lossy(member.name())); + } + + return; } + + // Fall back to parsing as an object file. + let as_obj = self.as_obj_file(); + if let Ok(obj) = as_obj { + f(obj, &self.path.to_string_lossy()); + return; + } + + panic!( + "failed to parse as either archive or object file: {:?}, {:?}", + as_archive.unwrap_err(), + as_obj.unwrap_err(), + ); } - /// For a given archive, do something with each symbol. - fn for_each_symbol(&self, mut f: impl FnMut(Symbol, &ObjFile, &ArchiveMember)) { - self.for_each_object(|obj, member| { - obj.symbols().for_each(|sym| f(sym, &obj, member)); + /// D something with each symbol in an archive or object file. + fn for_each_symbol(&self, mut f: impl FnMut(Symbol, &ObjFile, &str)) { + self.for_each_object(|obj, obj_path| { + obj.symbols().for_each(|sym| f(sym, &obj, obj_path)); }); } } From 3220121a33fd49b676d18e82895ea4f0dac3a01c Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Thu, 11 Sep 2025 05:22:44 +0900 Subject: [PATCH 05/12] ci: Use nextest on PowerPC64LE and s390x See https://github.com/taiki-e/install-action/issues/1056 for the context. --- library/compiler-builtins/.github/workflows/main.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/library/compiler-builtins/.github/workflows/main.yaml b/library/compiler-builtins/.github/workflows/main.yaml index 3afadbfe8941..16f958c881d3 100644 --- a/library/compiler-builtins/.github/workflows/main.yaml +++ b/library/compiler-builtins/.github/workflows/main.yaml @@ -132,10 +132,7 @@ jobs: rustup default "$channel" rustup target add "${{ matrix.target }}" - # Our scripts use nextest if possible. This is skipped on the native ppc - # and s390x runners since install-action doesn't support them. - uses: taiki-e/install-action@nextest - if: "!(matrix.os == 'ubuntu-24.04-ppc64le' || matrix.os == 'ubuntu-24.04-s390x')" - uses: Swatinem/rust-cache@v2 with: From bc57021f09e3c3e92e6f4d75f6a4f1af6dca9f7d Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Sat, 13 Sep 2025 18:55:11 +0200 Subject: [PATCH 06/12] doc: Document that `os_version_check.c` is implemented in `std` Since https://github.com/rust-lang/rust/pull/138944. --- library/compiler-builtins/compiler-builtins/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/compiler-builtins/compiler-builtins/README.md b/library/compiler-builtins/compiler-builtins/README.md index 2d92b7651f98..a12bd2ee7349 100644 --- a/library/compiler-builtins/compiler-builtins/README.md +++ b/library/compiler-builtins/compiler-builtins/README.md @@ -374,7 +374,7 @@ Miscellaneous functionality that is not used by Rust. - ~~i386/fp_mode.c~~ - ~~int_util.c~~ - ~~loongarch/fp_mode.c~~ -- ~~os_version_check.c~~ +- ~~os_version_check.c~~ (implemented in `std` instead) - ~~riscv/fp_mode.c~~ - ~~riscv/restore.S~~ (callee-saved registers) - ~~riscv/save.S~~ (callee-saved registers) From ee1b36a2434dadd44d580aa4114d3c6c2eb6afd2 Mon Sep 17 00:00:00 2001 From: cyrgani <85427285+cyrgani@users.noreply.github.com> Date: Mon, 22 Sep 2025 20:51:08 +0200 Subject: [PATCH 07/12] Remove usage of the to-be-deprecated `core::f32`, `core::f64` items Needed for https://github.com/rust-lang/rust/pull/146882. --- .../libm-test/src/precision.rs | 2 -- .../compiler-builtins/libm/src/math/atan.rs | 20 +++++++++---------- .../compiler-builtins/libm/src/math/cbrtf.rs | 2 -- .../compiler-builtins/libm/src/math/expm1.rs | 2 -- .../compiler-builtins/libm/src/math/hypot.rs | 2 -- .../compiler-builtins/libm/src/math/hypotf.rs | 2 -- .../compiler-builtins/libm/src/math/log10.rs | 2 -- .../compiler-builtins/libm/src/math/log10f.rs | 2 -- .../compiler-builtins/libm/src/math/log1p.rs | 2 -- .../compiler-builtins/libm/src/math/log1pf.rs | 2 -- .../compiler-builtins/libm/src/math/log2.rs | 2 -- .../compiler-builtins/libm/src/math/log2f.rs | 2 -- .../libm/src/math/rem_pio2f.rs | 2 -- 13 files changed, 9 insertions(+), 35 deletions(-) diff --git a/library/compiler-builtins/libm-test/src/precision.rs b/library/compiler-builtins/libm-test/src/precision.rs index 3fb8c1b37109..c441922d302b 100644 --- a/library/compiler-builtins/libm-test/src/precision.rs +++ b/library/compiler-builtins/libm-test/src/precision.rs @@ -1,8 +1,6 @@ //! Configuration for skipping or changing the result for individual test cases (inputs) rather //! than ignoring entire tests. -use core::f32; - use CheckBasis::{Mpfr, Musl}; use libm::support::CastFrom; use {BaseName as Bn, Identifier as Id}; diff --git a/library/compiler-builtins/libm/src/math/atan.rs b/library/compiler-builtins/libm/src/math/atan.rs index 0590ba87cf85..a303ebd42f0d 100644 --- a/library/compiler-builtins/libm/src/math/atan.rs +++ b/library/compiler-builtins/libm/src/math/atan.rs @@ -29,8 +29,6 @@ * to produce the hexadecimal values shown. */ -use core::f64; - use super::fabs; const ATANHI: [f64; 4] = [ @@ -134,19 +132,19 @@ pub fn atan(x: f64) -> f64 { #[cfg(test)] mod tests { - use core::f64; + use core::f64::consts; use super::atan; #[test] fn sanity_check() { for (input, answer) in [ - (3.0_f64.sqrt() / 3.0, f64::consts::FRAC_PI_6), - (1.0, f64::consts::FRAC_PI_4), - (3.0_f64.sqrt(), f64::consts::FRAC_PI_3), - (-3.0_f64.sqrt() / 3.0, -f64::consts::FRAC_PI_6), - (-1.0, -f64::consts::FRAC_PI_4), - (-3.0_f64.sqrt(), -f64::consts::FRAC_PI_3), + (3.0_f64.sqrt() / 3.0, consts::FRAC_PI_6), + (1.0, consts::FRAC_PI_4), + (3.0_f64.sqrt(), consts::FRAC_PI_3), + (-3.0_f64.sqrt() / 3.0, -consts::FRAC_PI_6), + (-1.0, -consts::FRAC_PI_4), + (-3.0_f64.sqrt(), -consts::FRAC_PI_3), ] .iter() { @@ -167,12 +165,12 @@ mod tests { #[test] fn infinity() { - assert_eq!(atan(f64::INFINITY), f64::consts::FRAC_PI_2); + assert_eq!(atan(f64::INFINITY), consts::FRAC_PI_2); } #[test] fn minus_infinity() { - assert_eq!(atan(f64::NEG_INFINITY), -f64::consts::FRAC_PI_2); + assert_eq!(atan(f64::NEG_INFINITY), -consts::FRAC_PI_2); } #[test] diff --git a/library/compiler-builtins/libm/src/math/cbrtf.rs b/library/compiler-builtins/libm/src/math/cbrtf.rs index 9d69584834a3..6916ca6735b6 100644 --- a/library/compiler-builtins/libm/src/math/cbrtf.rs +++ b/library/compiler-builtins/libm/src/math/cbrtf.rs @@ -17,8 +17,6 @@ * Return cube root of x */ -use core::f32; - const B1: u32 = 709958130; /* B1 = (127-127.0/3-0.03306235651)*2**23 */ const B2: u32 = 642849266; /* B2 = (127-127.0/3-24/3-0.03306235651)*2**23 */ diff --git a/library/compiler-builtins/libm/src/math/expm1.rs b/library/compiler-builtins/libm/src/math/expm1.rs index 3714bf3afc93..3ce1d886bb19 100644 --- a/library/compiler-builtins/libm/src/math/expm1.rs +++ b/library/compiler-builtins/libm/src/math/expm1.rs @@ -10,8 +10,6 @@ * ==================================================== */ -use core::f64; - const O_THRESHOLD: f64 = 7.09782712893383973096e+02; /* 0x40862E42, 0xFEFA39EF */ const LN2_HI: f64 = 6.93147180369123816490e-01; /* 0x3fe62e42, 0xfee00000 */ const LN2_LO: f64 = 1.90821492927058770002e-10; /* 0x3dea39ef, 0x35793c76 */ diff --git a/library/compiler-builtins/libm/src/math/hypot.rs b/library/compiler-builtins/libm/src/math/hypot.rs index b92ee18ca110..c0b2a19370cd 100644 --- a/library/compiler-builtins/libm/src/math/hypot.rs +++ b/library/compiler-builtins/libm/src/math/hypot.rs @@ -1,5 +1,3 @@ -use core::f64; - use super::sqrt; const SPLIT: f64 = 134217728. + 1.; // 0x1p27 + 1 === (2 ^ 27) + 1 diff --git a/library/compiler-builtins/libm/src/math/hypotf.rs b/library/compiler-builtins/libm/src/math/hypotf.rs index e7635ffc9a0b..dfb36d4b23ed 100644 --- a/library/compiler-builtins/libm/src/math/hypotf.rs +++ b/library/compiler-builtins/libm/src/math/hypotf.rs @@ -1,5 +1,3 @@ -use core::f32; - use super::sqrtf; #[cfg_attr(assert_no_panic, no_panic::no_panic)] diff --git a/library/compiler-builtins/libm/src/math/log10.rs b/library/compiler-builtins/libm/src/math/log10.rs index 29f25d944af9..228c00a5b2ff 100644 --- a/library/compiler-builtins/libm/src/math/log10.rs +++ b/library/compiler-builtins/libm/src/math/log10.rs @@ -17,8 +17,6 @@ * log10(x) = (f - f*f/2 + r)/log(10) + k*log10(2) */ -use core::f64; - const IVLN10HI: f64 = 4.34294481878168880939e-01; /* 0x3fdbcb7b, 0x15200000 */ const IVLN10LO: f64 = 2.50829467116452752298e-11; /* 0x3dbb9438, 0xca9aadd5 */ const LOG10_2HI: f64 = 3.01029995663611771306e-01; /* 0x3FD34413, 0x509F6000 */ diff --git a/library/compiler-builtins/libm/src/math/log10f.rs b/library/compiler-builtins/libm/src/math/log10f.rs index f89584bf9c99..f72fcf9e1e27 100644 --- a/library/compiler-builtins/libm/src/math/log10f.rs +++ b/library/compiler-builtins/libm/src/math/log10f.rs @@ -13,8 +13,6 @@ * See comments in log10.c. */ -use core::f32; - const IVLN10HI: f32 = 4.3432617188e-01; /* 0x3ede6000 */ const IVLN10LO: f32 = -3.1689971365e-05; /* 0xb804ead9 */ const LOG10_2HI: f32 = 3.0102920532e-01; /* 0x3e9a2080 */ diff --git a/library/compiler-builtins/libm/src/math/log1p.rs b/library/compiler-builtins/libm/src/math/log1p.rs index c991cce60df0..c2f9eb89be60 100644 --- a/library/compiler-builtins/libm/src/math/log1p.rs +++ b/library/compiler-builtins/libm/src/math/log1p.rs @@ -53,8 +53,6 @@ * See HP-15C Advanced Functions Handbook, p.193. */ -use core::f64; - const LN2_HI: f64 = 6.93147180369123816490e-01; /* 3fe62e42 fee00000 */ const LN2_LO: f64 = 1.90821492927058770002e-10; /* 3dea39ef 35793c76 */ const LG1: f64 = 6.666666666666735130e-01; /* 3FE55555 55555593 */ diff --git a/library/compiler-builtins/libm/src/math/log1pf.rs b/library/compiler-builtins/libm/src/math/log1pf.rs index 89a92fac98ee..2e4775b8de90 100644 --- a/library/compiler-builtins/libm/src/math/log1pf.rs +++ b/library/compiler-builtins/libm/src/math/log1pf.rs @@ -10,8 +10,6 @@ * ==================================================== */ -use core::f32; - const LN2_HI: f32 = 6.9313812256e-01; /* 0x3f317180 */ const LN2_LO: f32 = 9.0580006145e-06; /* 0x3717f7d1 */ /* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */ diff --git a/library/compiler-builtins/libm/src/math/log2.rs b/library/compiler-builtins/libm/src/math/log2.rs index 9b750c9a2a6c..0f72fe0b84dc 100644 --- a/library/compiler-builtins/libm/src/math/log2.rs +++ b/library/compiler-builtins/libm/src/math/log2.rs @@ -17,8 +17,6 @@ * log2(x) = (f - f*f/2 + r)/log(2) + k */ -use core::f64; - const IVLN2HI: f64 = 1.44269504072144627571e+00; /* 0x3ff71547, 0x65200000 */ const IVLN2LO: f64 = 1.67517131648865118353e-10; /* 0x3de705fc, 0x2eefa200 */ const LG1: f64 = 6.666666666666735130e-01; /* 3FE55555 55555593 */ diff --git a/library/compiler-builtins/libm/src/math/log2f.rs b/library/compiler-builtins/libm/src/math/log2f.rs index 0e5177d7afa8..78673675a915 100644 --- a/library/compiler-builtins/libm/src/math/log2f.rs +++ b/library/compiler-builtins/libm/src/math/log2f.rs @@ -13,8 +13,6 @@ * See comments in log2.c. */ -use core::f32; - const IVLN2HI: f32 = 1.4428710938e+00; /* 0x3fb8b000 */ const IVLN2LO: f32 = -1.7605285393e-04; /* 0xb9389ad4 */ /* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */ diff --git a/library/compiler-builtins/libm/src/math/rem_pio2f.rs b/library/compiler-builtins/libm/src/math/rem_pio2f.rs index 0472a10355a0..481f7ee830bb 100644 --- a/library/compiler-builtins/libm/src/math/rem_pio2f.rs +++ b/library/compiler-builtins/libm/src/math/rem_pio2f.rs @@ -14,8 +14,6 @@ * ==================================================== */ -use core::f64; - use super::rem_pio2_large; const TOINT: f64 = 1.5 / f64::EPSILON; From a7cfc82b642019cf3b25e8c025d4a240809afa7a Mon Sep 17 00:00:00 2001 From: The rustc-josh-sync Cronjob Bot Date: Thu, 25 Sep 2025 04:12:30 +0000 Subject: [PATCH 08/12] Prepare for merging from rust-lang/rust This updates the rust-version file to caccb4d0368bd918ef6668af8e13834d07040417. --- library/compiler-builtins/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/compiler-builtins/rust-version b/library/compiler-builtins/rust-version index 7420b6200967..8854fb95997b 100644 --- a/library/compiler-builtins/rust-version +++ b/library/compiler-builtins/rust-version @@ -1 +1 @@ -9385c64c95d971329e62917adc4349c8ccdbafe0 +caccb4d0368bd918ef6668af8e13834d07040417 From 37be71b0451269ecb9a4477862e3ef08290b34fa Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Thu, 25 Sep 2025 19:58:00 +0000 Subject: [PATCH 09/12] Add back the `unsafe` for `intrinsics::fma` but `allow(unused_unsafe)` Rustc commit 055e05a338af / builtins commit 2fb3a1871bc9 ("Mark float intrinsics with no preconditions as safe") changed `fma` and other intrinsics to not be unsafe to call. Unfortunately we can't remove the `unsafe` just yet since the rustc we pin for benchmarks is older than this. Add back `unsafe` but allow it to be unused. --- .../compiler-builtins/libm/src/math/support/float_traits.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/library/compiler-builtins/libm/src/math/support/float_traits.rs b/library/compiler-builtins/libm/src/math/support/float_traits.rs index b5ee6413d553..4e5011f62e0f 100644 --- a/library/compiler-builtins/libm/src/math/support/float_traits.rs +++ b/library/compiler-builtins/libm/src/math/support/float_traits.rs @@ -289,7 +289,10 @@ macro_rules! float_impl { cfg_if! { // fma is not yet available in `core` if #[cfg(intrinsics_enabled)] { - core::intrinsics::$fma_intrinsic(self, y, z) + // FIXME(msrv,bench): once our benchmark rustc version is above the + // 2022-09-23 nightly, this can be removed. + #[allow(unused_unsafe)] + unsafe { core::intrinsics::$fma_intrinsic(self, y, z) } } else { super::super::$fma_fn(self, y, z) } From feb1b52180dff2b95f6b47d44679027ee0af0f78 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Wed, 22 Oct 2025 11:35:20 +0200 Subject: [PATCH 10/12] Compare against `CARGO_CFG_TARGET_FAMILY` in a multi-valued fashion `cfg(target_family = "...")` can be set multiple times, and thus `CARGO_CFG_TARGET_FAMILY` can also contain comma-separated values, similar to `CARGO_CFG_TARGET_FEATURE`. This allows `cargo build --target wasm32-unknown-emscripten -p musl-math-sys` to work, and will become more important if we were to add e.g. `cfg(target_family = "darwin")` in the future as discussed in https://github.com/rust-lang/rust/issues/100343. --- library/compiler-builtins/crates/musl-math-sys/build.rs | 9 ++++++--- library/compiler-builtins/libm/configure.rs | 7 +++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/library/compiler-builtins/crates/musl-math-sys/build.rs b/library/compiler-builtins/crates/musl-math-sys/build.rs index 59e42f2d2e67..3bab5f2eb112 100644 --- a/library/compiler-builtins/crates/musl-math-sys/build.rs +++ b/library/compiler-builtins/crates/musl-math-sys/build.rs @@ -46,7 +46,7 @@ fn main() { let cfg = Config::from_env(); if cfg.target_env == "msvc" - || cfg.target_family == "wasm" + || cfg.target_families.iter().any(|f| f == "wasm") || cfg.target_features.iter().any(|f| f == "thumb-mode") { println!( @@ -69,7 +69,7 @@ struct Config { musl_arch: String, target_arch: String, target_env: String, - target_family: String, + target_families: Vec, target_os: String, target_string: String, target_vendor: String, @@ -79,6 +79,9 @@ struct Config { impl Config { fn from_env() -> Self { let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()); + let target_families = env::var("CARGO_CFG_TARGET_FAMILY") + .map(|feats| feats.split(',').map(ToOwned::to_owned).collect()) + .unwrap_or_default(); let target_features = env::var("CARGO_CFG_TARGET_FEATURE") .map(|feats| feats.split(',').map(ToOwned::to_owned).collect()) .unwrap_or_default(); @@ -104,7 +107,7 @@ impl Config { musl_arch, target_arch, target_env: env::var("CARGO_CFG_TARGET_ENV").unwrap(), - target_family: env::var("CARGO_CFG_TARGET_FAMILY").unwrap(), + target_families, target_os: env::var("CARGO_CFG_TARGET_OS").unwrap(), target_string: env::var("TARGET").unwrap(), target_vendor: env::var("CARGO_CFG_TARGET_VENDOR").unwrap(), diff --git a/library/compiler-builtins/libm/configure.rs b/library/compiler-builtins/libm/configure.rs index 76186e636527..857a30229716 100644 --- a/library/compiler-builtins/libm/configure.rs +++ b/library/compiler-builtins/libm/configure.rs @@ -13,7 +13,7 @@ pub struct Config { pub target_triple: String, pub target_arch: String, pub target_env: String, - pub target_family: Option, + pub target_families: Vec, pub target_os: String, pub target_string: String, pub target_vendor: String, @@ -25,6 +25,9 @@ pub struct Config { impl Config { pub fn from_env() -> Self { let target_triple = env::var("TARGET").unwrap(); + let target_families = env::var("CARGO_CFG_TARGET_FAMILY") + .map(|feats| feats.split(',').map(ToOwned::to_owned).collect()) + .unwrap_or_default(); let target_features = env::var("CARGO_CFG_TARGET_FEATURE") .map(|feats| feats.split(',').map(ToOwned::to_owned).collect()) .unwrap_or_default(); @@ -41,7 +44,7 @@ impl Config { cargo_features, 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_families, target_os: env::var("CARGO_CFG_TARGET_OS").unwrap(), target_string: env::var("TARGET").unwrap(), target_vendor: env::var("CARGO_CFG_TARGET_VENDOR").unwrap(), From 93b5361202665c41970646569df4236751297094 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Tue, 2 Dec 2025 05:22:00 -0500 Subject: [PATCH 11/12] ci: Increase the benchmark rustc version to 2025-12-01 Zerocopy (an indirect test dependency) has started requiring recently-stabilized features, so upgrade our benchmark toolchain to match. --- library/compiler-builtins/.github/workflows/main.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/compiler-builtins/.github/workflows/main.yaml b/library/compiler-builtins/.github/workflows/main.yaml index 16f958c881d3..c8faecfcb2cc 100644 --- a/library/compiler-builtins/.github/workflows/main.yaml +++ b/library/compiler-builtins/.github/workflows/main.yaml @@ -13,7 +13,7 @@ env: RUSTDOCFLAGS: -Dwarnings RUSTFLAGS: -Dwarnings RUST_BACKTRACE: full - BENCHMARK_RUSTC: nightly-2025-05-28 # Pin the toolchain for reproducable results + BENCHMARK_RUSTC: nightly-2025-12-01 # Pin the toolchain for reproducable results jobs: # Determine which tests should be run based on changed files. From 94a62dc6045f9bb027128119d55d54c593c5d795 Mon Sep 17 00:00:00 2001 From: The rustc-josh-sync Cronjob Bot Date: Tue, 2 Dec 2025 10:59:26 +0000 Subject: [PATCH 12/12] Prepare for merging from rust-lang/rust This updates the rust-version file to 47cd7120d9b4e1b64eb27c87522a07888197fae8. --- library/compiler-builtins/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/compiler-builtins/rust-version b/library/compiler-builtins/rust-version index 8854fb95997b..71fbbbaa984f 100644 --- a/library/compiler-builtins/rust-version +++ b/library/compiler-builtins/rust-version @@ -1 +1 @@ -caccb4d0368bd918ef6668af8e13834d07040417 +47cd7120d9b4e1b64eb27c87522a07888197fae8