diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b0d476f0e2..b852110a32 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -249,6 +249,42 @@ jobs: env: TARGET: ${{ matrix.target.tuple }} + intrinsic-test: + needs: [style] + name: Intrinsic Test + runs-on: ubuntu-latest + strategy: + matrix: + target: + - aarch64-unknown-linux-gnu + - aarch64_be-unknown-linux-gnu + - armv7-unknown-linux-gnueabihf + - arm-unknown-linux-gnueabihf + profile: [dev, release] + include: + - target: aarch64_be-unknown-linux-gnu + build_std: true + + steps: + - uses: actions/checkout@v4 + - name: Install Rust + run: | + rustup update nightly --no-self-update + rustup default nightly + - run: rustup target add ${{ matrix.target }} + if: ${{ (matrix.build_std || false) == false }} + - run: | + rustup component add rust-src + echo "CARGO_UNSTABLE_BUILD_STD=std" >> $GITHUB_ENV + if: ${{ matrix.build_std }} + + # Configure some env vars based on matrix configuration + - run: echo "PROFILE=--profile=${{ matrix.profile }}" >> $GITHUB_ENV + - run: ./ci/intrinsic-test-docker.sh ${{ matrix.target }} + if: ${{ !startsWith(matrix.target, 'thumb') }} + env: + TARGET: ${{ matrix.target }} + # Check that the generated files agree with the checked-in versions. check-stdarch-gen: needs: [style] @@ -276,6 +312,7 @@ jobs: - docs - verify - test + - intrinsic-test - check-stdarch-gen runs-on: ubuntu-latest # We need to ensure this job does *not* get skipped if its dependencies fail, diff --git a/ci/intrinsic-test-docker.sh b/ci/intrinsic-test-docker.sh new file mode 100755 index 0000000000..038fc4678e --- /dev/null +++ b/ci/intrinsic-test-docker.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env sh + +# Small script to run tests for a target (or all targets) inside all the +# respective docker images. + +set -ex + +if [ $# -lt 1 ]; then + >&2 echo "Usage: $0 " + exit 1 +fi + +run() { + # Set the linker that is used for the host (e.g. when compiling a build.rs) + # This overrides any configuration in e.g. `.cargo/config.toml`, which will + # probably not work within the docker container. + HOST_LINKER="CARGO_TARGET_$(rustc --print host-tuple | tr '[:lower:]-' '[:upper:]_')_LINKER" + + # Prevent `Read-only file system (os error 30)`. + cargo generate-lockfile + + echo "Building docker container for TARGET=${1}" + docker build -t stdarch -f "ci/docker/${1}/Dockerfile" ci/ + mkdir -p target c_programs rust_programs + echo "Running docker" + # shellcheck disable=SC2016 + docker run \ + --rm \ + --user "$(id -u)":"$(id -g)" \ + --env CARGO_HOME=/cargo \ + --env CARGO_TARGET_DIR=/checkout/target \ + --env TARGET="${1}" \ + --env "${HOST_LINKER}"="cc" \ + --env STDARCH_DISABLE_ASSERT_INSTR \ + --env NOSTD \ + --env NORUN \ + --env RUSTFLAGS \ + --env CARGO_UNSTABLE_BUILD_STD \ + --volume "${HOME}/.cargo":/cargo \ + --volume "$(rustc --print sysroot)":/rust:ro \ + --volume "$(pwd)":/checkout:ro \ + --volume "$(pwd)"/target:/checkout/target \ + --volume "$(pwd)"/c_programs:/checkout/c_programs \ + --volume "$(pwd)"/rust_programs:/checkout/rust_programs \ + --init \ + --workdir /checkout \ + --privileged \ + stdarch \ + sh -c "HOME=/tmp PATH=\$PATH:/rust/bin exec ci/intrinsic-test.sh ${1}" +} + +if [ -z "$1" ]; then + >&2 echo "No target specified!" + exit 1 +else + run "${1}" +fi diff --git a/ci/intrinsic-test.sh b/ci/intrinsic-test.sh new file mode 100755 index 0000000000..469e9e21c7 --- /dev/null +++ b/ci/intrinsic-test.sh @@ -0,0 +1,99 @@ +#!/usr/bin/env sh + +set -ex + +: "${TARGET?The TARGET environment variable must be set.}" + +export RUSTFLAGS="${RUSTFLAGS} -D warnings -Z merge-functions=disabled -Z verify-llvm-ir" +export HOST_RUSTFLAGS="${RUSTFLAGS}" +export PROFILE="${PROFILE:="--profile=release"}" + +case ${TARGET} in + # On 32-bit use a static relocation model which avoids some extra + # instructions when dealing with static data, notably allowing some + # instruction assertion checks to pass below the 20 instruction limit. If + # this is the default, dynamic, then too many instructions are generated + # when we assert the instruction for a function and it causes tests to fail. + i686-* | i586-*) + export RUSTFLAGS="${RUSTFLAGS} -C relocation-model=static" + ;; + # Some x86_64 targets enable by default more features beyond SSE2, + # which cause some instruction assertion checks to fail. + x86_64-*) + export RUSTFLAGS="${RUSTFLAGS} -C target-feature=-sse3" + ;; + #Unoptimized build uses fast-isel which breaks with msa + mips-* | mipsel-*) + export RUSTFLAGS="${RUSTFLAGS} -C llvm-args=-fast-isel=false" + ;; + armv7-*eabihf | thumbv7-*eabihf) + export RUSTFLAGS="${RUSTFLAGS} -Ctarget-feature=+neon" + ;; + # Some of our test dependencies use the deprecated `gcc` crates which + # doesn't detect RISC-V compilers automatically, so do it manually here. + riscv*) + export RUSTFLAGS="${RUSTFLAGS} -Ctarget-feature=+zk,+zks,+zbb,+zbc" + ;; +esac + +echo "RUSTFLAGS=${RUSTFLAGS}" +echo "OBJDUMP=${OBJDUMP}" +echo "PROFILE=${PROFILE}" + +INTRINSIC_TEST="--manifest-path=crates/intrinsic-test/Cargo.toml" + +# Test targets compiled with extra features. +case ${TARGET} in + # Setup aarch64 & armv7 specific variables, the runner, along with some + # tests to skip + aarch64-unknown-linux-gnu*) + TEST_CPPFLAGS="-fuse-ld=lld -I/usr/aarch64-linux-gnu/include/ -I/usr/aarch64-linux-gnu/include/c++/9/aarch64-linux-gnu/" + TEST_SKIP_INTRINSICS=crates/intrinsic-test/missing_aarch64.txt + TEST_CXX_COMPILER="clang++" + TEST_RUNNER="${CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUNNER}" + ;; + + aarch64_be-unknown-linux-gnu*) + TEST_CPPFLAGS="-fuse-ld=lld" + TEST_SKIP_INTRINSICS=crates/intrinsic-test/missing_aarch64.txt + TEST_CXX_COMPILER="clang++" + TEST_RUNNER="${CARGO_TARGET_AARCH64_BE_UNKNOWN_LINUX_GNU_RUNNER}" + ;; + + armv7-unknown-linux-gnueabihf*) + TEST_CPPFLAGS="-fuse-ld=lld -I/usr/arm-linux-gnueabihf/include/ -I/usr/arm-linux-gnueabihf/include/c++/9/arm-linux-gnueabihf/" + TEST_SKIP_INTRINSICS=crates/intrinsic-test/missing_arm.txt + TEST_CXX_COMPILER="clang++" + TEST_RUNNER="${CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_RUNNER}" + ;; + *) + ;; + +esac + +# Arm specific +case "${TARGET}" in + aarch64-unknown-linux-gnu*|armv7-unknown-linux-gnueabihf*) + CPPFLAGS="${TEST_CPPFLAGS}" RUSTFLAGS="${HOST_RUSTFLAGS}" RUST_LOG=warn \ + cargo run "${INTRINSIC_TEST}" "${PROFILE}" \ + --bin intrinsic-test -- intrinsics_data/arm_intrinsics.json \ + --runner "${TEST_RUNNER}" \ + --cppcompiler "${TEST_CXX_COMPILER}" \ + --skip "${TEST_SKIP_INTRINSICS}" \ + --target "${TARGET}" + ;; + + aarch64_be-unknown-linux-gnu*) + CPPFLAGS="${TEST_CPPFLAGS}" RUSTFLAGS="${HOST_RUSTFLAGS}" RUST_LOG=warn \ + cargo run "${INTRINSIC_TEST}" "${PROFILE}" \ + --bin intrinsic-test -- intrinsics_data/arm_intrinsics.json \ + --runner "${TEST_RUNNER}" \ + --cppcompiler "${TEST_CXX_COMPILER}" \ + --skip "${TEST_SKIP_INTRINSICS}" \ + --target "${TARGET}" \ + --linker "${CARGO_TARGET_AARCH64_BE_UNKNOWN_LINUX_GNU_LINKER}" \ + --cxx-toolchain-dir "${AARCH64_BE_TOOLCHAIN}" + ;; + *) + ;; +esac diff --git a/ci/run.sh b/ci/run.sh index aa4479395d..2bb77bae25 100755 --- a/ci/run.sh +++ b/ci/run.sh @@ -79,7 +79,6 @@ cargo_test() { CORE_ARCH="--manifest-path=crates/core_arch/Cargo.toml" STDARCH_EXAMPLES="--manifest-path=examples/Cargo.toml" -INTRINSIC_TEST="--manifest-path=crates/intrinsic-test/Cargo.toml" cargo_test "${CORE_ARCH} ${PROFILE}" @@ -130,61 +129,11 @@ case ${TARGET} in export RUSTFLAGS="${RUSTFLAGS} -C target-feature=+altivec" cargo_test "${PROFILE}" ;; - - # Setup aarch64 & armv7 specific variables, the runner, along with some - # tests to skip - aarch64-unknown-linux-gnu*) - TEST_CPPFLAGS="-fuse-ld=lld -I/usr/aarch64-linux-gnu/include/ -I/usr/aarch64-linux-gnu/include/c++/9/aarch64-linux-gnu/" - TEST_SKIP_INTRINSICS=crates/intrinsic-test/missing_aarch64.txt - TEST_CXX_COMPILER="clang++" - TEST_RUNNER="${CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUNNER}" - ;; - - aarch64_be-unknown-linux-gnu*) - TEST_CPPFLAGS="-fuse-ld=lld" - TEST_SKIP_INTRINSICS=crates/intrinsic-test/missing_aarch64.txt - TEST_CXX_COMPILER="clang++" - TEST_RUNNER="${CARGO_TARGET_AARCH64_BE_UNKNOWN_LINUX_GNU_RUNNER}" - ;; - - armv7-unknown-linux-gnueabihf*) - TEST_CPPFLAGS="-fuse-ld=lld -I/usr/arm-linux-gnueabihf/include/ -I/usr/arm-linux-gnueabihf/include/c++/9/arm-linux-gnueabihf/" - TEST_SKIP_INTRINSICS=crates/intrinsic-test/missing_arm.txt - TEST_CXX_COMPILER="clang++" - TEST_RUNNER="${CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_RUNNER}" - ;; *) ;; esac -# Arm specific -case "${TARGET}" in - aarch64-unknown-linux-gnu*|armv7-unknown-linux-gnueabihf*) - CPPFLAGS="${TEST_CPPFLAGS}" RUSTFLAGS="${HOST_RUSTFLAGS}" RUST_LOG=warn \ - cargo run "${INTRINSIC_TEST}" "${PROFILE}" \ - --bin intrinsic-test -- intrinsics_data/arm_intrinsics.json \ - --runner "${TEST_RUNNER}" \ - --cppcompiler "${TEST_CXX_COMPILER}" \ - --skip "${TEST_SKIP_INTRINSICS}" \ - --target "${TARGET}" - ;; - - aarch64_be-unknown-linux-gnu*) - CPPFLAGS="${TEST_CPPFLAGS}" RUSTFLAGS="${HOST_RUSTFLAGS}" RUST_LOG=warn \ - cargo run "${INTRINSIC_TEST}" "${PROFILE}" \ - --bin intrinsic-test -- intrinsics_data/arm_intrinsics.json \ - --runner "${TEST_RUNNER}" \ - --cppcompiler "${TEST_CXX_COMPILER}" \ - --skip "${TEST_SKIP_INTRINSICS}" \ - --target "${TARGET}" \ - --linker "${CARGO_TARGET_AARCH64_BE_UNKNOWN_LINUX_GNU_LINKER}" \ - --cxx-toolchain-dir "${AARCH64_BE_TOOLCHAIN}" - ;; - *) - ;; -esac - if [ "$NORUN" != "1" ] && [ "$NOSTD" != 1 ]; then # Test examples (