Rollup merge of #144974 - tgross35:update-builtins, r=tgross35

compiler-builtins subtree update

Subtree update of `compiler-builtins` to 87a66ec969.

Created using https://github.com/rust-lang/josh-sync.

r? ``@ghost``
This commit is contained in:
Trevor Gross 2025-08-07 19:36:37 -05:00 committed by GitHub
commit 0a1e0c65ec
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
161 changed files with 464 additions and 533 deletions

View file

@ -34,7 +34,9 @@ jobs:
- name: Fetch pull request ref
run: git fetch origin "$GITHUB_REF:$GITHUB_REF"
if: github.event_name == 'pull_request'
- run: python3 ci/ci-util.py generate-matrix >> "$GITHUB_OUTPUT"
- run: |
set -eo pipefail # Needed to actually fail the job if ci-util fails
python3 ci/ci-util.py generate-matrix | tee "$GITHUB_OUTPUT"
id: script
test:
@ -50,7 +52,6 @@ jobs:
os: ubuntu-24.04-arm
- target: aarch64-pc-windows-msvc
os: windows-2025
test_verbatim: 1
build_only: 1
- target: arm-unknown-linux-gnueabi
os: ubuntu-24.04
@ -70,8 +71,12 @@ jobs:
os: ubuntu-24.04
- target: powerpc64le-unknown-linux-gnu
os: ubuntu-24.04
- target: powerpc64le-unknown-linux-gnu
os: ubuntu-24.04-ppc64le
- target: riscv64gc-unknown-linux-gnu
os: ubuntu-24.04
- target: s390x-unknown-linux-gnu
os: ubuntu-24.04-s390x
- target: thumbv6m-none-eabi
os: ubuntu-24.04
- target: thumbv7em-none-eabi
@ -88,10 +93,8 @@ jobs:
os: macos-13
- target: i686-pc-windows-msvc
os: windows-2025
test_verbatim: 1
- target: x86_64-pc-windows-msvc
os: windows-2025
test_verbatim: 1
- target: i686-pc-windows-gnu
os: windows-2025
channel: nightly-i686-gnu
@ -102,11 +105,23 @@ jobs:
needs: [calculate_vars]
env:
BUILD_ONLY: ${{ matrix.build_only }}
TEST_VERBATIM: ${{ matrix.test_verbatim }}
MAY_SKIP_LIBM_CI: ${{ needs.calculate_vars.outputs.may_skip_libm_ci }}
steps:
- name: Print $HOME
shell: bash
run: |
set -x
echo "${HOME:-not found}"
pwd
printenv
- name: Print runner information
run: uname -a
# Native ppc and s390x runners don't have rustup by default
- name: Install rustup
if: matrix.os == 'ubuntu-24.04-ppc64le' || matrix.os == 'ubuntu-24.04-s390x'
run: sudo apt-get update && sudo apt-get install -y rustup
- uses: actions/checkout@v4
- name: Install Rust (rustup)
shell: bash
@ -117,7 +132,12 @@ jobs:
rustup update "$channel" --no-self-update
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:
key: ${{ matrix.target }}
@ -144,7 +164,7 @@ jobs:
shell: bash
- run: echo "RUST_COMPILER_RT_ROOT=$(realpath ./compiler-rt)" >> "$GITHUB_ENV"
shell: bash
- name: Download musl source
run: ./ci/update-musl.sh
shell: bash
@ -256,7 +276,7 @@ jobs:
with:
name: ${{ env.BASELINE_NAME }}
path: ${{ env.BASELINE_NAME }}.tar.xz
- name: Run wall time benchmarks
run: |
# Always use the same seed for benchmarks. Ideally we should switch to a
@ -311,8 +331,8 @@ jobs:
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- name: Install stable `rustfmt`
run: rustup set profile minimal && rustup default stable && rustup component add rustfmt
- name: Install nightly `rustfmt`
run: rustup set profile minimal && rustup default nightly && rustup component add rustfmt
- run: cargo fmt -- --check
extensive:

View file

@ -12,12 +12,13 @@ jobs:
if: github.repository == 'rust-lang/compiler-builtins'
uses: rust-lang/josh-sync/.github/workflows/rustc-pull.yml@main
with:
github-app-id: ${{ vars.APP_CLIENT_ID }}
# https://rust-lang.zulipchat.com/#narrow/channel/219381-t-libs/topic/compiler-builtins.20subtree.20sync.20automation/with/528482375
zulip-stream-id: 219381
zulip-topic: 'compiler-builtins subtree sync automation'
zulip-bot-email: "compiler-builtins-ci-bot@rust-lang.zulipchat.com"
zulip-bot-email: "compiler-builtins-ci-bot@rust-lang.zulipchat.com"
pr-base-branch: master
branch-name: rustc-pull
secrets:
zulip-api-token: ${{ secrets.ZULIP_API_TOKEN }}
token: ${{ secrets.GITHUB_TOKEN }}
github-app-secret: ${{ secrets.APP_PRIVATE_KEY }}

View file

@ -37,8 +37,9 @@ default = ["compiler-builtins"]
# implementations and also filling in unimplemented intrinsics
c = ["dep:cc"]
# Workaround for the Cranelift codegen backend. Disables any implementations
# which use inline assembly and fall back to pure Rust versions (if available).
# For implementations where there is both a generic version and a platform-
# specific version, use the generic version. This is meant to enable testing
# the generic versions on all platforms.
no-asm = []
# Workaround for codegen backends which haven't yet implemented `f16` and

View file

@ -40,11 +40,7 @@ mod intrinsics {
x as f64
}
#[cfg(all(
f16_enabled,
f128_enabled,
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
))]
#[cfg(all(f16_enabled, f128_enabled))]
pub fn extendhftf(x: f16) -> f128 {
x as f128
}
@ -201,11 +197,7 @@ mod intrinsics {
/* f128 operations */
#[cfg(all(
f16_enabled,
f128_enabled,
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
))]
#[cfg(all(f16_enabled, f128_enabled))]
pub fn trunctfhf(x: f128) -> f16 {
x as f16
}
@ -220,50 +212,32 @@ mod intrinsics {
x as f64
}
#[cfg(all(
f128_enabled,
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
))]
#[cfg(f128_enabled)]
pub fn fixtfsi(x: f128) -> i32 {
x as i32
}
#[cfg(all(
f128_enabled,
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
))]
#[cfg(f128_enabled)]
pub fn fixtfdi(x: f128) -> i64 {
x as i64
}
#[cfg(all(
f128_enabled,
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
))]
#[cfg(f128_enabled)]
pub fn fixtfti(x: f128) -> i128 {
x as i128
}
#[cfg(all(
f128_enabled,
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
))]
#[cfg(f128_enabled)]
pub fn fixunstfsi(x: f128) -> u32 {
x as u32
}
#[cfg(all(
f128_enabled,
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
))]
#[cfg(f128_enabled)]
pub fn fixunstfdi(x: f128) -> u64 {
x as u64
}
#[cfg(all(
f128_enabled,
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
))]
#[cfg(f128_enabled)]
pub fn fixunstfti(x: f128) -> u128 {
x as u128
}
@ -540,47 +514,25 @@ fn run() {
bb(extendhfdf(bb(2.)));
#[cfg(f16_enabled)]
bb(extendhfsf(bb(2.)));
#[cfg(all(
f16_enabled,
f128_enabled,
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
))]
#[cfg(all(f16_enabled, f128_enabled))]
bb(extendhftf(bb(2.)));
#[cfg(f128_enabled)]
bb(extendsftf(bb(2.)));
bb(fixdfti(bb(2.)));
bb(fixsfti(bb(2.)));
#[cfg(all(
f128_enabled,
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
))]
#[cfg(f128_enabled)]
bb(fixtfdi(bb(2.)));
#[cfg(all(
f128_enabled,
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
))]
#[cfg(f128_enabled)]
bb(fixtfsi(bb(2.)));
#[cfg(all(
f128_enabled,
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
))]
#[cfg(f128_enabled)]
bb(fixtfti(bb(2.)));
bb(fixunsdfti(bb(2.)));
bb(fixunssfti(bb(2.)));
#[cfg(all(
f128_enabled,
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
))]
#[cfg(f128_enabled)]
bb(fixunstfdi(bb(2.)));
#[cfg(all(
f128_enabled,
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
))]
#[cfg(f128_enabled)]
bb(fixunstfsi(bb(2.)));
#[cfg(all(
f128_enabled,
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
))]
#[cfg(f128_enabled)]
bb(fixunstfti(bb(2.)));
#[cfg(f128_enabled)]
bb(floatditf(bb(2)));
@ -616,11 +568,7 @@ fn run() {
bb(truncsfhf(bb(2.)));
#[cfg(f128_enabled)]
bb(trunctfdf(bb(2.)));
#[cfg(all(
f16_enabled,
f128_enabled,
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
))]
#[cfg(all(f16_enabled, f128_enabled))]
bb(trunctfhf(bb(2.)));
#[cfg(f128_enabled)]
bb(trunctfsf(bb(2.)));

View file

@ -365,7 +365,6 @@ float_bench! {
/* float -> unsigned int */
#[cfg(not(all(target_arch = "powerpc64", target_endian = "little")))]
float_bench! {
name: conv_f32_u32,
sig: (a: f32) -> u32,
@ -387,7 +386,6 @@ float_bench! {
],
}
#[cfg(not(all(target_arch = "powerpc64", target_endian = "little")))]
float_bench! {
name: conv_f32_u64,
sig: (a: f32) -> u64,
@ -409,7 +407,6 @@ float_bench! {
],
}
#[cfg(not(all(target_arch = "powerpc64", target_endian = "little")))]
float_bench! {
name: conv_f32_u128,
sig: (a: f32) -> u128,
@ -505,7 +502,6 @@ float_bench! {
/* float -> signed int */
#[cfg(not(all(target_arch = "powerpc64", target_endian = "little")))]
float_bench! {
name: conv_f32_i32,
sig: (a: f32) -> i32,
@ -527,7 +523,6 @@ float_bench! {
],
}
#[cfg(not(all(target_arch = "powerpc64", target_endian = "little")))]
float_bench! {
name: conv_f32_i64,
sig: (a: f32) -> i64,
@ -549,7 +544,6 @@ float_bench! {
],
}
#[cfg(not(all(target_arch = "powerpc64", target_endian = "little")))]
float_bench! {
name: conv_f32_i128,
sig: (a: f32) -> i128,
@ -666,9 +660,6 @@ pub fn float_conv() {
conv_f64_i128(&mut criterion);
#[cfg(f128_enabled)]
// FIXME: ppc64le has a sporadic overflow panic in the crate functions
// <https://github.com/rust-lang/compiler-builtins/issues/617#issuecomment-2125914639>
#[cfg(not(all(target_arch = "powerpc64", target_endian = "little")))]
{
conv_u32_f128(&mut criterion);
conv_u64_f128(&mut criterion);

View file

@ -110,9 +110,7 @@ float_bench! {
pub fn float_extend() {
let mut criterion = Criterion::default().configure_from_args();
// 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);
extend_f16_f64(&mut criterion);

View file

@ -121,9 +121,7 @@ float_bench! {
pub fn float_trunc() {
let mut criterion = Criterion::default().configure_from_args();
// FIXME(#655): `f16` tests disabled until we can bootstrap symbols
#[cfg(f16_enabled)]
#[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))]
{
trunc_f32_f16(&mut criterion);
trunc_f64_f16(&mut criterion);
@ -133,11 +131,8 @@ pub fn float_trunc() {
#[cfg(f128_enabled)]
{
// FIXME(#655): `f16` tests disabled until we can bootstrap symbols
#[cfg(f16_enabled)]
#[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))]
trunc_f128_f16(&mut criterion);
trunc_f128_f32(&mut criterion);
trunc_f128_f64(&mut criterion);
}

View file

@ -17,28 +17,14 @@ pub fn skip_sys_checks(test_name: &str) -> bool {
"extend_f16_f32",
"trunc_f32_f16",
"trunc_f64_f16",
// FIXME(#616): re-enable once fix is in nightly
// <https://github.com/rust-lang/compiler-builtins/issues/616>
"mul_f32",
"mul_f64",
];
// FIXME(f16_f128): error on LE ppc64. There are more tests that are cfg-ed out completely
// in their benchmark modules due to runtime panics.
// <https://github.com/rust-lang/compiler-builtins/issues/617#issuecomment-2125914639>
const PPC64LE_SKIPPED: &[&str] = &["extend_f32_f128"];
// FIXME(f16_f128): system symbols have incorrect results
// <https://github.com/rust-lang/compiler-builtins/issues/617#issuecomment-2125914639>
const X86_NO_SSE_SKIPPED: &[&str] = &[
"add_f128", "sub_f128", "mul_f128", "div_f128", "powi_f32", "powi_f64",
];
// FIXME(f16_f128): Wide multiply carry bug in `compiler-rt`, re-enable when nightly no longer
// uses `compiler-rt` version.
// <https://github.com/llvm/llvm-project/issues/91840>
const AARCH64_SKIPPED: &[&str] = &["mul_f128", "div_f128"];
// FIXME(llvm): system symbols have incorrect results on Windows
// <https://github.com/rust-lang/compiler-builtins/issues/617#issuecomment-2121359807>
const WINDOWS_SKIPPED: &[&str] = &[
@ -57,19 +43,7 @@ pub fn skip_sys_checks(test_name: &str) -> bool {
return true;
}
if cfg!(all(target_arch = "powerpc64", target_endian = "little"))
&& PPC64LE_SKIPPED.contains(&test_name)
{
return true;
}
if cfg!(all(target_arch = "x86", not(target_feature = "sse")))
&& X86_NO_SSE_SKIPPED.contains(&test_name)
{
return true;
}
if cfg!(target_arch = "aarch64") && AARCH64_SKIPPED.contains(&test_name) {
if cfg!(x86_no_sse) && X86_NO_SSE_SKIPPED.contains(&test_name) {
return true;
}

View file

@ -111,7 +111,7 @@ macro_rules! float_sum {
}
}
#[cfg(not(all(target_arch = "x86", not(target_feature = "sse"))))]
#[cfg(not(x86_no_sse))]
mod float_addsub {
use super::*;
@ -122,7 +122,7 @@ mod float_addsub {
}
#[cfg(f128_enabled)]
#[cfg(not(all(target_arch = "x86", not(target_feature = "sse"))))]
#[cfg(not(x86_no_sse))]
#[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))]
mod float_addsub_f128 {
use super::*;

View file

@ -59,32 +59,28 @@ mod i_to_f {
|| ((error_minus == error || error_plus == error)
&& ((f0.to_bits() & 1) != 0))
{
if !cfg!(any(
target_arch = "powerpc",
target_arch = "powerpc64"
)) {
panic!(
"incorrect rounding by {}({}): {}, ({}, {}, {}), errors ({}, {}, {})",
stringify!($fn),
x,
f1.to_bits(),
y_minus_ulp,
y,
y_plus_ulp,
error_minus,
error,
error_plus,
);
}
panic!(
"incorrect rounding by {}({}): {}, ({}, {}, {}), errors ({}, {}, {})",
stringify!($fn),
x,
f1.to_bits(),
y_minus_ulp,
y,
y_plus_ulp,
error_minus,
error,
error_plus,
);
}
}
// Test against native conversion. We disable testing on all `x86` because of
// rounding bugs with `i686`. `powerpc` also has the same rounding bug.
// Test against native conversion.
// FIXME(x86,ppc): the platform version has rounding bugs on i686 and
// PowerPC64le (for PPC this only shows up in Docker, not the native runner).
// https://github.com/rust-lang/compiler-builtins/pull/384#issuecomment-740413334
if !Float::eq_repr(f0, f1) && !cfg!(any(
target_arch = "x86",
target_arch = "powerpc",
target_arch = "powerpc64"
all(target_arch = "powerpc64", target_endian = "little")
)) {
panic!(
"{}({}): std: {:?}, builtins: {:?}",

View file

@ -138,7 +138,7 @@ macro_rules! float {
};
}
#[cfg(not(all(target_arch = "x86", not(target_feature = "sse"))))]
#[cfg(not(x86_no_sse))]
mod float_div {
use super::*;

View file

@ -1,7 +1,7 @@
#![allow(unused_macros)]
#![cfg_attr(f128_enabled, feature(f128))]
#![cfg(not(all(target_arch = "x86", not(target_feature = "sse"))))]
#[cfg_attr(x86_no_sse, allow(unused))]
use builtins_test::*;
// This is approximate because of issues related to
@ -52,6 +52,7 @@ macro_rules! pow {
};
}
#[cfg(not(x86_no_sse))] // FIXME(i586): failure for powidf2
pow! {
f32, 1e-4, __powisf2, all();
f64, 1e-12, __powidf2, all();

View file

@ -1,6 +1,6 @@
#![feature(decl_macro)] // so we can use pub(super)
#![feature(macro_metavar_expr_concat)]
#![cfg(all(target_arch = "aarch64", target_os = "linux", not(feature = "no-asm")))]
#![cfg(all(target_arch = "aarch64", target_os = "linux"))]
/// Translate a byte size to a Rust type.
macro int_ty {

View file

@ -113,7 +113,7 @@ macro_rules! float_mul {
};
}
#[cfg(not(all(target_arch = "x86", not(target_feature = "sse"))))]
#[cfg(not(x86_no_sse))]
mod float_mul {
use super::*;
@ -126,7 +126,7 @@ mod float_mul {
}
#[cfg(f128_enabled)]
#[cfg(not(all(target_arch = "x86", not(target_feature = "sse"))))]
#[cfg(not(x86_no_sse))]
#[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))]
mod float_mul_f128 {
use super::*;

View file

@ -7,10 +7,12 @@ git history.
import json
import os
import pprint
import re
import subprocess as sp
import sys
from dataclasses import dataclass
from functools import cache
from glob import glob
from inspect import cleandoc
from os import getenv
@ -50,15 +52,6 @@ GIT = ["git", "-C", REPO_ROOT]
DEFAULT_BRANCH = "master"
WORKFLOW_NAME = "CI" # Workflow that generates the benchmark artifacts
ARTIFACT_PREFIX = "baseline-icount*"
# Place this in a PR body to skip regression checks (must be at the start of a line).
REGRESSION_DIRECTIVE = "ci: allow-regressions"
# Place this in a PR body to skip extensive tests
SKIP_EXTENSIVE_DIRECTIVE = "ci: skip-extensive"
# Place this in a PR body to allow running a large number of extensive tests. If not
# set, this script will error out if a threshold is exceeded in order to avoid
# accidentally spending huge amounts of CI time.
ALLOW_MANY_EXTENSIVE_DIRECTIVE = "ci: allow-many-extensive"
MANY_EXTENSIVE_THRESHOLD = 20
# Don't run exhaustive tests if these files change, even if they contaiin a function
# definition.
@ -70,7 +63,7 @@ IGNORE_FILES = [
# libm PR CI takes a long time and doesn't need to run unless relevant files have been
# changed. Anything matching this regex pattern will trigger a run.
TRIGGER_LIBM_PR_CI = ".*(libm|musl).*"
TRIGGER_LIBM_CI_FILE_PAT = ".*(libm|musl).*"
TYPES = ["f16", "f32", "f64", "f128"]
@ -80,6 +73,54 @@ def eprint(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)
@dataclass(init=False)
class PrCfg:
"""Directives that we allow in the commit body to control test behavior.
These are of the form `ci: foo`, at the start of a line.
"""
# Skip regression checks (must be at the start of a line).
allow_regressions: bool = False
# Don't run extensive tests
skip_extensive: bool = False
# Allow running a large number of extensive tests. If not set, this script
# will error out if a threshold is exceeded in order to avoid accidentally
# spending huge amounts of CI time.
allow_many_extensive: bool = False
# Max number of extensive tests to run by default
MANY_EXTENSIVE_THRESHOLD: int = 20
# Run tests for `libm` that may otherwise be skipped due to no changed files.
always_test_libm: bool = False
# String values of directive names
DIR_ALLOW_REGRESSIONS: str = "allow-regressions"
DIR_SKIP_EXTENSIVE: str = "skip-extensive"
DIR_ALLOW_MANY_EXTENSIVE: str = "allow-many-extensive"
DIR_TEST_LIBM: str = "test-libm"
def __init__(self, body: str):
directives = re.finditer(r"^\s*ci:\s*(?P<dir_name>\S*)", body, re.MULTILINE)
for dir in directives:
name = dir.group("dir_name")
if name == self.DIR_ALLOW_REGRESSIONS:
self.allow_regressions = True
elif name == self.DIR_SKIP_EXTENSIVE:
self.skip_extensive = True
elif name == self.DIR_ALLOW_MANY_EXTENSIVE:
self.allow_many_extensive = True
elif name == self.DIR_TEST_LIBM:
self.always_test_libm = True
else:
eprint(f"Found unexpected directive `{name}`")
exit(1)
pprint.pp(self)
@dataclass
class PrInfo:
"""GitHub response for PR query"""
@ -88,10 +129,21 @@ class PrInfo:
commits: list[str]
created_at: str
number: int
cfg: PrCfg
@classmethod
def load(cls, pr_number: int | str) -> Self:
"""For a given PR number, query the body and commit list"""
def from_env(cls) -> Self | None:
"""Create a PR object from the PR_NUMBER environment if set, `None` otherwise."""
pr_env = os.environ.get("PR_NUMBER")
if pr_env is not None and len(pr_env) > 0:
return cls.from_pr(pr_env)
return None
@classmethod
@cache # Cache so we don't print info messages multiple times
def from_pr(cls, pr_number: int | str) -> Self:
"""For a given PR number, query the body and commit list."""
pr_info = sp.check_output(
[
"gh",
@ -104,13 +156,9 @@ class PrInfo:
],
text=True,
)
eprint("PR info:", json.dumps(pr_info, indent=4))
return cls(**json.loads(pr_info))
def contains_directive(self, directive: str) -> bool:
"""Return true if the provided directive is on a line in the PR body"""
lines = self.body.splitlines()
return any(line.startswith(directive) for line in lines)
pr_json = json.loads(pr_info)
eprint("PR info:", json.dumps(pr_json, indent=4))
return cls(**json.loads(pr_info), cfg=PrCfg(pr_json["body"]))
class FunctionDef(TypedDict):
@ -207,26 +255,32 @@ class Context:
"""If this is a PR and no libm files were changed, allow skipping libm
jobs."""
if self.is_pr():
return all(not re.match(TRIGGER_LIBM_PR_CI, str(f)) for f in self.changed)
# Always run on merge CI
if not self.is_pr():
return False
return False
pr = PrInfo.from_env()
assert pr is not None, "Is a PR but couldn't load PrInfo"
# Allow opting in to libm tests
if pr.cfg.always_test_libm:
return False
# By default, run if there are any changed files matching the pattern
return all(not re.match(TRIGGER_LIBM_CI_FILE_PAT, str(f)) for f in self.changed)
def emit_workflow_output(self):
"""Create a JSON object a list items for each type's changed files, if any
did change, and the routines that were affected by the change.
"""
pr_number = os.environ.get("PR_NUMBER")
skip_tests = False
error_on_many_tests = False
if pr_number is not None and len(pr_number) > 0:
pr = PrInfo.load(pr_number)
skip_tests = pr.contains_directive(SKIP_EXTENSIVE_DIRECTIVE)
error_on_many_tests = not pr.contains_directive(
ALLOW_MANY_EXTENSIVE_DIRECTIVE
)
pr = PrInfo.from_env()
if pr is not None:
skip_tests = pr.cfg.skip_extensive
error_on_many_tests = not pr.cfg.allow_many_extensive
if skip_tests:
eprint("Skipping all extensive tests")
@ -253,16 +307,14 @@ class Context:
may_skip = str(self.may_skip_libm_ci()).lower()
print(f"extensive_matrix={ext_matrix}")
print(f"may_skip_libm_ci={may_skip}")
eprint(f"extensive_matrix={ext_matrix}")
eprint(f"may_skip_libm_ci={may_skip}")
eprint(f"total extensive tests: {total_to_test}")
if error_on_many_tests and total_to_test > MANY_EXTENSIVE_THRESHOLD:
if error_on_many_tests and total_to_test > PrCfg.MANY_EXTENSIVE_THRESHOLD:
eprint(
f"More than {MANY_EXTENSIVE_THRESHOLD} tests would be run; add"
f" `{ALLOW_MANY_EXTENSIVE_DIRECTIVE}` to the PR body if this is"
f"More than {PrCfg.MANY_EXTENSIVE_THRESHOLD} tests would be run; add"
f" `{PrCfg.DIR_ALLOW_MANY_EXTENSIVE}` to the PR body if this is"
" intentional. If this is refactoring that happens to touch a lot of"
f" files, `{SKIP_EXTENSIVE_DIRECTIVE}` can be used instead."
f" files, `{PrCfg.DIR_SKIP_EXTENSIVE}` can be used instead."
)
exit(1)
@ -371,8 +423,8 @@ def handle_bench_regressions(args: list[str]):
eprint(USAGE)
exit(1)
pr = PrInfo.load(pr_number)
if pr.contains_directive(REGRESSION_DIRECTIVE):
pr = PrInfo.from_pr(pr_number)
if pr.cfg.allow_regressions:
eprint("PR allows regressions")
return

View file

@ -1,4 +1,4 @@
ARG IMAGE=ubuntu:24.04
ARG IMAGE=ubuntu:25.04
FROM $IMAGE
RUN apt-get update && \

View file

@ -1,4 +1,4 @@
ARG IMAGE=ubuntu:24.04
ARG IMAGE=ubuntu:25.04
FROM $IMAGE
RUN apt-get update && \

View file

@ -1,4 +1,4 @@
ARG IMAGE=ubuntu:24.04
ARG IMAGE=ubuntu:25.04
FROM $IMAGE
RUN apt-get update && \

View file

@ -1,4 +1,4 @@
ARG IMAGE=ubuntu:24.04
ARG IMAGE=ubuntu:25.04
FROM $IMAGE
RUN apt-get update && \

View file

@ -1,4 +1,4 @@
ARG IMAGE=ubuntu:24.04
ARG IMAGE=ubuntu:25.04
FROM $IMAGE
RUN apt-get update && \

View file

@ -1,4 +1,4 @@
ARG IMAGE=ubuntu:24.04
ARG IMAGE=ubuntu:25.04
FROM $IMAGE
RUN apt-get update && \

View file

@ -1,4 +1,4 @@
ARG IMAGE=ubuntu:24.04
ARG IMAGE=ubuntu:25.04
FROM $IMAGE
RUN apt-get update && \

View file

@ -1,4 +1,4 @@
ARG IMAGE=ubuntu:24.04
ARG IMAGE=ubuntu:25.04
FROM $IMAGE
RUN apt-get update && \

View file

@ -1,4 +1,4 @@
ARG IMAGE=ubuntu:24.04
ARG IMAGE=ubuntu:25.04
FROM $IMAGE
RUN apt-get update && \

View file

@ -1,4 +1,4 @@
ARG IMAGE=ubuntu:24.04
ARG IMAGE=ubuntu:25.04
FROM $IMAGE
RUN apt-get update && \

View file

@ -1,4 +1,4 @@
ARG IMAGE=ubuntu:24.04
ARG IMAGE=ubuntu:25.04
FROM $IMAGE
RUN apt-get update && \

View file

@ -1,4 +1,4 @@
ARG IMAGE=ubuntu:24.04
ARG IMAGE=ubuntu:25.04
FROM $IMAGE
RUN apt-get update && \

View file

@ -1,4 +1,4 @@
ARG IMAGE=ubuntu:24.04
ARG IMAGE=ubuntu:25.04
FROM $IMAGE
RUN apt-get update && \

View file

@ -1,4 +1,4 @@
ARG IMAGE=ubuntu:24.04
ARG IMAGE=ubuntu:25.04
FROM $IMAGE
RUN apt-get update && \
@ -12,6 +12,5 @@ ENV CARGO_TARGET_POWERPC64LE_UNKNOWN_LINUX_GNU_LINKER="$TOOLCHAIN_PREFIX"gcc \
CARGO_TARGET_POWERPC64LE_UNKNOWN_LINUX_GNU_RUNNER=qemu-ppc64le-static \
AR_powerpc64le_unknown_linux_gnu="$TOOLCHAIN_PREFIX"ar \
CC_powerpc64le_unknown_linux_gnu="$TOOLCHAIN_PREFIX"gcc \
QEMU_CPU=POWER8 \
QEMU_LD_PREFIX=/usr/powerpc64le-linux-gnu \
RUST_TEST_THREADS=1

View file

@ -1,4 +1,4 @@
ARG IMAGE=ubuntu:24.04
ARG IMAGE=ubuntu:25.04
FROM $IMAGE
RUN apt-get update && \

View file

@ -1,4 +1,4 @@
ARG IMAGE=ubuntu:24.04
ARG IMAGE=ubuntu:25.04
FROM $IMAGE
RUN apt-get update && \

View file

@ -1,4 +1,4 @@
ARG IMAGE=ubuntu:24.04
ARG IMAGE=ubuntu:25.04
FROM $IMAGE
RUN apt-get update && \

View file

@ -1,4 +1,4 @@
ARG IMAGE=ubuntu:24.04
ARG IMAGE=ubuntu:25.04
FROM $IMAGE
RUN apt-get update && \

View file

@ -1,4 +1,4 @@
ARG IMAGE=ubuntu:24.04
ARG IMAGE=ubuntu:25.04
FROM $IMAGE
RUN apt-get update && \

View file

@ -1,4 +1,4 @@
ARG IMAGE=ubuntu:24.04
ARG IMAGE=ubuntu:25.04
FROM $IMAGE
RUN apt-get update && \

View file

@ -97,7 +97,7 @@ if [ "${1:-}" = "--help" ] || [ "$#" -gt 1 ]; then
usage: ./ci/run-docker.sh [target]
you can also set DOCKER_BASE_IMAGE to use something other than the default
ubuntu:24.04 (or rustlang/rust:nightly).
ubuntu:25.04 (or rustlang/rust:nightly).
"
exit
fi

View file

@ -41,7 +41,10 @@ else
"${test_builtins[@]}" --benches
"${test_builtins[@]}" --benches --release
if [ "${TEST_VERBATIM:-}" = "1" ]; then
# Validate that having a verbatim path for the target directory works
# (trivial to regress using `/` in paths to build artifacts rather than
# `Path::join`). MinGW does not currently support these paths.
if [[ "$target" = *"windows"* ]] && [[ "$target" != *"gnu"* ]]; then
verb_path=$(cmd.exe //C echo \\\\?\\%cd%\\builtins-test\\target2)
"${test_builtins[@]}" --target-dir "$verb_path" --features c
fi
@ -161,7 +164,7 @@ else
mflags+=(--workspace --target "$target")
cmd=(cargo test "${mflags[@]}")
profile_flag="--profile"
# If nextest is available, use that
command -v cargo-nextest && nextest=1 || nextest=0
if [ "$nextest" = "1" ]; then
@ -204,7 +207,7 @@ else
"${cmd[@]}" "$profile_flag" release-checked --features unstable-intrinsics --benches
# Ensure that the routines do not panic.
#
#
# `--tests` must be passed because no-panic is only enabled as a dev
# dependency. The `release-opt` profile must be used to enable LTO and a
# single CGU.

View file

@ -3,7 +3,7 @@
set -eux
url=git://git.musl-libc.org/musl
url=https://github.com/kraj/musl.git
ref=c47ad25ea3b484e10326f933e927c0bc8cded3da
dst=crates/musl-math-sys/musl

View file

@ -35,8 +35,9 @@ default = ["compiler-builtins"]
# implementations and also filling in unimplemented intrinsics
c = ["dep:cc"]
# Workaround for the Cranelift codegen backend. Disables any implementations
# which use inline assembly and fall back to pure Rust versions (if available).
# For implementations where there is both a generic version and a platform-
# specific version, use the generic version. This is meant to enable testing
# the generic versions on all platforms.
no-asm = []
# Workaround for codegen backends which haven't yet implemented `f16` and

View file

@ -106,13 +106,6 @@ fn configure_libm(target: &Target) {
println!("cargo:rustc-cfg=optimizations_enabled");
}
// Config shorthands
println!("cargo:rustc-check-cfg=cfg(x86_no_sse)");
if target.arch == "x86" && !target.features.iter().any(|f| f == "sse") {
// Shorthand to detect i586 targets
println!("cargo:rustc-cfg=x86_no_sse");
}
println!(
"cargo:rustc-env=CFG_CARGO_FEATURES={:?}",
target.cargo_features

View file

@ -1,6 +1,5 @@
// Configuration that is shared between `compiler_builtins` and `builtins_test`.
use std::process::{Command, Stdio};
use std::{env, str};
#[derive(Debug)]
@ -35,26 +34,6 @@ impl Target {
.map(|s| s.to_lowercase().replace("_", "-"))
.collect();
// Query rustc for options that Cargo does not provide env for. The bootstrap hack is used
// to get consistent output regardless of channel (`f16`/`f128` config options are hidden
// on stable otherwise).
let mut cmd = Command::new(env::var("RUSTC").unwrap());
cmd.args(["--print=cfg", "--target", &triple])
.env("RUSTC_BOOTSTRAP", "1")
.stderr(Stdio::inherit());
let out = cmd
.output()
.unwrap_or_else(|e| panic!("failed to run `{cmd:?}`: {e}"));
let rustc_cfg = str::from_utf8(&out.stdout).unwrap();
// If we couldn't query `rustc` (e.g. a custom JSON target was used), make the safe
// choice and leave `f16` and `f128` disabled.
let rustc_output_ok = out.status.success();
let reliable_f128 =
rustc_output_ok && rustc_cfg.lines().any(|l| l == "target_has_reliable_f128");
let reliable_f16 =
rustc_output_ok && rustc_cfg.lines().any(|l| l == "target_has_reliable_f16");
Self {
triple,
triple_split,
@ -74,8 +53,10 @@ impl Target {
.split(",")
.map(ToOwned::to_owned)
.collect(),
reliable_f128,
reliable_f16,
// Note that these are unstable options, so only show up with the nightly compiler or
// with `RUSTC_BOOTSTRAP=1` (which is required to use the types anyway).
reliable_f128: env::var_os("CARGO_CFG_TARGET_HAS_RELIABLE_F128").is_some(),
reliable_f16: env::var_os("CARGO_CFG_TARGET_HAS_RELIABLE_F16").is_some(),
}
}
@ -100,6 +81,13 @@ pub fn configure_aliases(target: &Target) {
println!("cargo:rustc-cfg=thumb_1")
}
// Config shorthands
println!("cargo:rustc-check-cfg=cfg(x86_no_sse)");
if target.arch == "x86" && !target.features.iter().any(|f| f == "sse") {
// Shorthand to detect i586 targets
println!("cargo:rustc-cfg=x86_no_sse");
}
/* Not all backends support `f16` and `f128` to the same level on all architectures, so we
* need to disable things if the compiler may crash. See configuration at:
* * https://github.com/rust-lang/rust/blob/c65dccabacdfd6c8a7f7439eba13422fdd89b91e/compiler/rustc_codegen_llvm/src/llvm_util.rs#L367-L432

View file

@ -4,7 +4,7 @@ use core::intrinsics;
intrinsics! {
#[unsafe(naked)]
#[cfg(all(target_os = "uefi", not(feature = "no-asm")))]
#[cfg(target_os = "uefi")]
pub unsafe extern "custom" fn __chkstk() {
core::arch::naked_asm!(
".p2align 2",

View file

@ -1,5 +1,3 @@
#![cfg(not(feature = "no-asm"))]
// Interfaces used by naked trampolines.
// SAFETY: these are defined in compiler-builtins
unsafe extern "C" {

View file

@ -1,5 +1,3 @@
#![cfg(not(feature = "no-asm"))]
use core::arch::global_asm;
global_asm!(include_str!("hexagon/func_macro.s"), options(raw));

View file

@ -60,7 +60,7 @@ pub mod arm;
#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))]
pub mod aarch64;
#[cfg(all(target_arch = "aarch64", target_os = "linux", not(feature = "no-asm"),))]
#[cfg(all(target_arch = "aarch64", target_os = "linux"))]
pub mod aarch64_linux;
#[cfg(all(

View file

@ -44,8 +44,6 @@
#![cfg(not(feature = "mangled-names"))]
// Windows and Cygwin already has builtins to do this.
#![cfg(not(any(windows, target_os = "cygwin")))]
// All these builtins require assembly
#![cfg(not(feature = "no-asm"))]
// We only define stack probing for these architectures today.
#![cfg(any(target_arch = "x86_64", target_arch = "x86"))]

View file

@ -9,10 +9,7 @@ use core::intrinsics;
intrinsics! {
#[unsafe(naked)]
#[cfg(all(
any(all(windows, target_env = "gnu"), target_os = "uefi"),
not(feature = "no-asm")
))]
#[cfg(any(all(windows, target_env = "gnu"), target_os = "uefi"))]
pub unsafe extern "custom" fn __chkstk() {
core::arch::naked_asm!(
"jmp {}", // Jump to __alloca since fallthrough may be unreliable"
@ -21,10 +18,7 @@ intrinsics! {
}
#[unsafe(naked)]
#[cfg(all(
any(all(windows, target_env = "gnu"), target_os = "uefi"),
not(feature = "no-asm")
))]
#[cfg(any(all(windows, target_env = "gnu"), target_os = "uefi"))]
pub unsafe extern "custom" fn _alloca() {
// __chkstk and _alloca are the same function
core::arch::naked_asm!(

View file

@ -9,14 +9,7 @@ use core::intrinsics;
intrinsics! {
#[unsafe(naked)]
#[cfg(all(
any(
all(windows, target_env = "gnu"),
target_os = "cygwin",
target_os = "uefi"
),
not(feature = "no-asm")
))]
#[cfg(any(all(windows, target_env = "gnu"), target_os = "cygwin", target_os = "uefi"))]
pub unsafe extern "custom" fn ___chkstk_ms() {
core::arch::naked_asm!(
"push %rcx",

View file

@ -40,8 +40,6 @@ macro_rules! functions {
) => {
// Run a simple check to ensure we can link and call the function without crashing.
#[test]
// FIXME(#309): LE PPC crashes calling some musl functions
#[cfg_attr(all(target_arch = "powerpc64", target_endian = "little"), ignore)]
fn $name() {
<fn($($aty),+) -> $rty>::check(super::$name);
}

View file

@ -5,8 +5,7 @@ edition = "2024"
publish = false
[dependencies]
# FIXME: used as a git dependency since the latest release does not support wasm
object = { git = "https://github.com/gimli-rs/object.git", rev = "013fac75da56a684377af4151b8164b78c1790e0" }
object = "0.37.1"
serde_json = "1.0.140"
[features]

View file

@ -271,18 +271,6 @@ impl MaybeOverride<(f32,)> for SpecialCase {
impl MaybeOverride<(f64,)> for SpecialCase {
fn check_float<F: Float>(input: (f64,), actual: F, expected: F, ctx: &CheckCtx) -> CheckAction {
if cfg!(x86_no_sse)
&& ctx.base_name == BaseName::Ceil
&& ctx.basis == CheckBasis::Musl
&& input.0 < 0.0
&& input.0 > -1.0
&& expected == F::ZERO
&& actual == F::ZERO
{
// musl returns -0.0, we return +0.0
return XFAIL("i586 ceil signed zero");
}
if cfg!(x86_no_sse)
&& (ctx.base_name == BaseName::Rint || ctx.base_name == BaseName::Roundeven)
&& (expected - actual).abs() <= F::ONE
@ -292,16 +280,6 @@ impl MaybeOverride<(f64,)> for SpecialCase {
return XFAIL("i586 rint rounding mode");
}
if cfg!(x86_no_sse)
&& (ctx.fn_ident == Identifier::Ceil || ctx.fn_ident == Identifier::Floor)
&& expected.eq_repr(F::NEG_ZERO)
&& actual.eq_repr(F::ZERO)
{
// FIXME: the x87 implementations do not keep the distinction between -0.0 and 0.0.
// See https://github.com/rust-lang/libm/pull/404#issuecomment-2572399955
return XFAIL("i586 ceil/floor signed zero");
}
if cfg!(x86_no_sse)
&& (ctx.fn_ident == Identifier::Exp10 || ctx.fn_ident == Identifier::Exp2)
{

View file

@ -1,9 +1,9 @@
// Configuration shared with both libm and libm-test
use std::env;
use std::path::PathBuf;
use std::process::{Command, Stdio};
use std::{env, str};
#[derive(Debug)]
#[allow(dead_code)]
pub struct Config {
pub manifest_dir: PathBuf,
@ -33,26 +33,6 @@ impl Config {
.map(|s| s.to_lowercase().replace("_", "-"))
.collect();
// Query rustc for options that Cargo does not provide env for. The bootstrap hack is used
// to get consistent output regardless of channel (`f16`/`f128` config options are hidden
// on stable otherwise).
let mut cmd = Command::new(env::var("RUSTC").unwrap());
cmd.args(["--print=cfg", "--target", &target_triple])
.env("RUSTC_BOOTSTRAP", "1")
.stderr(Stdio::inherit());
let out = cmd
.output()
.unwrap_or_else(|e| panic!("failed to run `{cmd:?}`: {e}"));
let rustc_cfg = str::from_utf8(&out.stdout).unwrap();
// If we couldn't query `rustc` (e.g. a custom JSON target was used), make the safe
// choice and leave `f16` and `f128` disabled.
let rustc_output_ok = out.status.success();
let reliable_f128 =
rustc_output_ok && rustc_cfg.lines().any(|l| l == "target_has_reliable_f128");
let reliable_f16 =
rustc_output_ok && rustc_cfg.lines().any(|l| l == "target_has_reliable_f16");
Self {
target_triple,
manifest_dir: PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()),
@ -66,8 +46,10 @@ impl Config {
target_string: env::var("TARGET").unwrap(),
target_vendor: env::var("CARGO_CFG_TARGET_VENDOR").unwrap(),
target_features,
reliable_f128,
reliable_f16,
// Note that these are unstable options, so only show up with the nightly compiler or
// with `RUSTC_BOOTSTRAP=1` (which is required to use the types anyway).
reliable_f128: env::var_os("CARGO_CFG_TARGET_HAS_RELIABLE_F128").is_some(),
reliable_f16: env::var_os("CARGO_CFG_TARGET_HAS_RELIABLE_F16").is_some(),
}
}
}

View file

@ -59,7 +59,7 @@ fn r(z: f64) -> f64 {
/// Computes the inverse cosine (arc cosine) of the input value.
/// Arguments must be in the range -1 to 1.
/// Returns values in radians, in the range of 0 to pi.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn acos(x: f64) -> f64 {
let x1p_120f = f64::from_bits(0x3870000000000000); // 0x1p-120 === 2 ^ -120
let z: f64;

View file

@ -33,7 +33,7 @@ fn r(z: f32) -> f32 {
/// Computes the inverse cosine (arc cosine) of the input value.
/// Arguments must be in the range -1 to 1.
/// Returns values in radians, in the range of 0 to pi.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn acosf(x: f32) -> f32 {
let x1p_120 = f32::from_bits(0x03800000); // 0x1p-120 === 2 ^ (-120)

View file

@ -7,7 +7,7 @@ const LN2: f64 = 0.693147180559945309417232121458176568; /* 0x3fe62e42, 0xfefa3
/// Calculates the inverse hyperbolic cosine of `x`.
/// Is defined as `log(x + sqrt(x*x-1))`.
/// `x` must be a number greater than or equal to 1.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn acosh(x: f64) -> f64 {
let u = x.to_bits();
let e = ((u >> 52) as usize) & 0x7ff;

View file

@ -7,7 +7,7 @@ const LN2: f32 = 0.693147180559945309417232121458176568;
/// Calculates the inverse hyperbolic cosine of `x`.
/// Is defined as `log(x + sqrt(x*x-1))`.
/// `x` must be a number greater than or equal to 1.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn acoshf(x: f32) -> f32 {
let u = x.to_bits();
let a = u & 0x7fffffff;

View file

@ -1,37 +1,62 @@
//! Architecture-specific support for x86-32 without SSE2
//!
//! We use an alternative implementation on x86, because the
//! main implementation fails with the x87 FPU used by
//! debian i386, probably due to excess precision issues.
//!
//! See https://github.com/rust-lang/compiler-builtins/pull/976 for discussion on why these
//! functions are implemented in this way.
use super::super::fabs;
/// Use an alternative implementation on x86, because the
/// main implementation fails with the x87 FPU used by
/// debian i386, probably due to excess precision issues.
/// Basic implementation taken from https://github.com/rust-lang/libm/issues/219.
pub fn ceil(x: f64) -> f64 {
if fabs(x).to_bits() < 4503599627370496.0_f64.to_bits() {
let truncated = x as i64 as f64;
if truncated < x {
return truncated + 1.0;
} else {
return truncated;
}
} else {
return x;
pub fn ceil(mut x: f64) -> f64 {
unsafe {
core::arch::asm!(
"fld qword ptr [{x}]",
// Save the FPU control word, using `x` as scratch space.
"fstcw [{x}]",
// Set rounding control to 0b10 (+∞).
"mov word ptr [{x} + 2], 0x0b7f",
"fldcw [{x} + 2]",
// Round.
"frndint",
// Restore FPU control word.
"fldcw [{x}]",
// Save rounded value to memory.
"fstp qword ptr [{x}]",
x = in(reg) &mut x,
// All the x87 FPU stack is used, all registers must be clobbered
out("st(0)") _, out("st(1)") _,
out("st(2)") _, out("st(3)") _,
out("st(4)") _, out("st(5)") _,
out("st(6)") _, out("st(7)") _,
options(nostack),
);
}
x
}
/// Use an alternative implementation on x86, because the
/// main implementation fails with the x87 FPU used by
/// debian i386, probably due to excess precision issues.
/// Basic implementation taken from https://github.com/rust-lang/libm/issues/219.
pub fn floor(x: f64) -> f64 {
if fabs(x).to_bits() < 4503599627370496.0_f64.to_bits() {
let truncated = x as i64 as f64;
if truncated > x {
return truncated - 1.0;
} else {
return truncated;
}
} else {
return x;
pub fn floor(mut x: f64) -> f64 {
unsafe {
core::arch::asm!(
"fld qword ptr [{x}]",
// Save the FPU control word, using `x` as scratch space.
"fstcw [{x}]",
// Set rounding control to 0b01 (-∞).
"mov word ptr [{x} + 2], 0x077f",
"fldcw [{x} + 2]",
// Round.
"frndint",
// Restore FPU control word.
"fldcw [{x}]",
// Save rounded value to memory.
"fstp qword ptr [{x}]",
x = in(reg) &mut x,
// All the x87 FPU stack is used, all registers must be clobbered
out("st(0)") _, out("st(1)") _,
out("st(2)") _, out("st(3)") _,
out("st(4)") _, out("st(5)") _,
out("st(6)") _, out("st(7)") _,
options(nostack),
);
}
x
}

View file

@ -66,7 +66,7 @@ fn comp_r(z: f64) -> f64 {
/// Computes the inverse sine (arc sine) of the argument `x`.
/// Arguments to asin must be in the range -1 to 1.
/// Returns values in radians, in the range of -pi/2 to pi/2.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn asin(mut x: f64) -> f64 {
let z: f64;
let r: f64;

View file

@ -35,7 +35,7 @@ fn r(z: f32) -> f32 {
/// Computes the inverse sine (arc sine) of the argument `x`.
/// Arguments to asin must be in the range -1 to 1.
/// Returns values in radians, in the range of -pi/2 to pi/2.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn asinf(mut x: f32) -> f32 {
let x1p_120 = f64::from_bits(0x3870000000000000); // 0x1p-120 === 2 ^ (-120)

View file

@ -7,7 +7,7 @@ const LN2: f64 = 0.693147180559945309417232121458176568; /* 0x3fe62e42, 0xfefa3
///
/// Calculates the inverse hyperbolic sine of `x`.
/// Is defined as `sgn(x)*log(|x|+sqrt(x*x+1))`.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn asinh(mut x: f64) -> f64 {
let mut u = x.to_bits();
let e = ((u >> 52) as usize) & 0x7ff;

View file

@ -7,7 +7,7 @@ const LN2: f32 = 0.693147180559945309417232121458176568;
///
/// Calculates the inverse hyperbolic sine of `x`.
/// Is defined as `sgn(x)*log(|x|+sqrt(x*x+1))`.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn asinhf(mut x: f32) -> f32 {
let u = x.to_bits();
let i = u & 0x7fffffff;

View file

@ -65,7 +65,7 @@ const AT: [f64; 11] = [
///
/// Computes the inverse tangent (arc tangent) of the input value.
/// Returns a value in radians, in the range of -pi/2 to pi/2.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn atan(x: f64) -> f64 {
let mut x = x;
let mut ix = (x.to_bits() >> 32) as u32;

View file

@ -47,7 +47,7 @@ const PI_LO: f64 = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */
/// Computes the inverse tangent (arc tangent) of `y/x`.
/// Produces the correct result even for angles near pi/2 or -pi/2 (that is, when `x` is near 0).
/// Returns a value in radians, in the range of -pi to pi.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn atan2(y: f64, x: f64) -> f64 {
if x.is_nan() || y.is_nan() {
return x + y;

View file

@ -23,7 +23,7 @@ const PI_LO: f32 = -8.7422776573e-08; /* 0xb3bbbd2e */
/// Computes the inverse tangent (arc tangent) of `y/x`.
/// Produces the correct result even for angles near pi/2 or -pi/2 (that is, when `x` is near 0).
/// Returns a value in radians, in the range of -pi to pi.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn atan2f(y: f32, x: f32) -> f32 {
if x.is_nan() || y.is_nan() {
return x + y;

View file

@ -41,7 +41,7 @@ const A_T: [f32; 5] = [
///
/// Computes the inverse tangent (arc tangent) of the input value.
/// Returns a value in radians, in the range of -pi/2 to pi/2.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn atanf(mut x: f32) -> f32 {
let x1p_120 = f32::from_bits(0x03800000); // 0x1p-120 === 2 ^ (-120)

View file

@ -5,7 +5,7 @@ use super::log1p;
///
/// Calculates the inverse hyperbolic tangent of `x`.
/// Is defined as `log((1+x)/(1-x))/2 = log1p(2x/(1-x))/2`.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn atanh(x: f64) -> f64 {
let u = x.to_bits();
let e = ((u >> 52) as usize) & 0x7ff;

View file

@ -5,7 +5,7 @@ use super::log1pf;
///
/// Calculates the inverse hyperbolic tangent of `x`.
/// Is defined as `log((1+x)/(1-x))/2 = log1p(2x/(1-x))/2`.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn atanhf(mut x: f32) -> f32 {
let mut u = x.to_bits();
let sign = (u >> 31) != 0;

View file

@ -8,7 +8,7 @@ use super::Float;
use super::support::{FpResult, Round, cold_path};
/// Compute the cube root of the argument.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn cbrt(x: f64) -> f64 {
cbrt_round(x, Round::Nearest).val
}

View file

@ -25,7 +25,7 @@ const B2: u32 = 642849266; /* B2 = (127-127.0/3-24/3-0.03306235651)*2**23 */
/// Cube root (f32)
///
/// Computes the cube root of the argument.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn cbrtf(x: f32) -> f32 {
let x1p24 = f32::from_bits(0x4b800000); // 0x1p24f === 2 ^ 24

View file

@ -2,7 +2,7 @@
///
/// Finds the nearest integer greater than or equal to `x`.
#[cfg(f16_enabled)]
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn ceilf16(x: f16) -> f16 {
super::generic::ceil(x)
}
@ -10,7 +10,7 @@ pub fn ceilf16(x: f16) -> f16 {
/// Ceil (f32)
///
/// Finds the nearest integer greater than or equal to `x`.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn ceilf(x: f32) -> f32 {
select_implementation! {
name: ceilf,
@ -24,7 +24,7 @@ pub fn ceilf(x: f32) -> f32 {
/// Ceil (f64)
///
/// Finds the nearest integer greater than or equal to `x`.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn ceil(x: f64) -> f64 {
select_implementation! {
name: ceil,
@ -40,7 +40,7 @@ pub fn ceil(x: f64) -> f64 {
///
/// Finds the nearest integer greater than or equal to `x`.
#[cfg(f128_enabled)]
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn ceilf128(x: f128) -> f128 {
super::generic::ceil(x)
}

View file

@ -3,7 +3,7 @@
/// Constructs a number with the magnitude (absolute value) of its
/// first argument, `x`, and the sign of its second argument, `y`.
#[cfg(f16_enabled)]
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn copysignf16(x: f16, y: f16) -> f16 {
super::generic::copysign(x, y)
}
@ -12,7 +12,7 @@ pub fn copysignf16(x: f16, y: f16) -> f16 {
///
/// Constructs a number with the magnitude (absolute value) of its
/// first argument, `x`, and the sign of its second argument, `y`.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn copysignf(x: f32, y: f32) -> f32 {
super::generic::copysign(x, y)
}
@ -21,7 +21,7 @@ pub fn copysignf(x: f32, y: f32) -> f32 {
///
/// Constructs a number with the magnitude (absolute value) of its
/// first argument, `x`, and the sign of its second argument, `y`.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn copysign(x: f64, y: f64) -> f64 {
super::generic::copysign(x, y)
}
@ -31,7 +31,7 @@ pub fn copysign(x: f64, y: f64) -> f64 {
/// Constructs a number with the magnitude (absolute value) of its
/// first argument, `x`, and the sign of its second argument, `y`.
#[cfg(f128_enabled)]
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn copysignf128(x: f128, y: f128) -> f128 {
super::generic::copysign(x, y)
}

View file

@ -45,7 +45,7 @@ use super::{k_cos, k_sin, rem_pio2};
/// The cosine of `x` (f64).
///
/// `x` is specified in radians.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn cos(x: f64) -> f64 {
let ix = (f64::to_bits(x) >> 32) as u32 & 0x7fffffff;

View file

@ -27,7 +27,7 @@ const C4_PIO2: f64 = 4. * FRAC_PI_2; /* 0x401921FB, 0x54442D18 */
/// The cosine of `x` (f32).
///
/// `x` is specified in radians.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn cosf(x: f32) -> f32 {
let x64 = x as f64;

View file

@ -5,7 +5,7 @@ use super::{exp, expm1, k_expo2};
/// Computes the hyperbolic cosine of the argument x.
/// Is defined as `(exp(x) + exp(-x))/2`
/// Angles are specified in radians.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn cosh(mut x: f64) -> f64 {
/* |x| */
let mut ix = x.to_bits();

View file

@ -5,7 +5,7 @@ use super::{expf, expm1f, k_expo2f};
/// Computes the hyperbolic cosine of the argument x.
/// Is defined as `(exp(x) + exp(-x))/2`
/// Angles are specified in radians.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn coshf(mut x: f32) -> f32 {
let x1p120 = f32::from_bits(0x7b800000); // 0x1p120f === 2 ^ 120

View file

@ -219,7 +219,7 @@ fn erfc2(ix: u32, mut x: f64) -> f64 {
/// Calculates an approximation to the “error function”, which estimates
/// the probability that an observation will fall within x standard
/// deviations of the mean (assuming a normal distribution).
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn erf(x: f64) -> f64 {
let r: f64;
let s: f64;

View file

@ -130,7 +130,7 @@ fn erfc2(mut ix: u32, mut x: f32) -> f32 {
/// Calculates an approximation to the “error function”, which estimates
/// the probability that an observation will fall within x standard
/// deviations of the mean (assuming a normal distribution).
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn erff(x: f32) -> f32 {
let r: f32;
let s: f32;

View file

@ -81,7 +81,7 @@ const P5: f64 = 4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */
///
/// Calculate the exponential of `x`, that is, *e* raised to the power `x`
/// (where *e* is the base of the natural system of logarithms, approximately 2.71828).
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn exp(mut x: f64) -> f64 {
let x1p1023 = f64::from_bits(0x7fe0000000000000); // 0x1p1023 === 2 ^ 1023
let x1p_149 = f64::from_bits(0x36a0000000000000); // 0x1p-149 === 2 ^ -149

View file

@ -7,7 +7,7 @@ const P10: &[f64] = &[
];
/// Calculates 10 raised to the power of `x` (f64).
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn exp10(x: f64) -> f64 {
let (mut y, n) = modf(x);
let u: u64 = n.to_bits();

View file

@ -7,7 +7,7 @@ const P10: &[f32] = &[
];
/// Calculates 10 raised to the power of `x` (f32).
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn exp10f(x: f32) -> f32 {
let (mut y, n) = modff(x);
let u = n.to_bits();

View file

@ -322,7 +322,7 @@ static TBL: [u64; TBLSIZE * 2] = [
/// Exponential, base 2 (f64)
///
/// Calculate `2^x`, that is, 2 raised to the power `x`.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn exp2(mut x: f64) -> f64 {
let redux = f64::from_bits(0x4338000000000000) / TBLSIZE as f64;
let p1 = f64::from_bits(0x3fe62e42fefa39ef);

View file

@ -73,7 +73,7 @@ static EXP2FT: [u64; TBLSIZE] = [
/// Exponential, base 2 (f32)
///
/// Calculate `2^x`, that is, 2 raised to the power `x`.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn exp2f(mut x: f32) -> f32 {
let redux = f32::from_bits(0x4b400000) / TBLSIZE as f32;
let p1 = f32::from_bits(0x3f317218);

View file

@ -30,7 +30,7 @@ const P2: f32 = -2.7667332906e-3; /* -0xb55215.0p-32 */
///
/// Calculate the exponential of `x`, that is, *e* raised to the power `x`
/// (where *e* is the base of the natural system of logarithms, approximately 2.71828).
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn expf(mut x: f32) -> f32 {
let x1p127 = f32::from_bits(0x7f000000); // 0x1p127f === 2 ^ 127
let x1p_126 = f32::from_bits(0x800000); // 0x1p-126f === 2 ^ -126 /*original 0x1p-149f ??????????? */

View file

@ -30,7 +30,7 @@ const Q5: f64 = -2.01099218183624371326e-07; /* BE8AFDB7 6E09C32D */
/// system of logarithms, approximately 2.71828).
/// The result is accurate even for small values of `x`,
/// where using `exp(x)-1` would lose many significant digits.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn expm1(mut x: f64) -> f64 {
let hi: f64;
let lo: f64;

View file

@ -32,7 +32,7 @@ const Q2: f32 = 1.5807170421e-3; /* 0xcf3010.0p-33 */
/// system of logarithms, approximately 2.71828).
/// The result is accurate even for small values of `x`,
/// where using `exp(x)-1` would lose many significant digits.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn expm1f(mut x: f32) -> f32 {
let x1p127 = f32::from_bits(0x7f000000); // 0x1p127f === 2 ^ 127

View file

@ -1,7 +1,7 @@
use super::{combine_words, exp};
/* exp(x)/2 for x >= log(DBL_MAX), slightly better than 0.5*exp(x/2)*exp(x/2) */
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub(crate) fn expo2(x: f64) -> f64 {
/* k is such that k*ln2 has minimal relative error and x - kln2 > log(DBL_MIN) */
const K: i32 = 2043;

View file

@ -3,7 +3,7 @@
/// Calculates the absolute value (magnitude) of the argument `x`,
/// by direct manipulation of the bit representation of `x`.
#[cfg(f16_enabled)]
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fabsf16(x: f16) -> f16 {
super::generic::fabs(x)
}
@ -12,7 +12,7 @@ pub fn fabsf16(x: f16) -> f16 {
///
/// Calculates the absolute value (magnitude) of the argument `x`,
/// by direct manipulation of the bit representation of `x`.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fabsf(x: f32) -> f32 {
select_implementation! {
name: fabsf,
@ -27,7 +27,7 @@ pub fn fabsf(x: f32) -> f32 {
///
/// Calculates the absolute value (magnitude) of the argument `x`,
/// by direct manipulation of the bit representation of `x`.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fabs(x: f64) -> f64 {
select_implementation! {
name: fabs,
@ -43,7 +43,7 @@ pub fn fabs(x: f64) -> f64 {
/// Calculates the absolute value (magnitude) of the argument `x`,
/// by direct manipulation of the bit representation of `x`.
#[cfg(f128_enabled)]
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fabsf128(x: f128) -> f128 {
super::generic::fabs(x)
}

View file

@ -7,7 +7,7 @@
///
/// A range error may occur.
#[cfg(f16_enabled)]
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fdimf16(x: f16, y: f16) -> f16 {
super::generic::fdim(x, y)
}
@ -20,7 +20,7 @@ pub fn fdimf16(x: f16, y: f16) -> f16 {
/// * NAN if either argument is NAN.
///
/// A range error may occur.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fdimf(x: f32, y: f32) -> f32 {
super::generic::fdim(x, y)
}
@ -33,7 +33,7 @@ pub fn fdimf(x: f32, y: f32) -> f32 {
/// * NAN if either argument is NAN.
///
/// A range error may occur.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fdim(x: f64, y: f64) -> f64 {
super::generic::fdim(x, y)
}
@ -47,7 +47,7 @@ pub fn fdim(x: f64, y: f64) -> f64 {
///
/// A range error may occur.
#[cfg(f128_enabled)]
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fdimf128(x: f128, y: f128) -> f128 {
super::generic::fdim(x, y)
}

View file

@ -2,7 +2,7 @@
///
/// Finds the nearest integer less than or equal to `x`.
#[cfg(f16_enabled)]
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn floorf16(x: f16) -> f16 {
return super::generic::floor(x);
}
@ -10,7 +10,7 @@ pub fn floorf16(x: f16) -> f16 {
/// Floor (f64)
///
/// Finds the nearest integer less than or equal to `x`.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn floor(x: f64) -> f64 {
select_implementation! {
name: floor,
@ -25,7 +25,7 @@ pub fn floor(x: f64) -> f64 {
/// Floor (f32)
///
/// Finds the nearest integer less than or equal to `x`.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn floorf(x: f32) -> f32 {
select_implementation! {
name: floorf,
@ -40,7 +40,7 @@ pub fn floorf(x: f32) -> f32 {
///
/// Finds the nearest integer less than or equal to `x`.
#[cfg(f128_enabled)]
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn floorf128(x: f128) -> f128 {
return super::generic::floor(x);
}

View file

@ -7,7 +7,7 @@ use crate::support::Round;
// Placeholder so we can have `fmaf16` in the `Float` trait.
#[allow(unused)]
#[cfg(f16_enabled)]
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub(crate) fn fmaf16(_x: f16, _y: f16, _z: f16) -> f16 {
unimplemented!()
}
@ -15,7 +15,7 @@ pub(crate) fn fmaf16(_x: f16, _y: f16, _z: f16) -> f16 {
/// Floating multiply add (f32)
///
/// Computes `(x*y)+z`, rounded as one ternary operation (i.e. calculated with infinite precision).
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fmaf(x: f32, y: f32, z: f32) -> f32 {
select_implementation! {
name: fmaf,
@ -32,7 +32,7 @@ pub fn fmaf(x: f32, y: f32, z: f32) -> f32 {
/// Fused multiply add (f64)
///
/// Computes `(x*y)+z`, rounded as one ternary operation (i.e. calculated with infinite precision).
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fma(x: f64, y: f64, z: f64) -> f64 {
select_implementation! {
name: fma,
@ -50,7 +50,7 @@ pub fn fma(x: f64, y: f64, z: f64) -> f64 {
///
/// Computes `(x*y)+z`, rounded as one ternary operation (i.e. calculated with infinite precision).
#[cfg(f128_enabled)]
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fmaf128(x: f128, y: f128, z: f128) -> f128 {
generic::fma_round(x, y, z, Round::Nearest).val
}

View file

@ -3,7 +3,7 @@
/// This coincides with IEEE 754-2011 `minNum`. The result disregards signed zero (meaning if
/// the inputs are -0.0 and +0.0, either may be returned).
#[cfg(f16_enabled)]
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fminf16(x: f16, y: f16) -> f16 {
super::generic::fmin(x, y)
}
@ -12,7 +12,7 @@ pub fn fminf16(x: f16, y: f16) -> f16 {
///
/// This coincides with IEEE 754-2011 `minNum`. The result disregards signed zero (meaning if
/// the inputs are -0.0 and +0.0, either may be returned).
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fminf(x: f32, y: f32) -> f32 {
super::generic::fmin(x, y)
}
@ -21,7 +21,7 @@ pub fn fminf(x: f32, y: f32) -> f32 {
///
/// This coincides with IEEE 754-2011 `minNum`. The result disregards signed zero (meaning if
/// the inputs are -0.0 and +0.0, either may be returned).
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fmin(x: f64, y: f64) -> f64 {
super::generic::fmin(x, y)
}
@ -31,7 +31,7 @@ pub fn fmin(x: f64, y: f64) -> f64 {
/// This coincides with IEEE 754-2011 `minNum`. The result disregards signed zero (meaning if
/// the inputs are -0.0 and +0.0, either may be returned).
#[cfg(f128_enabled)]
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fminf128(x: f128, y: f128) -> f128 {
super::generic::fmin(x, y)
}
@ -41,7 +41,7 @@ pub fn fminf128(x: f128, y: f128) -> f128 {
/// This coincides with IEEE 754-2011 `maxNum`. The result disregards signed zero (meaning if
/// the inputs are -0.0 and +0.0, either may be returned).
#[cfg(f16_enabled)]
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fmaxf16(x: f16, y: f16) -> f16 {
super::generic::fmax(x, y)
}
@ -50,7 +50,7 @@ pub fn fmaxf16(x: f16, y: f16) -> f16 {
///
/// This coincides with IEEE 754-2011 `maxNum`. The result disregards signed zero (meaning if
/// the inputs are -0.0 and +0.0, either may be returned).
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fmaxf(x: f32, y: f32) -> f32 {
super::generic::fmax(x, y)
}
@ -59,7 +59,7 @@ pub fn fmaxf(x: f32, y: f32) -> f32 {
///
/// This coincides with IEEE 754-2011 `maxNum`. The result disregards signed zero (meaning if
/// the inputs are -0.0 and +0.0, either may be returned).
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fmax(x: f64, y: f64) -> f64 {
super::generic::fmax(x, y)
}
@ -69,7 +69,7 @@ pub fn fmax(x: f64, y: f64) -> f64 {
/// This coincides with IEEE 754-2011 `maxNum`. The result disregards signed zero (meaning if
/// the inputs are -0.0 and +0.0, either may be returned).
#[cfg(f128_enabled)]
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fmaxf128(x: f128, y: f128) -> f128 {
super::generic::fmax(x, y)
}

View file

@ -2,7 +2,7 @@
///
/// This coincides with IEEE 754-2019 `minimum`. The result orders -0.0 < 0.0.
#[cfg(f16_enabled)]
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fminimumf16(x: f16, y: f16) -> f16 {
super::generic::fminimum(x, y)
}
@ -10,7 +10,7 @@ pub fn fminimumf16(x: f16, y: f16) -> f16 {
/// Return the lesser of two arguments or, if either argument is NaN, the other argument.
///
/// This coincides with IEEE 754-2019 `minimum`. The result orders -0.0 < 0.0.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fminimum(x: f64, y: f64) -> f64 {
super::generic::fminimum(x, y)
}
@ -18,7 +18,7 @@ pub fn fminimum(x: f64, y: f64) -> f64 {
/// Return the lesser of two arguments or, if either argument is NaN, the other argument.
///
/// This coincides with IEEE 754-2019 `minimum`. The result orders -0.0 < 0.0.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fminimumf(x: f32, y: f32) -> f32 {
super::generic::fminimum(x, y)
}
@ -27,7 +27,7 @@ pub fn fminimumf(x: f32, y: f32) -> f32 {
///
/// This coincides with IEEE 754-2019 `minimum`. The result orders -0.0 < 0.0.
#[cfg(f128_enabled)]
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fminimumf128(x: f128, y: f128) -> f128 {
super::generic::fminimum(x, y)
}
@ -36,7 +36,7 @@ pub fn fminimumf128(x: f128, y: f128) -> f128 {
///
/// This coincides with IEEE 754-2019 `maximum`. The result orders -0.0 < 0.0.
#[cfg(f16_enabled)]
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fmaximumf16(x: f16, y: f16) -> f16 {
super::generic::fmaximum(x, y)
}
@ -44,7 +44,7 @@ pub fn fmaximumf16(x: f16, y: f16) -> f16 {
/// Return the greater of two arguments or, if either argument is NaN, the other argument.
///
/// This coincides with IEEE 754-2019 `maximum`. The result orders -0.0 < 0.0.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fmaximumf(x: f32, y: f32) -> f32 {
super::generic::fmaximum(x, y)
}
@ -52,7 +52,7 @@ pub fn fmaximumf(x: f32, y: f32) -> f32 {
/// Return the greater of two arguments or, if either argument is NaN, the other argument.
///
/// This coincides with IEEE 754-2019 `maximum`. The result orders -0.0 < 0.0.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fmaximum(x: f64, y: f64) -> f64 {
super::generic::fmaximum(x, y)
}
@ -61,7 +61,7 @@ pub fn fmaximum(x: f64, y: f64) -> f64 {
///
/// This coincides with IEEE 754-2019 `maximum`. The result orders -0.0 < 0.0.
#[cfg(f128_enabled)]
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fmaximumf128(x: f128, y: f128) -> f128 {
super::generic::fmaximum(x, y)
}

View file

@ -2,7 +2,7 @@
///
/// This coincides with IEEE 754-2019 `minimumNumber`. The result orders -0.0 < 0.0.
#[cfg(f16_enabled)]
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fminimum_numf16(x: f16, y: f16) -> f16 {
super::generic::fminimum_num(x, y)
}
@ -10,7 +10,7 @@ pub fn fminimum_numf16(x: f16, y: f16) -> f16 {
/// Return the lesser of two arguments or, if either argument is NaN, NaN.
///
/// This coincides with IEEE 754-2019 `minimumNumber`. The result orders -0.0 < 0.0.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fminimum_numf(x: f32, y: f32) -> f32 {
super::generic::fminimum_num(x, y)
}
@ -18,7 +18,7 @@ pub fn fminimum_numf(x: f32, y: f32) -> f32 {
/// Return the lesser of two arguments or, if either argument is NaN, NaN.
///
/// This coincides with IEEE 754-2019 `minimumNumber`. The result orders -0.0 < 0.0.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fminimum_num(x: f64, y: f64) -> f64 {
super::generic::fminimum_num(x, y)
}
@ -27,7 +27,7 @@ pub fn fminimum_num(x: f64, y: f64) -> f64 {
///
/// This coincides with IEEE 754-2019 `minimumNumber`. The result orders -0.0 < 0.0.
#[cfg(f128_enabled)]
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fminimum_numf128(x: f128, y: f128) -> f128 {
super::generic::fminimum_num(x, y)
}
@ -36,7 +36,7 @@ pub fn fminimum_numf128(x: f128, y: f128) -> f128 {
///
/// This coincides with IEEE 754-2019 `maximumNumber`. The result orders -0.0 < 0.0.
#[cfg(f16_enabled)]
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fmaximum_numf16(x: f16, y: f16) -> f16 {
super::generic::fmaximum_num(x, y)
}
@ -44,7 +44,7 @@ pub fn fmaximum_numf16(x: f16, y: f16) -> f16 {
/// Return the greater of two arguments or, if either argument is NaN, NaN.
///
/// This coincides with IEEE 754-2019 `maximumNumber`. The result orders -0.0 < 0.0.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fmaximum_numf(x: f32, y: f32) -> f32 {
super::generic::fmaximum_num(x, y)
}
@ -52,7 +52,7 @@ pub fn fmaximum_numf(x: f32, y: f32) -> f32 {
/// Return the greater of two arguments or, if either argument is NaN, NaN.
///
/// This coincides with IEEE 754-2019 `maximumNumber`. The result orders -0.0 < 0.0.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fmaximum_num(x: f64, y: f64) -> f64 {
super::generic::fmaximum_num(x, y)
}
@ -61,7 +61,7 @@ pub fn fmaximum_num(x: f64, y: f64) -> f64 {
///
/// This coincides with IEEE 754-2019 `maximumNumber`. The result orders -0.0 < 0.0.
#[cfg(f128_enabled)]
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fmaximum_numf128(x: f128, y: f128) -> f128 {
super::generic::fmaximum_num(x, y)
}

View file

@ -1,25 +1,25 @@
/// Calculate the remainder of `x / y`, the precise result of `x - trunc(x / y) * y`.
#[cfg(f16_enabled)]
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fmodf16(x: f16, y: f16) -> f16 {
super::generic::fmod(x, y)
}
/// Calculate the remainder of `x / y`, the precise result of `x - trunc(x / y) * y`.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fmodf(x: f32, y: f32) -> f32 {
super::generic::fmod(x, y)
}
/// Calculate the remainder of `x / y`, the precise result of `x - trunc(x / y) * y`.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fmod(x: f64, y: f64) -> f64 {
super::generic::fmod(x, y)
}
/// Calculate the remainder of `x / y`, the precise result of `x - trunc(x / y) * y`.
#[cfg(f128_enabled)]
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn fmodf128(x: f128, y: f128) -> f128 {
super::generic::fmod(x, y)
}

View file

@ -1,4 +1,4 @@
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn frexp(x: f64) -> (f64, i32) {
let mut y = x.to_bits();
let ee = ((y >> 52) & 0x7ff) as i32;

View file

@ -1,4 +1,4 @@
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn frexpf(x: f32) -> (f32, i32) {
let mut y = x.to_bits();
let ee: i32 = ((y >> 23) & 0xff) as i32;

View file

@ -17,7 +17,7 @@ fn sq(x: f64) -> (f64, f64) {
(hi, lo)
}
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn hypot(mut x: f64, mut y: f64) -> f64 {
let x1p700 = f64::from_bits(0x6bb0000000000000); // 0x1p700 === 2 ^ 700
let x1p_700 = f64::from_bits(0x1430000000000000); // 0x1p-700 === 2 ^ -700

View file

@ -2,7 +2,7 @@ use core::f32;
use super::sqrtf;
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn hypotf(mut x: f32, mut y: f32) -> f32 {
let x1p90 = f32::from_bits(0x6c800000); // 0x1p90f === 2 ^ 90
let x1p_90 = f32::from_bits(0x12800000); // 0x1p-90f === 2 ^ -90

View file

@ -1,7 +1,7 @@
const FP_ILOGBNAN: i32 = -1 - 0x7fffffff;
const FP_ILOGB0: i32 = FP_ILOGBNAN;
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn ilogb(x: f64) -> i32 {
let mut i: u64 = x.to_bits();
let e = ((i >> 52) & 0x7ff) as i32;

View file

@ -1,7 +1,7 @@
const FP_ILOGBNAN: i32 = -1 - 0x7fffffff;
const FP_ILOGB0: i32 = FP_ILOGBNAN;
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
pub fn ilogbf(x: f32) -> i32 {
let mut i = x.to_bits();
let e = ((i >> 23) & 0xff) as i32;

Some files were not shown because too many files have changed in this diff Show more