Skip to content

Commit

Permalink
Enable more targets on CI
Browse files Browse the repository at this point in the history
This brings the targets tested here in line with those tested in
`compiler-builtins`.
  • Loading branch information
tgross35 committed Oct 25, 2024
1 parent 84c6c54 commit 12bf64a
Show file tree
Hide file tree
Showing 4 changed files with 208 additions and 56 deletions.
130 changes: 101 additions & 29 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,114 @@ name: CI
on: [push, pull_request]

env:
CARGO_TERM_VERBOSE: true
RUSTDOCFLAGS: -Dwarnings
RUSTFLAGS: -Dwarnings
RUST_BACKTRACE: full

jobs:
docker:
name: Docker
runs-on: ubuntu-latest
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
target:
- aarch64-unknown-linux-gnu
- arm-unknown-linux-gnueabi
- arm-unknown-linux-gnueabihf
- armv7-unknown-linux-gnueabihf
# - i686-unknown-linux-gnu
# MIPS targets disabled since they are dropped to tier 3.
# See https://github.com/rust-lang/compiler-team/issues/648
#- mips-unknown-linux-gnu
#- mips64-unknown-linux-gnuabi64
#- mips64el-unknown-linux-gnuabi64
- powerpc-unknown-linux-gnu
- powerpc64-unknown-linux-gnu
- powerpc64le-unknown-linux-gnu
- x86_64-unknown-linux-gnu
include:
- target: aarch64-apple-darwin
os: macos-latest
- target: aarch64-unknown-linux-gnu
os: ubuntu-latest
- target: aarch64-pc-windows-msvc
os: windows-latest
build_only: 1
- target: arm-unknown-linux-gnueabi
os: ubuntu-latest
- target: arm-unknown-linux-gnueabihf
os: ubuntu-latest
- target: armv7-unknown-linux-gnueabihf
os: ubuntu-latest
- target: i586-unknown-linux-gnu
os: ubuntu-latest
- target: i686-unknown-linux-gnu
os: ubuntu-latest
- target: powerpc-unknown-linux-gnu
os: ubuntu-latest
- target: powerpc64-unknown-linux-gnu
os: ubuntu-latest
- target: powerpc64le-unknown-linux-gnu
os: ubuntu-latest
- target: riscv64gc-unknown-linux-gnu
os: ubuntu-latest
- target: thumbv6m-none-eabi
os: ubuntu-latest
- target: thumbv7em-none-eabi
os: ubuntu-latest
- target: thumbv7em-none-eabihf
os: ubuntu-latest
- target: thumbv7m-none-eabi
os: ubuntu-latest
- target: x86_64-unknown-linux-gnu
os: ubuntu-latest
- target: x86_64-apple-darwin
os: macos-13
- target: i686-pc-windows-msvc
os: windows-latest
- target: x86_64-pc-windows-msvc
os: windows-latest
- target: i686-pc-windows-gnu
os: windows-latest
channel: nightly-i686-gnu
- target: x86_64-pc-windows-gnu
os: windows-latest
channel: nightly-x86_64-gnu
runs-on: ${{ matrix.os }}
env:
BUILD_ONLY: ${{ matrix.build_only }}
steps:
- uses: actions/checkout@master
- name: Install Rust
run: rustup update nightly && rustup default nightly
- run: rustup target add ${{ matrix.target }}
- run: rustup target add x86_64-unknown-linux-musl
- run: cargo generate-lockfile
- run: ./ci/run-docker.sh ${{ matrix.target }}
- name: Print runner information
run: uname -a
- uses: actions/checkout@v4
- name: Install Rust (rustup)
shell: bash
run: |
channel="nightly"
# Account for channels that have required components (MinGW)
[ -n "${{ matrix.channel }}" ] && channel="${{ matrix.channel }}"
rustup update "$channel" --no-self-update
rustup default "$channel"
rustup target add ${{ matrix.target }}
rustup component add llvm-tools-preview
- uses: Swatinem/rust-cache@v2
with:
key: ${{ matrix.target }}

- name: Download musl source
run: ./ci/download-musl.sh
shell: bash

# Non-linux tests just use our raw script
- name: Run locally
if: matrix.os != 'ubuntu-latest'
shell: bash
run: ./ci/run.sh ${{ matrix.target }}

# Otherwise we use our docker containers to run builds
- name: Run in Docker
if: matrix.os == 'ubuntu-latest'
run: |
rustup target add x86_64-unknown-linux-musl
cargo generate-lockfile && ./ci/run-docker.sh ${{ matrix.target }}
rustfmt:
name: Rustfmt
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Install Rust
run: rustup update stable && rustup default stable && rustup component add rustfmt
run: |
rustup update stable --no-self-update
rustup default stable
rustup component add rustfmt
- run: cargo fmt -- --check

wasm:
Expand All @@ -50,17 +118,19 @@ jobs:
steps:
- uses: actions/checkout@master
- name: Install Rust
run: rustup update nightly && rustup default nightly
run: rustup update nightly --no-self-update && rustup default nightly
- run: rustup target add wasm32-unknown-unknown
- name: Download MUSL source
run: ./ci/download-musl.sh
- run: cargo build --target wasm32-unknown-unknown

cb:
builtins:
name: "The compiler-builtins crate works"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Install Rust
run: rustup update nightly && rustup default nightly
run: rustup update nightly --no-self-update && rustup default nightly
- run: cargo build -p cb

benchmarks:
Expand All @@ -69,15 +139,17 @@ jobs:
steps:
- uses: actions/checkout@master
- name: Install Rust
run: rustup update nightly && rustup default nightly
run: rustup update nightly --no-self-update && rustup default nightly
- name: Download MUSL source
run: ./ci/download-musl.sh
- run: cargo bench --all

success:
needs:
- docker
- rustfmt
- wasm
- cb
- builtins
- benchmarks
runs-on: ubuntu-latest
# GitHub branch protection is exceedingly silly and treats "jobs skipped because a dependency
Expand Down
69 changes: 56 additions & 13 deletions ci/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,64 @@

set -eux

target="$1"
export RUST_BACKTRACE="${RUST_BACKTRACE:-full}"
# Needed for no-panic to correct detect a lack of panics
export RUSTFLAGS="${RUSTFLAGS:-} -Ccodegen-units=1"

cmd="cargo test --all --target $target"
target="${1:-}"

# Needed for no-panic to correct detect a lack of panics
export RUSTFLAGS="$RUSTFLAGS -Ccodegen-units=1"
if [ -z "$target" ]; then
host_target=$(rustc -vV | awk '/^host/ { print $2 }')
echo "Defaulted to host target $host_target"
target="$host_target"
fi

extra_flags=""

# We need to specifically skip tests for musl-math-sys on systems that can't
# build musl since otherwise `--all` will activate it.
case "$target" in
# Can't build at all on MSVC, WASM, or thumb
*windows-msvc*) extra_flags="$extra_flags --exclude musl-math-sys" ;;
*wasm*) extra_flags="$extra_flags --exclude musl-math-sys" ;;
*thumb*) extra_flags="$extra_flags --exclude musl-math-sys" ;;

# We can build musl on MinGW but running tests gets a stack overflow
*windows-gnu*) ;;
# FIXME(#309): LE PPC crashes calling the musl version of some functions. It
# seems like a qemu bug but should be investigated further at some point.
# See <https://github.com/rust-lang/libm/issues/309>.
*powerpc64le*) ;;

# Everything else gets musl enabled
*) extra_flags="$extra_flags --features libm-test/build-musl" ;;
esac

# FIXME: `STATUS_DLL_NOT_FOUND` testing macros on CI.
# <https://github.com/rust-lang/rust/issues/128944>
case "$target" in
*windows-gnu) extra_flags="$extra_flags --exclude libm-macros" ;;
esac

if [ "$(uname -a)" = "Linux" ]; then
# also run the reference tests when we can. requires a Linux host.
extra_flags="$extra_flags --features libm-test/musl-bitwise-tests"
fi

if [ "${BUILD_ONLY:-}" = "1" ]; then
cmd="cargo build --target $target --package libm"
$cmd
$cmd --features 'unstable'

# stable by default
$cmd
$cmd --release
echo "no tests to run for no_std"
else
cmd="cargo test --all --target $target $extra_flags"

# unstable with a feature
$cmd --features 'unstable'
$cmd --release --features 'unstable'
# stable by default
$cmd
$cmd --release

# also run the reference tests
$cmd --features 'unstable libm-test/musl-bitwise-tests'
$cmd --release --features 'unstable libm-test/musl-bitwise-tests'
# unstable with a feature
$cmd --features 'unstable'
$cmd --release --features 'unstable'
fi
47 changes: 40 additions & 7 deletions crates/libm-test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,45 @@ pub fn musl_allowed_ulp(name: &str) -> u32 {
}
}

/// If only a few checks are incorrect, xfail them here rather than skipping the entire test.
pub fn xfail<F: Float>(actual: F, expected: F, ctx: &CheckCtx) -> bool {
match (&ctx.basis, ctx.fname) {
// FIXME(correctness): for large negative inputs (e.g.
// -1.7976931348623157e308), we return -NaN but musl says +NaN
(CheckBasis::Musl, "tgamma" | "tgammaf") if actual.is_nan() && expected.is_nan() => true,
_ => false,
/// Return the unsuffixed version of a function name; e.g. `abs` and `absf` both return `abs`,
/// `lgamma_r` and `lgammaf_r` both return `lgamma_r`.
pub fn canonical_name(name: &str) -> &str {
let known_mappings = &[
("erff", "erf"),
("erf", "erf"),
("lgammaf_r", "lgamma_r"),
("modff", "modf"),
("modf", "modf"),
];

match known_mappings.iter().find(|known| known.0 == name) {
Some(found) => found.1,
None => name
.strip_suffix("f")
.or_else(|| name.strip_suffix("f16"))
.or_else(|| name.strip_suffix("f128"))
.unwrap_or(name),
}
}

/// Allow customization of the checks run on floats.
///
/// If `None` is returned, checks should proceed as usual. If `Some(result)` is returned,
/// checks are skipped and the result is returned instead.
pub fn specialized_checks<F: Float>(
actual: F,
expected: F,
ctx: &CheckCtx,
) -> Option<anyhow::Result<()>> {
match ctx.canonical_name() {
"abs" | "copysign" if actual.is_nan() && expected.is_nan() => {
// abs and copysign require signaling NaNs to be preserved, so verify bit equality.
if actual.to_bits() == expected.to_bits() {
Some(Ok(()))
} else {
Some(Err(anyhow::anyhow!("NaNs have different bitpatterns")))
}
}
_ => None,
}
}
18 changes: 11 additions & 7 deletions crates/libm-test/src/test_traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ pub struct CheckCtx {
pub basis: CheckBasis,
}

impl CheckCtx {
/// Return the unsuffixed version of the function name.
pub fn canonical_name(&self) -> &'static str {
crate::canonical_name(self.fname)
}
}

/// Possible items to test against
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum CheckBasis {
Expand Down Expand Up @@ -140,17 +147,14 @@ where
fn validate<'a>(self, expected: Self, input: Input, ctx: &CheckCtx) -> anyhow::Result<()> {
// Create a wrapper function so we only need to `.with_context` once.
let inner = || -> anyhow::Result<()> {
if crate::xfail(self, expected, ctx) {
return Ok(());
// If the tested function requires a nonstandard test, run it here.
if let Some(res) = crate::specialized_checks(self, expected, ctx) {
return res;
}

// Check when both are NaNs
if self.is_nan() && expected.is_nan() {
ensure!(
self.to_bits() == expected.to_bits(),
"NaNs have different bitpatterns"
);
// Nothing else to check
// By default, NaNs have nothing special to check.
return Ok(());
} else if self.is_nan() || expected.is_nan() {
// Check when only one is a NaN
Expand Down

0 comments on commit 12bf64a

Please sign in to comment.