From 5a9a6d821bd82db71cc4e229417a46b0e9e3d665 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Thu, 13 Aug 2026 05:57:33 -0400 Subject: [PATCH 01/28] ci: Move dependency installs to a separate script --- .../.github/workflows/main.yaml | 17 ++------- .../compiler-builtins/ci/install-test-deps.sh | 38 +++++++++++++++++++ 2 files changed, 41 insertions(+), 14 deletions(-) create mode 100755 library/compiler-builtins/ci/install-test-deps.sh diff --git a/library/compiler-builtins/.github/workflows/main.yaml b/library/compiler-builtins/.github/workflows/main.yaml index 2ded0f6177d7b..dfbf5ddb03afd 100644 --- a/library/compiler-builtins/.github/workflows/main.yaml +++ b/library/compiler-builtins/.github/workflows/main.yaml @@ -132,22 +132,11 @@ jobs: lscpu || (sysctl -a | grep cpu) || true echo "home: ${HOME:-not found}" pwd - - # Native ppc and s390x runners don't have rustup by default - - name: Install rustup - if: matrix.os == 'ubuntu-26.04-ppc64le' || matrix.os == 'ubuntu-26.04-s390x' - run: sudo apt-get update && sudo apt-get install -y rustup - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: { persist-credentials: false } - - name: Install Rust (rustup) - run: | - channel="nightly" - # Account for channels that have required components (MinGW) - [ -n "$JOB_CHANNEL" ] && channel="$JOB_CHANNEL" - rustup update "$channel" --no-self-update - rustup default "$channel" - rustup target add "$JOB_TARGET" + + - name: Set up dependencies and Rust + run: ./ci/install-test-deps.sh "$JOB_TARGET" "$JOB_CHANNEL" "$RUN_IN_DOCKER" - uses: taiki-e/install-action@7f4eb899022d8fe70b20c4f3de697aa85c309026 # v2.85.11 with: diff --git a/library/compiler-builtins/ci/install-test-deps.sh b/library/compiler-builtins/ci/install-test-deps.sh new file mode 100755 index 0000000000000..7321e4c5d5440 --- /dev/null +++ b/library/compiler-builtins/ci/install-test-deps.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +set -eux + +target="${1}" + +# Allow setting a channel to account for required components (MinGW) +channel="${2:-nightly}" + +# Some runners (native ppc and s390x, self-hosted) don't have all the dependencies +# we need, so we need to install them. + +needed_deps=() +to_install=() + +if [ "$RUN_IN_DOCKER" != "0" ]; then + needed_deps+=(rustup m4) +fi + +for dep in "${needed_deps[@]}"; do + ! command -v "$dep" && to_install+=("$dep") +done + +if [ ${#to_install[@]} -ne 0 ]; then + if command -v apt-get; then + sudo apt-get update + sudo apt-get install -y "${to_install[@]}" + elif command -v apk; then + doas apk add "${to_install[@]}" + else + echo "No package manager found" + fi +fi + +# Install the correct Rust version +rustup update "$channel" --no-self-update +rustup default "$channel" +rustup target add "$target" From c2a81bf1485c23bbdbaa68b1ad4ff5d330e0a99b Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Mon, 17 Aug 2026 01:42:44 -0500 Subject: [PATCH 02/28] ci: Enable `CARGO_TERM_VERBOSE` --- library/compiler-builtins/.github/workflows/main.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/library/compiler-builtins/.github/workflows/main.yaml b/library/compiler-builtins/.github/workflows/main.yaml index dfbf5ddb03afd..646b9c0c16fd2 100644 --- a/library/compiler-builtins/.github/workflows/main.yaml +++ b/library/compiler-builtins/.github/workflows/main.yaml @@ -11,6 +11,7 @@ concurrency: env: CARGO_TERM_COLOR: always + CARGO_TERM_VERBOSE: true LIBM_BUILD_VERBOSE: true RUSTDOCFLAGS: -Dwarnings RUSTFLAGS: -Dwarnings From ca1a7c000456509e120a13e8c50d9449b70b70e8 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Mon, 17 Aug 2026 02:12:37 -0500 Subject: [PATCH 03/28] ci: Increase the timeout of MSRV builds The git registry now takes long enough to download that the 10 minute timeout is hit. --- library/compiler-builtins/.github/workflows/main.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/compiler-builtins/.github/workflows/main.yaml b/library/compiler-builtins/.github/workflows/main.yaml index 646b9c0c16fd2..cb6c56047d96d 100644 --- a/library/compiler-builtins/.github/workflows/main.yaml +++ b/library/compiler-builtins/.github/workflows/main.yaml @@ -335,7 +335,7 @@ jobs: msrv: name: Check libm MSRV runs-on: ubuntu-26.04 - timeout-minutes: 10 + timeout-minutes: 20 env: RUSTFLAGS: # No need to check warnings on old MSRV, unset `-Dwarnings` steps: @@ -348,7 +348,7 @@ jobs: rustup update "$msrv" --no-self-update && rustup default "$msrv" - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 - run: | - # FIXME(msrv): Remove the workspace Cargo.toml so 1.63 cargo doesn't see + # FIXME(msrv): Remove the workspace Cargo.toml so MSRV cargo doesn't see # `edition = "2024"` and get spooked. rm Cargo.toml cargo build --manifest-path libm/Cargo.toml From 90e14017fde1aa31db6c5e1de9cc8d281f02919a Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Mon, 17 Aug 2026 00:08:48 -0500 Subject: [PATCH 04/28] ci: Fix the command for local Docker use --- library/compiler-builtins/ci/run-docker.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/compiler-builtins/ci/run-docker.sh b/library/compiler-builtins/ci/run-docker.sh index 08f20b934acd5..5bf81bce13516 100755 --- a/library/compiler-builtins/ci/run-docker.sh +++ b/library/compiler-builtins/ci/run-docker.sh @@ -58,7 +58,7 @@ run() { "IMAGE=${DOCKER_BASE_IMAGE:-rustlang/rust:nightly}" ) run_args=(-v "compiler-builtins-cache:/builtins-target") - run_cmd="$run_cmd HOME=/tmp" "USING_CONTAINER_RUSTC=1" + run_cmd="$run_cmd HOME=/tmp USING_CONTAINER_RUSTC=1" fi if [ -d compiler-rt ]; then From d03ac90d3dbde8a95d8981c0b3354d974d69767e Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Mon, 17 Aug 2026 09:01:27 +0000 Subject: [PATCH 05/28] ci: Set `-Dlinker_messages` Since 1.97, linker warnings can be denied via rustc. --- 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 cb6c56047d96d..27ccbd7f3764d 100644 --- a/library/compiler-builtins/.github/workflows/main.yaml +++ b/library/compiler-builtins/.github/workflows/main.yaml @@ -14,7 +14,7 @@ env: CARGO_TERM_VERBOSE: true LIBM_BUILD_VERBOSE: true RUSTDOCFLAGS: -Dwarnings - RUSTFLAGS: -Dwarnings + RUSTFLAGS: -Dwarnings -Dlinker_messages RUST_BACKTRACE: full BENCHMARK_RUSTC: nightly-2026-08-05 # Pin the toolchain for reproducable results From 34ed943e7ce892a6a5a39b58fd5478c7210d1a37 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Mon, 17 Aug 2026 03:28:17 -0500 Subject: [PATCH 06/28] ci: Split and sort docker dependencies --- .../ci/docker/aarch64-unknown-linux-gnu/Dockerfile | 12 ++++++++---- .../ci/docker/arm-unknown-linux-gnueabi/Dockerfile | 11 +++++++---- .../docker/arm-unknown-linux-gnueabihf/Dockerfile | 11 +++++++---- .../armv7-unknown-linux-gnueabihf/Dockerfile | 11 +++++++---- .../ci/docker/i586-unknown-linux-gnu/Dockerfile | 9 ++++++--- .../ci/docker/i686-unknown-linux-gnu/Dockerfile | 9 ++++++--- .../loongarch64-unknown-linux-gnu/Dockerfile | 11 +++++++---- .../ci/docker/mips-unknown-linux-gnu/Dockerfile | 14 +++++++++----- .../mips64-unknown-linux-gnuabi64/Dockerfile | 5 ++--- .../mips64el-unknown-linux-gnuabi64/Dockerfile | 3 +-- .../ci/docker/mipsel-unknown-linux-gnu/Dockerfile | 13 ++++++++----- .../ci/docker/powerpc-unknown-linux-gnu/Dockerfile | 13 ++++++++----- .../docker/powerpc64-unknown-linux-gnu/Dockerfile | 14 +++++++++----- .../powerpc64le-unknown-linux-gnu/Dockerfile | 13 ++++++++----- .../docker/riscv64gc-unknown-linux-gnu/Dockerfile | 13 ++++++++----- .../ci/docker/thumbv6m-none-eabi/Dockerfile | 7 ++++--- .../ci/docker/thumbv7em-none-eabi/Dockerfile | 7 ++++--- .../ci/docker/thumbv7em-none-eabihf/Dockerfile | 7 ++++--- .../ci/docker/thumbv7m-none-eabi/Dockerfile | 7 ++++--- .../ci/docker/wasm32-unknown-unknown/Dockerfile | 8 +++++--- .../ci/docker/x86_64-unknown-linux-gnu/Dockerfile | 9 ++++++--- 21 files changed, 128 insertions(+), 79 deletions(-) diff --git a/library/compiler-builtins/ci/docker/aarch64-unknown-linux-gnu/Dockerfile b/library/compiler-builtins/ci/docker/aarch64-unknown-linux-gnu/Dockerfile index 30a13fc5de910..af3232a3aa0f7 100644 --- a/library/compiler-builtins/ci/docker/aarch64-unknown-linux-gnu/Dockerfile +++ b/library/compiler-builtins/ci/docker/aarch64-unknown-linux-gnu/Dockerfile @@ -1,10 +1,14 @@ ARG IMAGE=ubuntu:26.04 FROM $IMAGE -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - gcc libc6-dev ca-certificates \ - gcc-aarch64-linux-gnu m4 make libc6-dev-arm64-cross \ +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates \ + gcc \ + gcc-aarch64-linux-gnu \ + libc6-dev \ + libc6-dev-arm64-cross \ + m4 \ + make \ qemu-user ENV TOOLCHAIN_PREFIX=aarch64-linux-gnu- diff --git a/library/compiler-builtins/ci/docker/arm-unknown-linux-gnueabi/Dockerfile b/library/compiler-builtins/ci/docker/arm-unknown-linux-gnueabi/Dockerfile index 41ff36a49e3bb..2bd11ca870233 100644 --- a/library/compiler-builtins/ci/docker/arm-unknown-linux-gnueabi/Dockerfile +++ b/library/compiler-builtins/ci/docker/arm-unknown-linux-gnueabi/Dockerfile @@ -1,10 +1,13 @@ ARG IMAGE=ubuntu:26.04 FROM $IMAGE -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - gcc libc6-dev ca-certificates \ - gcc-arm-linux-gnueabi libc6-dev-armel-cross qemu-user +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates \ + gcc \ + gcc-arm-linux-gnueabi \ + libc6-dev \ + libc6-dev-armel-cross \ + qemu-user ENV TOOLCHAIN_PREFIX=arm-linux-gnueabi- ENV CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABI_LINKER="$TOOLCHAIN_PREFIX"gcc \ diff --git a/library/compiler-builtins/ci/docker/arm-unknown-linux-gnueabihf/Dockerfile b/library/compiler-builtins/ci/docker/arm-unknown-linux-gnueabihf/Dockerfile index 1fad72c470f03..1e50e293d1183 100644 --- a/library/compiler-builtins/ci/docker/arm-unknown-linux-gnueabihf/Dockerfile +++ b/library/compiler-builtins/ci/docker/arm-unknown-linux-gnueabihf/Dockerfile @@ -1,10 +1,13 @@ ARG IMAGE=ubuntu:26.04 FROM $IMAGE -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - gcc libc6-dev ca-certificates \ - gcc-arm-linux-gnueabihf libc6-dev-armhf-cross qemu-user +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates \ + gcc \ + gcc-arm-linux-gnueabihf \ + libc6-dev \ + libc6-dev-armhf-cross \ + qemu-user ENV TOOLCHAIN_PREFIX=arm-linux-gnueabihf- ENV CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_LINKER="$TOOLCHAIN_PREFIX"gcc \ diff --git a/library/compiler-builtins/ci/docker/armv7-unknown-linux-gnueabihf/Dockerfile b/library/compiler-builtins/ci/docker/armv7-unknown-linux-gnueabihf/Dockerfile index 039ccd5745256..6f27aee73558d 100644 --- a/library/compiler-builtins/ci/docker/armv7-unknown-linux-gnueabihf/Dockerfile +++ b/library/compiler-builtins/ci/docker/armv7-unknown-linux-gnueabihf/Dockerfile @@ -1,10 +1,13 @@ ARG IMAGE=ubuntu:26.04 FROM $IMAGE -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - gcc libc6-dev ca-certificates \ - gcc-arm-linux-gnueabihf libc6-dev-armhf-cross qemu-user +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates \ + gcc \ + gcc-arm-linux-gnueabihf \ + libc6-dev \ + libc6-dev-armhf-cross \ + qemu-user ENV TOOLCHAIN_PREFIX=arm-linux-gnueabihf- ENV CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_LINKER="$TOOLCHAIN_PREFIX"gcc \ diff --git a/library/compiler-builtins/ci/docker/i586-unknown-linux-gnu/Dockerfile b/library/compiler-builtins/ci/docker/i586-unknown-linux-gnu/Dockerfile index 9319e73dd03f0..8c0aea18a66bd 100644 --- a/library/compiler-builtins/ci/docker/i586-unknown-linux-gnu/Dockerfile +++ b/library/compiler-builtins/ci/docker/i586-unknown-linux-gnu/Dockerfile @@ -1,6 +1,9 @@ ARG IMAGE=ubuntu:26.04 FROM $IMAGE -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - gcc-multilib m4 make libc6-dev ca-certificates +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates \ + gcc-multilib \ + libc6-dev \ + m4 \ + make diff --git a/library/compiler-builtins/ci/docker/i686-unknown-linux-gnu/Dockerfile b/library/compiler-builtins/ci/docker/i686-unknown-linux-gnu/Dockerfile index 9319e73dd03f0..8c0aea18a66bd 100644 --- a/library/compiler-builtins/ci/docker/i686-unknown-linux-gnu/Dockerfile +++ b/library/compiler-builtins/ci/docker/i686-unknown-linux-gnu/Dockerfile @@ -1,6 +1,9 @@ ARG IMAGE=ubuntu:26.04 FROM $IMAGE -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - gcc-multilib m4 make libc6-dev ca-certificates +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates \ + gcc-multilib \ + libc6-dev \ + m4 \ + make diff --git a/library/compiler-builtins/ci/docker/loongarch64-unknown-linux-gnu/Dockerfile b/library/compiler-builtins/ci/docker/loongarch64-unknown-linux-gnu/Dockerfile index 442a13164880c..76ef1a8619d35 100644 --- a/library/compiler-builtins/ci/docker/loongarch64-unknown-linux-gnu/Dockerfile +++ b/library/compiler-builtins/ci/docker/loongarch64-unknown-linux-gnu/Dockerfile @@ -1,10 +1,13 @@ ARG IMAGE=ubuntu:26.04 FROM $IMAGE -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - gcc libc6-dev qemu-user ca-certificates \ - gcc-14-loongarch64-linux-gnu libc6-dev-loong64-cross +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates \ + gcc \ + gcc-14-loongarch64-linux-gnu \ + libc6-dev \ + libc6-dev-loong64-cross \ + qemu-user ENV CARGO_TARGET_LOONGARCH64_UNKNOWN_LINUX_GNU_LINKER=loongarch64-linux-gnu-gcc-14 \ CARGO_TARGET_LOONGARCH64_UNKNOWN_LINUX_GNU_RUNNER=qemu-loongarch64 \ diff --git a/library/compiler-builtins/ci/docker/mips-unknown-linux-gnu/Dockerfile b/library/compiler-builtins/ci/docker/mips-unknown-linux-gnu/Dockerfile index 9941a8c2736c0..9f1f272f38a3d 100644 --- a/library/compiler-builtins/ci/docker/mips-unknown-linux-gnu/Dockerfile +++ b/library/compiler-builtins/ci/docker/mips-unknown-linux-gnu/Dockerfile @@ -1,11 +1,15 @@ ARG IMAGE=ubuntu:26.04 FROM $IMAGE -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - gcc libc6-dev ca-certificates \ - gcc-mips-linux-gnu libc6-dev-mips-cross \ - binfmt-support qemu-user qemu-system-mips +RUN apt-get update && apt-get install -y --no-install-recommends \ + binfmt-support \ + ca-certificates \ + gcc \ + gcc-mips-linux-gnu \ + libc6-dev \ + libc6-dev-mips-cross \ + qemu-system-mips \ + qemu-user ENV TOOLCHAIN_PREFIX=mips-linux-gnu- ENV CARGO_TARGET_MIPS_UNKNOWN_LINUX_GNU_LINKER="$TOOLCHAIN_PREFIX"gcc \ diff --git a/library/compiler-builtins/ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile b/library/compiler-builtins/ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile index c20d0a77b81c3..261979c0d2052 100644 --- a/library/compiler-builtins/ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile +++ b/library/compiler-builtins/ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile @@ -1,15 +1,14 @@ ARG IMAGE=ubuntu:26.04 FROM $IMAGE -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ +RUN apt-get update && apt-get install -y --no-install-recommends \ ca-certificates \ gcc \ gcc-mips64-linux-gnuabi64 \ libc6-dev \ libc6-dev-mips64-cross \ - qemu-user \ qemu-system-mips + qemu-user \ ENV TOOLCHAIN_PREFIX=mips64-linux-gnuabi64- ENV CARGO_TARGET_MIPS64_UNKNOWN_LINUX_GNUABI64_LINKER="$TOOLCHAIN_PREFIX"gcc \ diff --git a/library/compiler-builtins/ci/docker/mips64el-unknown-linux-gnuabi64/Dockerfile b/library/compiler-builtins/ci/docker/mips64el-unknown-linux-gnuabi64/Dockerfile index 584f7ffff45a5..d394e7f8e23f3 100644 --- a/library/compiler-builtins/ci/docker/mips64el-unknown-linux-gnuabi64/Dockerfile +++ b/library/compiler-builtins/ci/docker/mips64el-unknown-linux-gnuabi64/Dockerfile @@ -1,8 +1,7 @@ ARG IMAGE=ubuntu:26.04 FROM $IMAGE -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ +RUN apt-get update && apt-get install -y --no-install-recommends \ ca-certificates \ gcc \ gcc-mips64el-linux-gnuabi64 \ diff --git a/library/compiler-builtins/ci/docker/mipsel-unknown-linux-gnu/Dockerfile b/library/compiler-builtins/ci/docker/mipsel-unknown-linux-gnu/Dockerfile index ead99bb9c1132..3ae411030e1ed 100644 --- a/library/compiler-builtins/ci/docker/mipsel-unknown-linux-gnu/Dockerfile +++ b/library/compiler-builtins/ci/docker/mipsel-unknown-linux-gnu/Dockerfile @@ -1,11 +1,14 @@ ARG IMAGE=ubuntu:26.04 FROM $IMAGE -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - gcc libc6-dev ca-certificates \ - gcc-mipsel-linux-gnu libc6-dev-mipsel-cross \ - binfmt-support qemu-user +RUN apt-get update && apt-get install -y --no-install-recommends \ + binfmt-support \ + ca-certificates \ + gcc \ + gcc-mipsel-linux-gnu \ + libc6-dev \ + libc6-dev-mipsel-cross \ + qemu-user ENV TOOLCHAIN_PREFIX=mipsel-linux-gnu- ENV CARGO_TARGET_MIPSEL_UNKNOWN_LINUX_GNU_LINKER="$TOOLCHAIN_PREFIX"gcc \ diff --git a/library/compiler-builtins/ci/docker/powerpc-unknown-linux-gnu/Dockerfile b/library/compiler-builtins/ci/docker/powerpc-unknown-linux-gnu/Dockerfile index 74071874ed7cf..40bdcedba24bb 100644 --- a/library/compiler-builtins/ci/docker/powerpc-unknown-linux-gnu/Dockerfile +++ b/library/compiler-builtins/ci/docker/powerpc-unknown-linux-gnu/Dockerfile @@ -1,11 +1,14 @@ ARG IMAGE=ubuntu:26.04 FROM $IMAGE -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - gcc libc6-dev qemu-user ca-certificates \ - gcc-powerpc-linux-gnu libc6-dev-powerpc-cross \ - qemu-system-ppc +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates \ + gcc \ + gcc-powerpc-linux-gnu \ + libc6-dev \ + libc6-dev-powerpc-cross \ + qemu-system-ppc \ + qemu-user ENV TOOLCHAIN_PREFIX=powerpc-linux-gnu- ENV CARGO_TARGET_POWERPC_UNKNOWN_LINUX_GNU_LINKER="$TOOLCHAIN_PREFIX"gcc \ diff --git a/library/compiler-builtins/ci/docker/powerpc64-unknown-linux-gnu/Dockerfile b/library/compiler-builtins/ci/docker/powerpc64-unknown-linux-gnu/Dockerfile index ba4fec7160b64..70c92a25273fa 100644 --- a/library/compiler-builtins/ci/docker/powerpc64-unknown-linux-gnu/Dockerfile +++ b/library/compiler-builtins/ci/docker/powerpc64-unknown-linux-gnu/Dockerfile @@ -1,11 +1,15 @@ ARG IMAGE=ubuntu:26.04 FROM $IMAGE -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - gcc libc6-dev ca-certificates \ - gcc-powerpc64-linux-gnu libc6-dev-ppc64-cross \ - binfmt-support qemu-user qemu-system-ppc +RUN apt-get update && apt-get install -y --no-install-recommends \ + binfmt-support \ + ca-certificates \ + gcc \ + gcc-powerpc64-linux-gnu \ + libc6-dev \ + libc6-dev-ppc64-cross \ + qemu-system-ppc \ + qemu-user ENV TOOLCHAIN_PREFIX=powerpc64-linux-gnu- ENV CARGO_TARGET_POWERPC64_UNKNOWN_LINUX_GNU_LINKER="$TOOLCHAIN_PREFIX"gcc \ diff --git a/library/compiler-builtins/ci/docker/powerpc64le-unknown-linux-gnu/Dockerfile b/library/compiler-builtins/ci/docker/powerpc64le-unknown-linux-gnu/Dockerfile index e90d4c8812042..572d671345573 100644 --- a/library/compiler-builtins/ci/docker/powerpc64le-unknown-linux-gnu/Dockerfile +++ b/library/compiler-builtins/ci/docker/powerpc64le-unknown-linux-gnu/Dockerfile @@ -1,11 +1,14 @@ ARG IMAGE=ubuntu:26.04 FROM $IMAGE -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - gcc libc6-dev qemu-user ca-certificates \ - gcc-powerpc64le-linux-gnu libc6-dev-ppc64el-cross \ - qemu-system-ppc +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates \ + gcc \ + gcc-powerpc64le-linux-gnu \ + libc6-dev \ + libc6-dev-ppc64el-cross \ + qemu-system-ppc \ + qemu-user ENV TOOLCHAIN_PREFIX=powerpc64le-linux-gnu- ENV CARGO_TARGET_POWERPC64LE_UNKNOWN_LINUX_GNU_LINKER="$TOOLCHAIN_PREFIX"gcc \ diff --git a/library/compiler-builtins/ci/docker/riscv64gc-unknown-linux-gnu/Dockerfile b/library/compiler-builtins/ci/docker/riscv64gc-unknown-linux-gnu/Dockerfile index 96442121bcd9e..7ff30f71a5555 100644 --- a/library/compiler-builtins/ci/docker/riscv64gc-unknown-linux-gnu/Dockerfile +++ b/library/compiler-builtins/ci/docker/riscv64gc-unknown-linux-gnu/Dockerfile @@ -1,11 +1,14 @@ ARG IMAGE=ubuntu:26.04 FROM $IMAGE -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - gcc libc6-dev qemu-user ca-certificates \ - gcc-riscv64-linux-gnu libc6-dev-riscv64-cross \ - qemu-system-riscv +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates \ + gcc \ + gcc-riscv64-linux-gnu \ + libc6-dev \ + libc6-dev-riscv64-cross \ + qemu-system-riscv \ + qemu-user ENV TOOLCHAIN_PREFIX=riscv64-linux-gnu- ENV CARGO_TARGET_RISCV64GC_UNKNOWN_LINUX_GNU_LINKER="$TOOLCHAIN_PREFIX"gcc \ diff --git a/library/compiler-builtins/ci/docker/thumbv6m-none-eabi/Dockerfile b/library/compiler-builtins/ci/docker/thumbv6m-none-eabi/Dockerfile index 463cce94e5540..d77fb4fc60db5 100644 --- a/library/compiler-builtins/ci/docker/thumbv6m-none-eabi/Dockerfile +++ b/library/compiler-builtins/ci/docker/thumbv6m-none-eabi/Dockerfile @@ -1,9 +1,10 @@ ARG IMAGE=ubuntu:26.04 FROM $IMAGE -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - gcc libc6-dev ca-certificates \ +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates \ + gcc \ gcc-arm-none-eabi \ + libc6-dev \ libnewlib-arm-none-eabi ENV BUILD_ONLY=1 diff --git a/library/compiler-builtins/ci/docker/thumbv7em-none-eabi/Dockerfile b/library/compiler-builtins/ci/docker/thumbv7em-none-eabi/Dockerfile index 463cce94e5540..d77fb4fc60db5 100644 --- a/library/compiler-builtins/ci/docker/thumbv7em-none-eabi/Dockerfile +++ b/library/compiler-builtins/ci/docker/thumbv7em-none-eabi/Dockerfile @@ -1,9 +1,10 @@ ARG IMAGE=ubuntu:26.04 FROM $IMAGE -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - gcc libc6-dev ca-certificates \ +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates \ + gcc \ gcc-arm-none-eabi \ + libc6-dev \ libnewlib-arm-none-eabi ENV BUILD_ONLY=1 diff --git a/library/compiler-builtins/ci/docker/thumbv7em-none-eabihf/Dockerfile b/library/compiler-builtins/ci/docker/thumbv7em-none-eabihf/Dockerfile index 463cce94e5540..d77fb4fc60db5 100644 --- a/library/compiler-builtins/ci/docker/thumbv7em-none-eabihf/Dockerfile +++ b/library/compiler-builtins/ci/docker/thumbv7em-none-eabihf/Dockerfile @@ -1,9 +1,10 @@ ARG IMAGE=ubuntu:26.04 FROM $IMAGE -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - gcc libc6-dev ca-certificates \ +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates \ + gcc \ gcc-arm-none-eabi \ + libc6-dev \ libnewlib-arm-none-eabi ENV BUILD_ONLY=1 diff --git a/library/compiler-builtins/ci/docker/thumbv7m-none-eabi/Dockerfile b/library/compiler-builtins/ci/docker/thumbv7m-none-eabi/Dockerfile index 463cce94e5540..d77fb4fc60db5 100644 --- a/library/compiler-builtins/ci/docker/thumbv7m-none-eabi/Dockerfile +++ b/library/compiler-builtins/ci/docker/thumbv7m-none-eabi/Dockerfile @@ -1,9 +1,10 @@ ARG IMAGE=ubuntu:26.04 FROM $IMAGE -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - gcc libc6-dev ca-certificates \ +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates \ + gcc \ gcc-arm-none-eabi \ + libc6-dev \ libnewlib-arm-none-eabi ENV BUILD_ONLY=1 diff --git a/library/compiler-builtins/ci/docker/wasm32-unknown-unknown/Dockerfile b/library/compiler-builtins/ci/docker/wasm32-unknown-unknown/Dockerfile index 09f35c3b128d0..0e203d20700ac 100644 --- a/library/compiler-builtins/ci/docker/wasm32-unknown-unknown/Dockerfile +++ b/library/compiler-builtins/ci/docker/wasm32-unknown-unknown/Dockerfile @@ -1,8 +1,10 @@ ARG IMAGE=ubuntu:26.04 FROM $IMAGE -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - gcc clang libc6-dev ca-certificates +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates \ + clang \ + gcc \ + libc6-dev ENV CARGO_TARGET_WASM32_UNKNOWN_UNKNOWN_RUNNER=true diff --git a/library/compiler-builtins/ci/docker/x86_64-unknown-linux-gnu/Dockerfile b/library/compiler-builtins/ci/docker/x86_64-unknown-linux-gnu/Dockerfile index 103c395ee8496..1cf59a802511a 100644 --- a/library/compiler-builtins/ci/docker/x86_64-unknown-linux-gnu/Dockerfile +++ b/library/compiler-builtins/ci/docker/x86_64-unknown-linux-gnu/Dockerfile @@ -1,6 +1,9 @@ ARG IMAGE=ubuntu:26.04 FROM $IMAGE -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - gcc m4 make libc6-dev ca-certificates +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates \ + gcc \ + libc6-dev \ + m4 \ + make From 482100de4989334cdeeabd1e312a46f33e42a1f8 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Fri, 7 Aug 2026 12:17:24 -0500 Subject: [PATCH 07/28] bench: Update pinned nightly to 2026-08-06 This is the first version with LLVM23. --- 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 27ccbd7f3764d..9e44cbc4a4f16 100644 --- a/library/compiler-builtins/.github/workflows/main.yaml +++ b/library/compiler-builtins/.github/workflows/main.yaml @@ -16,7 +16,7 @@ env: RUSTDOCFLAGS: -Dwarnings RUSTFLAGS: -Dwarnings -Dlinker_messages RUST_BACKTRACE: full - BENCHMARK_RUSTC: nightly-2026-08-05 # Pin the toolchain for reproducable results + BENCHMARK_RUSTC: nightly-2026-08-06 # Pin the toolchain for reproducable results defaults: run: From e45bb36fd63418c10b11d2fd78ed9ad91e70ba01 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Mon, 17 Aug 2026 06:34:27 -0500 Subject: [PATCH 08/28] ci: Delete `RUST_TEST_THREADS=1` This was added as part of the original test infrastructure at 8e161a791a89 ("Expand and refactor teting infrastructure") but there doesn't seem to be any reason to keep this restriction; qemu should handle the threads fine. --- .../ci/docker/aarch64-unknown-linux-gnu/Dockerfile | 3 +-- .../ci/docker/arm-unknown-linux-gnueabi/Dockerfile | 3 +-- .../ci/docker/arm-unknown-linux-gnueabihf/Dockerfile | 3 +-- .../ci/docker/armv7-unknown-linux-gnueabihf/Dockerfile | 3 +-- .../ci/docker/loongarch64-unknown-linux-gnu/Dockerfile | 3 +-- .../ci/docker/mips-unknown-linux-gnu/Dockerfile | 3 +-- .../ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile | 3 +-- .../ci/docker/mips64el-unknown-linux-gnuabi64/Dockerfile | 3 +-- .../ci/docker/mipsel-unknown-linux-gnu/Dockerfile | 3 +-- .../ci/docker/powerpc-unknown-linux-gnu/Dockerfile | 3 +-- .../ci/docker/powerpc64-unknown-linux-gnu/Dockerfile | 3 +-- .../ci/docker/powerpc64le-unknown-linux-gnu/Dockerfile | 3 +-- .../ci/docker/riscv64gc-unknown-linux-gnu/Dockerfile | 3 +-- 13 files changed, 13 insertions(+), 26 deletions(-) diff --git a/library/compiler-builtins/ci/docker/aarch64-unknown-linux-gnu/Dockerfile b/library/compiler-builtins/ci/docker/aarch64-unknown-linux-gnu/Dockerfile index af3232a3aa0f7..555191eedecb6 100644 --- a/library/compiler-builtins/ci/docker/aarch64-unknown-linux-gnu/Dockerfile +++ b/library/compiler-builtins/ci/docker/aarch64-unknown-linux-gnu/Dockerfile @@ -16,5 +16,4 @@ ENV CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER="$TOOLCHAIN_PREFIX"gcc \ CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUNNER=qemu-aarch64 \ AR_aarch64_unknown_linux_gnu="$TOOLCHAIN_PREFIX"ar \ CC_aarch64_unknown_linux_gnu="$TOOLCHAIN_PREFIX"gcc \ - QEMU_LD_PREFIX=/usr/aarch64-linux-gnu \ - RUST_TEST_THREADS=1 + QEMU_LD_PREFIX=/usr/aarch64-linux-gnu diff --git a/library/compiler-builtins/ci/docker/arm-unknown-linux-gnueabi/Dockerfile b/library/compiler-builtins/ci/docker/arm-unknown-linux-gnueabi/Dockerfile index 2bd11ca870233..a23e3526855f9 100644 --- a/library/compiler-builtins/ci/docker/arm-unknown-linux-gnueabi/Dockerfile +++ b/library/compiler-builtins/ci/docker/arm-unknown-linux-gnueabi/Dockerfile @@ -14,5 +14,4 @@ ENV CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABI_LINKER="$TOOLCHAIN_PREFIX"gcc \ CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABI_RUNNER=qemu-arm \ AR_arm_unknown_linux_gnueabi="$TOOLCHAIN_PREFIX"ar \ CC_arm_unknown_linux_gnueabi="$TOOLCHAIN_PREFIX"gcc \ - QEMU_LD_PREFIX=/usr/arm-linux-gnueabi \ - RUST_TEST_THREADS=1 + QEMU_LD_PREFIX=/usr/arm-linux-gnueabi diff --git a/library/compiler-builtins/ci/docker/arm-unknown-linux-gnueabihf/Dockerfile b/library/compiler-builtins/ci/docker/arm-unknown-linux-gnueabihf/Dockerfile index 1e50e293d1183..003cc64c8ddc6 100644 --- a/library/compiler-builtins/ci/docker/arm-unknown-linux-gnueabihf/Dockerfile +++ b/library/compiler-builtins/ci/docker/arm-unknown-linux-gnueabihf/Dockerfile @@ -14,5 +14,4 @@ ENV CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_LINKER="$TOOLCHAIN_PREFIX"gcc \ CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_RUNNER=qemu-arm \ AR_arm_unknown_linux_gnueabihf="$TOOLCHAIN_PREFIX"ar \ CC_arm_unknown_linux_gnueabihf="$TOOLCHAIN_PREFIX"gcc \ - QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf \ - RUST_TEST_THREADS=1 + QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf diff --git a/library/compiler-builtins/ci/docker/armv7-unknown-linux-gnueabihf/Dockerfile b/library/compiler-builtins/ci/docker/armv7-unknown-linux-gnueabihf/Dockerfile index 6f27aee73558d..391096e01c8a6 100644 --- a/library/compiler-builtins/ci/docker/armv7-unknown-linux-gnueabihf/Dockerfile +++ b/library/compiler-builtins/ci/docker/armv7-unknown-linux-gnueabihf/Dockerfile @@ -14,5 +14,4 @@ ENV CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_LINKER="$TOOLCHAIN_PREFIX"gcc \ CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_RUNNER=qemu-arm \ AR_armv7_unknown_linux_gnueabihf="$TOOLCHAIN_PREFIX"ar \ CC_armv7_unknown_linux_gnueabihf="$TOOLCHAIN_PREFIX"gcc \ - QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf \ - RUST_TEST_THREADS=1 + QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf diff --git a/library/compiler-builtins/ci/docker/loongarch64-unknown-linux-gnu/Dockerfile b/library/compiler-builtins/ci/docker/loongarch64-unknown-linux-gnu/Dockerfile index 76ef1a8619d35..0684b7cc4bb63 100644 --- a/library/compiler-builtins/ci/docker/loongarch64-unknown-linux-gnu/Dockerfile +++ b/library/compiler-builtins/ci/docker/loongarch64-unknown-linux-gnu/Dockerfile @@ -13,5 +13,4 @@ ENV CARGO_TARGET_LOONGARCH64_UNKNOWN_LINUX_GNU_LINKER=loongarch64-linux-gnu-gcc- CARGO_TARGET_LOONGARCH64_UNKNOWN_LINUX_GNU_RUNNER=qemu-loongarch64 \ AR_loongarch64_unknown_linux_gnu=loongarch64-linux-gnu-ar \ CC_loongarch64_unknown_linux_gnu=loongarch64-linux-gnu-gcc-14 \ - QEMU_LD_PREFIX=/usr/loongarch64-linux-gnu \ - RUST_TEST_THREADS=1 + QEMU_LD_PREFIX=/usr/loongarch64-linux-gnu diff --git a/library/compiler-builtins/ci/docker/mips-unknown-linux-gnu/Dockerfile b/library/compiler-builtins/ci/docker/mips-unknown-linux-gnu/Dockerfile index 9f1f272f38a3d..690d878a23ef1 100644 --- a/library/compiler-builtins/ci/docker/mips-unknown-linux-gnu/Dockerfile +++ b/library/compiler-builtins/ci/docker/mips-unknown-linux-gnu/Dockerfile @@ -16,5 +16,4 @@ ENV CARGO_TARGET_MIPS_UNKNOWN_LINUX_GNU_LINKER="$TOOLCHAIN_PREFIX"gcc \ CARGO_TARGET_MIPS_UNKNOWN_LINUX_GNU_RUNNER=qemu-mips \ AR_mips_unknown_linux_gnu="$TOOLCHAIN_PREFIX"ar \ CC_mips_unknown_linux_gnu="$TOOLCHAIN_PREFIX"gcc \ - QEMU_LD_PREFIX=/usr/mips-linux-gnu \ - RUST_TEST_THREADS=1 + QEMU_LD_PREFIX=/usr/mips-linux-gnu diff --git a/library/compiler-builtins/ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile b/library/compiler-builtins/ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile index 261979c0d2052..6ff8effb8570d 100644 --- a/library/compiler-builtins/ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile +++ b/library/compiler-builtins/ci/docker/mips64-unknown-linux-gnuabi64/Dockerfile @@ -15,5 +15,4 @@ ENV CARGO_TARGET_MIPS64_UNKNOWN_LINUX_GNUABI64_LINKER="$TOOLCHAIN_PREFIX"gcc \ CARGO_TARGET_MIPS64_UNKNOWN_LINUX_GNUABI64_RUNNER=qemu-mips64 \ AR_mips64_unknown_linux_gnuabi64="$TOOLCHAIN_PREFIX"ar \ CC_mips64_unknown_linux_gnuabi64="$TOOLCHAIN_PREFIX"gcc \ - QEMU_LD_PREFIX=/usr/mips64-linux-gnuabi64 \ - RUST_TEST_THREADS=1 + QEMU_LD_PREFIX=/usr/mips64-linux-gnuabi64 diff --git a/library/compiler-builtins/ci/docker/mips64el-unknown-linux-gnuabi64/Dockerfile b/library/compiler-builtins/ci/docker/mips64el-unknown-linux-gnuabi64/Dockerfile index d394e7f8e23f3..445fec6786d32 100644 --- a/library/compiler-builtins/ci/docker/mips64el-unknown-linux-gnuabi64/Dockerfile +++ b/library/compiler-builtins/ci/docker/mips64el-unknown-linux-gnuabi64/Dockerfile @@ -14,5 +14,4 @@ ENV CARGO_TARGET_MIPS64EL_UNKNOWN_LINUX_GNUABI64_LINKER="$TOOLCHAIN_PREFIX"gcc \ CARGO_TARGET_MIPS64EL_UNKNOWN_LINUX_GNUABI64_RUNNER=qemu-mips64el \ AR_mips64el_unknown_linux_gnuabi64="$TOOLCHAIN_PREFIX"ar \ CC_mips64el_unknown_linux_gnuabi64="$TOOLCHAIN_PREFIX"gcc \ - QEMU_LD_PREFIX=/usr/mips64el-linux-gnuabi64 \ - RUST_TEST_THREADS=1 + QEMU_LD_PREFIX=/usr/mips64el-linux-gnuabi64 diff --git a/library/compiler-builtins/ci/docker/mipsel-unknown-linux-gnu/Dockerfile b/library/compiler-builtins/ci/docker/mipsel-unknown-linux-gnu/Dockerfile index 3ae411030e1ed..6d4dc124443b8 100644 --- a/library/compiler-builtins/ci/docker/mipsel-unknown-linux-gnu/Dockerfile +++ b/library/compiler-builtins/ci/docker/mipsel-unknown-linux-gnu/Dockerfile @@ -15,5 +15,4 @@ ENV CARGO_TARGET_MIPSEL_UNKNOWN_LINUX_GNU_LINKER="$TOOLCHAIN_PREFIX"gcc \ CARGO_TARGET_MIPSEL_UNKNOWN_LINUX_GNU_RUNNER=qemu-mipsel \ AR_mipsel_unknown_linux_gnu="$TOOLCHAIN_PREFIX"ar \ CC_mipsel_unknown_linux_gnu="$TOOLCHAIN_PREFIX"gcc \ - QEMU_LD_PREFIX=/usr/mipsel-linux-gnu \ - RUST_TEST_THREADS=1 + QEMU_LD_PREFIX=/usr/mipsel-linux-gnu diff --git a/library/compiler-builtins/ci/docker/powerpc-unknown-linux-gnu/Dockerfile b/library/compiler-builtins/ci/docker/powerpc-unknown-linux-gnu/Dockerfile index 40bdcedba24bb..025ba1a7c419a 100644 --- a/library/compiler-builtins/ci/docker/powerpc-unknown-linux-gnu/Dockerfile +++ b/library/compiler-builtins/ci/docker/powerpc-unknown-linux-gnu/Dockerfile @@ -15,5 +15,4 @@ ENV CARGO_TARGET_POWERPC_UNKNOWN_LINUX_GNU_LINKER="$TOOLCHAIN_PREFIX"gcc \ CARGO_TARGET_POWERPC_UNKNOWN_LINUX_GNU_RUNNER=qemu-ppc \ AR_powerpc_unknown_linux_gnu="$TOOLCHAIN_PREFIX"ar \ CC_powerpc_unknown_linux_gnu="$TOOLCHAIN_PREFIX"gcc \ - QEMU_LD_PREFIX=/usr/powerpc-linux-gnu \ - RUST_TEST_THREADS=1 + QEMU_LD_PREFIX=/usr/powerpc-linux-gnu diff --git a/library/compiler-builtins/ci/docker/powerpc64-unknown-linux-gnu/Dockerfile b/library/compiler-builtins/ci/docker/powerpc64-unknown-linux-gnu/Dockerfile index 70c92a25273fa..fc6e011aaae58 100644 --- a/library/compiler-builtins/ci/docker/powerpc64-unknown-linux-gnu/Dockerfile +++ b/library/compiler-builtins/ci/docker/powerpc64-unknown-linux-gnu/Dockerfile @@ -16,5 +16,4 @@ ENV CARGO_TARGET_POWERPC64_UNKNOWN_LINUX_GNU_LINKER="$TOOLCHAIN_PREFIX"gcc \ CARGO_TARGET_POWERPC64_UNKNOWN_LINUX_GNU_RUNNER=qemu-ppc64 \ AR_powerpc64_unknown_linux_gnu="$TOOLCHAIN_PREFIX"ar \ CC_powerpc64_unknown_linux_gnu="$TOOLCHAIN_PREFIX"gcc \ - QEMU_LD_PREFIX=/usr/powerpc64-linux-gnu \ - RUST_TEST_THREADS=1 + QEMU_LD_PREFIX=/usr/powerpc64-linux-gnu diff --git a/library/compiler-builtins/ci/docker/powerpc64le-unknown-linux-gnu/Dockerfile b/library/compiler-builtins/ci/docker/powerpc64le-unknown-linux-gnu/Dockerfile index 572d671345573..0913b2a609349 100644 --- a/library/compiler-builtins/ci/docker/powerpc64le-unknown-linux-gnu/Dockerfile +++ b/library/compiler-builtins/ci/docker/powerpc64le-unknown-linux-gnu/Dockerfile @@ -15,5 +15,4 @@ ENV CARGO_TARGET_POWERPC64LE_UNKNOWN_LINUX_GNU_LINKER="$TOOLCHAIN_PREFIX"gcc \ CARGO_TARGET_POWERPC64LE_UNKNOWN_LINUX_GNU_RUNNER=qemu-ppc64le \ AR_powerpc64le_unknown_linux_gnu="$TOOLCHAIN_PREFIX"ar \ CC_powerpc64le_unknown_linux_gnu="$TOOLCHAIN_PREFIX"gcc \ - QEMU_LD_PREFIX=/usr/powerpc64le-linux-gnu \ - RUST_TEST_THREADS=1 + QEMU_LD_PREFIX=/usr/powerpc64le-linux-gnu diff --git a/library/compiler-builtins/ci/docker/riscv64gc-unknown-linux-gnu/Dockerfile b/library/compiler-builtins/ci/docker/riscv64gc-unknown-linux-gnu/Dockerfile index 7ff30f71a5555..af8e0f3d4733a 100644 --- a/library/compiler-builtins/ci/docker/riscv64gc-unknown-linux-gnu/Dockerfile +++ b/library/compiler-builtins/ci/docker/riscv64gc-unknown-linux-gnu/Dockerfile @@ -15,5 +15,4 @@ ENV CARGO_TARGET_RISCV64GC_UNKNOWN_LINUX_GNU_LINKER="$TOOLCHAIN_PREFIX"gcc \ CARGO_TARGET_RISCV64GC_UNKNOWN_LINUX_GNU_RUNNER=qemu-riscv64 \ AR_riscv64gc_unknown_linux_gnu="$TOOLCHAIN_PREFIX"ar \ CC_riscv64gc_unknown_linux_gnu="$TOOLCHAIN_PREFIX"gcc \ - QEMU_LD_PREFIX=/usr/riscv64-linux-gnu \ - RUST_TEST_THREADS=1 + QEMU_LD_PREFIX=/usr/riscv64-linux-gnu From cfb82de0fccad70337c4a5c6538600a9c9b530f8 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Fri, 14 Aug 2026 12:48:38 +0200 Subject: [PATCH 09/28] enable `f128` tests against system libs on windows With LLVM 23, containing f128 abi fixes, this now works --- library/compiler-builtins/builtins-test/build.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/library/compiler-builtins/builtins-test/build.rs b/library/compiler-builtins/builtins-test/build.rs index 133186bc7f57d..b36d581b9d195 100644 --- a/library/compiler-builtins/builtins-test/build.rs +++ b/library/compiler-builtins/builtins-test/build.rs @@ -58,12 +58,6 @@ fn main() { if cfg.target_arch == "arm" || cfg.target_vendor == "apple" || cfg.target_env == "msvc" - // GCC and LLVM disagree on the ABI of `f16` and `f128` with MinGW. See - // . - || (cfg.target_os == "windows" && cfg.target_env == "gnu") - // FIXME(llvm): There is an ABI incompatibility between GCC and Clang on 32-bit x86. - // See . - || cfg.target_arch == "x86" // 32-bit PowerPC and 64-bit LE gets code generated that Qemu cannot handle. See // . || cfg.target_arch == "powerpc" From 06a01635de0800709b30c099e2b514d98674241c Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Tue, 18 Aug 2026 02:13:48 -0500 Subject: [PATCH 10/28] ci: Don't test with `--benches` in debug mode Benchmarks are designed to run in release mode so these can be pretty slow. Running once with `release-checked` is sufficient. --- library/compiler-builtins/ci/run.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/library/compiler-builtins/ci/run.sh b/library/compiler-builtins/ci/run.sh index 359bf3d945b9b..adb610dad36fe 100755 --- a/library/compiler-builtins/ci/run.sh +++ b/library/compiler-builtins/ci/run.sh @@ -61,7 +61,6 @@ else "${test_builtins[@]}" --release "${test_builtins[@]}" --features c "${test_builtins[@]}" --features c --release - "${test_builtins[@]}" --benches "${test_builtins[@]}" --benches --release "${test_builtins[@]}" --no-default-features "${test_builtins[@]}" --no-default-features --release @@ -201,7 +200,6 @@ else # Test once with intrinsics enabled "${cmd[@]}" --features arch,unstable-intrinsics - "${cmd[@]}" --features arch,unstable-intrinsics --benches # Test the same in release mode, which also increases coverage. Also ensure # the soft float routines are checked. From 90c7ab49121c67130920b330e7998e6a67a70258 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Tue, 18 Aug 2026 02:22:37 -0500 Subject: [PATCH 11/28] ci: Group output into sections --- library/compiler-builtins/ci/run.sh | 47 ++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/library/compiler-builtins/ci/run.sh b/library/compiler-builtins/ci/run.sh index adb610dad36fe..22c136e2df39f 100755 --- a/library/compiler-builtins/ci/run.sh +++ b/library/compiler-builtins/ci/run.sh @@ -26,6 +26,13 @@ if [ "${USING_CONTAINER_RUSTC:-}" = 1 ]; then rustup target add "$target" fi +# Run the command with its output in a collapsable section +asgroup() { + echo "::group::$*" + "$@" + echo "::endgroup" +} + # If nextest is available, use that command -v cargo-nextest && nextest=1 || nextest=0 if [ "$nextest" = "1" ]; then @@ -57,13 +64,13 @@ else --target "$target" ) - "${test_builtins[@]}" - "${test_builtins[@]}" --release - "${test_builtins[@]}" --features c - "${test_builtins[@]}" --features c --release - "${test_builtins[@]}" --benches --release - "${test_builtins[@]}" --no-default-features - "${test_builtins[@]}" --no-default-features --release + asgroup "${test_builtins[@]}" + asgroup "${test_builtins[@]}" --release + asgroup "${test_builtins[@]}" --features c + asgroup "${test_builtins[@]}" --features c --release + asgroup "${test_builtins[@]}" --benches --release + asgroup "${test_builtins[@]}" --no-default-features + asgroup "${test_builtins[@]}" --no-default-features --release # Validate that having a verbatim path for the target directory works # (trivial to regress using `/` in paths to build artifacts rather than @@ -74,6 +81,9 @@ else fi fi + +echo "::group::Run symcheck" + # Ensure there are no duplicate symbols or references to `core` when # `compiler-builtins` is built with various features. Symcheck invokes Cargo to # build with the arguments we provide it, then validates the built artifacts. @@ -93,6 +103,11 @@ symcheck_cb_args=(-- --package compiler_builtins --features compiler-builtins) "${symcheck[@]}" "${symcheck_cb_args[@]}" --no-default-features "${symcheck[@]}" "${symcheck_cb_args[@]}" --no-default-features --release +echo "::endgroup" + + +echo "::group::Run intrinsics tests" + run_intrinsics_test() { build_args=(--verbose --manifest-path builtins-test-intrinsics/Cargo.toml) build_args+=("$@") @@ -118,6 +133,8 @@ run_intrinsics_test --features c --release CARGO_PROFILE_DEV_LTO=true run_intrinsics_test CARGO_PROFILE_RELEASE_LTO=true run_intrinsics_test --release +echo "::endgroup" + # Test libm # Make sure a simple build works @@ -189,31 +206,31 @@ else cmd=("${test_runner[@]}" "${mflags[@]}") # Test once without intrinsics - "${cmd[@]}" + asgroup "${cmd[@]}" # Run doctests if they were excluded by nextest - [ "$nextest" = "1" ] && cargo test --doc --exclude compiler_builtins "${mflags[@]}" + [ "$nextest" = "1" ] && asgroup cargo test --doc --exclude compiler_builtins "${mflags[@]}" # Exclude the macros and utile crates from the rest of the tests to save CI # runtime, they shouldn't have anything feature- or opt-level-dependent. cmd+=(--exclude util --exclude libm-macros) # Test once with intrinsics enabled - "${cmd[@]}" --features arch,unstable-intrinsics + asgroup "${cmd[@]}" --features arch,unstable-intrinsics # Test the same in release mode, which also increases coverage. Also ensure # the soft float routines are checked. - "${cmd[@]}" "$profile_flag" release-checked - "${cmd[@]}" "$profile_flag" release-checked --features arch - "${cmd[@]}" "$profile_flag" release-checked --features arch,unstable-intrinsics - "${cmd[@]}" "$profile_flag" release-checked --features arch,unstable-intrinsics --benches + asgroup "${cmd[@]}" "$profile_flag" release-checked + asgroup "${cmd[@]}" "$profile_flag" release-checked --features arch + asgroup "${cmd[@]}" "$profile_flag" release-checked --features arch,unstable-intrinsics + asgroup "${cmd[@]}" "$profile_flag" release-checked --features arch,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. - ENSURE_NO_PANIC=1 cargo build \ + ENSURE_NO_PANIC=1 asgroup cargo build \ -p libm \ --target "$target" \ --no-default-features \ From c0a0e1036087814d83be22101d80c7d34d97a7da Mon Sep 17 00:00:00 2001 From: beetrees Date: Tue, 18 Aug 2026 15:24:55 +0100 Subject: [PATCH 12/28] Rename `#[ppc_alias]` to `#[ppc_name]` --- .../builtins-test/src/bench.rs | 8 +++---- .../compiler-builtins/src/float/add.rs | 2 +- .../compiler-builtins/src/float/cmp.rs | 14 +++++------ .../compiler-builtins/src/float/conv.rs | 24 +++++++++---------- .../compiler-builtins/src/float/div.rs | 2 +- .../compiler-builtins/src/float/extend.rs | 6 ++--- .../compiler-builtins/src/float/mul.rs | 2 +- .../compiler-builtins/src/float/pow.rs | 2 +- .../compiler-builtins/src/float/sub.rs | 2 +- .../compiler-builtins/src/float/trunc.rs | 6 ++--- .../compiler-builtins/src/macros.rs | 8 +++---- 11 files changed, 38 insertions(+), 38 deletions(-) diff --git a/library/compiler-builtins/builtins-test/src/bench.rs b/library/compiler-builtins/builtins-test/src/bench.rs index dd03579285cbc..2985303988287 100644 --- a/library/compiler-builtins/builtins-test/src/bench.rs +++ b/library/compiler-builtins/builtins-test/src/bench.rs @@ -76,11 +76,11 @@ macro_rules! float_bench { sig: ($($arg:ident: $arg_ty:ty),*) -> $ret_ty:ty, // Path to the crate in compiler_builtins crate_fn: $crate_fn:path, - // Optional alias on ppc + // Optional name on ppc $( crate_fn_ppc: $crate_fn_ppc:path, )? // Name of the system symbol sys_fn: $sys_fn:ident, - // Optional alias on ppc + // Optional name on ppc $( sys_fn_ppc: $sys_fn_ppc:path, )? // Meta saying whether the system symbol is available sys_available: $sys_available:meta, @@ -122,7 +122,7 @@ macro_rules! float_bench { #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] let target_crate_fn = $crate_fn; - // On PPC, use an alias if specified + // On PPC, use the PPC name if specified #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] let target_crate_fn = float_bench!(@coalesce $($crate_fn_ppc)?, $crate_fn); @@ -135,7 +135,7 @@ macro_rules! float_bench { #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] let target_sys_fn = $sys_fn; - // On PPC, use an alias if specified + // On PPC, use the PPC name if specified #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] let target_sys_fn = float_bench!(@coalesce $($sys_fn_ppc)?, $sys_fn); diff --git a/library/compiler-builtins/compiler-builtins/src/float/add.rs b/library/compiler-builtins/compiler-builtins/src/float/add.rs index 69de07372f16e..6d51d32780cde 100644 --- a/library/compiler-builtins/compiler-builtins/src/float/add.rs +++ b/library/compiler-builtins/compiler-builtins/src/float/add.rs @@ -207,7 +207,7 @@ intrinsics! { add(a, b) } - #[ppc_alias = __addkf3] + #[ppc_name = __addkf3] #[cfg(f128_enabled)] pub extern "C" fn __addtf3(a: f128, b: f128) -> f128 { add(a, b) diff --git a/library/compiler-builtins/compiler-builtins/src/float/cmp.rs b/library/compiler-builtins/compiler-builtins/src/float/cmp.rs index 243c9c767f61b..a5ce9a2113b4d 100644 --- a/library/compiler-builtins/compiler-builtins/src/float/cmp.rs +++ b/library/compiler-builtins/compiler-builtins/src/float/cmp.rs @@ -227,37 +227,37 @@ intrinsics! { #[cfg(f128_enabled)] intrinsics! { - #[ppc_alias = __lekf2] + #[ppc_name = __lekf2] pub extern "C" fn __letf2(a: f128, b: f128) -> crate::float::cmp::CmpResult { cmp(a, b).to_default_cmp_result() } - #[ppc_alias = __gekf2] + #[ppc_name = __gekf2] pub extern "C" fn __getf2(a: f128, b: f128) -> crate::float::cmp::CmpResult { cmp(a, b).to_gt_ge_cmp_result() } - #[ppc_alias = __unordkf2] + #[ppc_name = __unordkf2] pub extern "C" fn __unordtf2(a: f128, b: f128) -> crate::float::cmp::CmpResult { unord(a, b) as crate::float::cmp::CmpResult } - #[ppc_alias = __eqkf2] + #[ppc_name = __eqkf2] pub extern "C" fn __eqtf2(a: f128, b: f128) -> crate::float::cmp::CmpResult { cmp(a, b).to_default_cmp_result() } - #[ppc_alias = __ltkf2] + #[ppc_name = __ltkf2] pub extern "C" fn __lttf2(a: f128, b: f128) -> crate::float::cmp::CmpResult { cmp(a, b).to_default_cmp_result() } - #[ppc_alias = __nekf2] + #[ppc_name = __nekf2] pub extern "C" fn __netf2(a: f128, b: f128) -> crate::float::cmp::CmpResult { cmp(a, b).to_default_cmp_result() } - #[ppc_alias = __gtkf2] + #[ppc_name = __gtkf2] pub extern "C" fn __gttf2(a: f128, b: f128) -> crate::float::cmp::CmpResult { cmp(a, b).to_gt_ge_cmp_result() } diff --git a/library/compiler-builtins/compiler-builtins/src/float/conv.rs b/library/compiler-builtins/compiler-builtins/src/float/conv.rs index 6193aa416e222..13a0ed4fcd39f 100644 --- a/library/compiler-builtins/compiler-builtins/src/float/conv.rs +++ b/library/compiler-builtins/compiler-builtins/src/float/conv.rs @@ -248,19 +248,19 @@ intrinsics! { f64::from_bits(int_to_float::u128_to_f64_bits((u128::from(hi) << 64) | u128::from(lo))) } - #[ppc_alias = __floatunsikf] + #[ppc_name = __floatunsikf] #[cfg(f128_enabled)] pub extern "C" fn __floatunsitf(i: u32) -> f128 { f128::from_bits(int_to_float::u32_to_f128_bits(i)) } - #[ppc_alias = __floatundikf] + #[ppc_name = __floatundikf] #[cfg(f128_enabled)] pub extern "C" fn __floatunditf(i: u64) -> f128 { f128::from_bits(int_to_float::u64_to_f128_bits(i)) } - #[ppc_alias = __floatuntikf] + #[ppc_name = __floatuntikf] #[cfg(f128_enabled)] pub extern "C" fn __floatuntitf(i: u128) -> f128 { f128::from_bits(int_to_float::u128_to_f128_bits(i)) @@ -309,19 +309,19 @@ intrinsics! { int_to_float::signed((i128::from(hi) << 64) | i128::from(lo), int_to_float::u128_to_f64_bits) } - #[ppc_alias = __floatsikf] + #[ppc_name = __floatsikf] #[cfg(f128_enabled)] pub extern "C" fn __floatsitf(i: i32) -> f128 { int_to_float::signed(i, int_to_float::u32_to_f128_bits) } - #[ppc_alias = __floatdikf] + #[ppc_name = __floatdikf] #[cfg(f128_enabled)] pub extern "C" fn __floatditf(i: i64) -> f128 { int_to_float::signed(i, int_to_float::u64_to_f128_bits) } - #[ppc_alias = __floattikf] + #[ppc_name = __floattikf] #[cfg(f128_enabled)] pub extern "C" fn __floattitf(i: i128) -> f128 { int_to_float::signed(i, int_to_float::u128_to_f128_bits) @@ -439,19 +439,19 @@ intrinsics! { float_to_unsigned_int(f) } - #[ppc_alias = __fixunskfsi] + #[ppc_name = __fixunskfsi] #[cfg(f128_enabled)] pub extern "C" fn __fixunstfsi(f: f128) -> u32 { float_to_unsigned_int(f) } - #[ppc_alias = __fixunskfdi] + #[ppc_name = __fixunskfdi] #[cfg(f128_enabled)] pub extern "C" fn __fixunstfdi(f: f128) -> u64 { float_to_unsigned_int(f) } - #[ppc_alias = __fixunskfti] + #[ppc_name = __fixunskfti] #[cfg(f128_enabled)] pub extern "C" fn __fixunstfti(f: f128) -> u128 { float_to_unsigned_int(f) @@ -488,19 +488,19 @@ intrinsics! { float_to_signed_int(f) } - #[ppc_alias = __fixkfsi] + #[ppc_name = __fixkfsi] #[cfg(f128_enabled)] pub extern "C" fn __fixtfsi(f: f128) -> i32 { float_to_signed_int(f) } - #[ppc_alias = __fixkfdi] + #[ppc_name = __fixkfdi] #[cfg(f128_enabled)] pub extern "C" fn __fixtfdi(f: f128) -> i64 { float_to_signed_int(f) } - #[ppc_alias = __fixkfti] + #[ppc_name = __fixkfti] #[cfg(f128_enabled)] pub extern "C" fn __fixtfti(f: f128) -> i128 { float_to_signed_int(f) diff --git a/library/compiler-builtins/compiler-builtins/src/float/div.rs b/library/compiler-builtins/compiler-builtins/src/float/div.rs index 419d8ad5e7061..1438ca687be0d 100644 --- a/library/compiler-builtins/compiler-builtins/src/float/div.rs +++ b/library/compiler-builtins/compiler-builtins/src/float/div.rs @@ -615,7 +615,7 @@ intrinsics! { div(a, b) } - #[ppc_alias = __divkf3] + #[ppc_name = __divkf3] #[cfg(f128_enabled)] pub extern "C" fn __divtf3(a: f128, b: f128) -> f128 { div(a, b) diff --git a/library/compiler-builtins/compiler-builtins/src/float/extend.rs b/library/compiler-builtins/compiler-builtins/src/float/extend.rs index 58038ce57f834..f6095ed1156f3 100644 --- a/library/compiler-builtins/compiler-builtins/src/float/extend.rs +++ b/library/compiler-builtins/compiler-builtins/src/float/extend.rs @@ -100,21 +100,21 @@ intrinsics! { } #[aapcs_on_arm] - #[ppc_alias = __extendhfkf2] + #[ppc_name = __extendhfkf2] #[cfg(all(f16_enabled, f128_enabled))] pub extern "C" fn __extendhftf2(a: f16) -> f128 { extend(a) } #[aapcs_on_arm] - #[ppc_alias = __extendsfkf2] + #[ppc_name = __extendsfkf2] #[cfg(f128_enabled)] pub extern "C" fn __extendsftf2(a: f32) -> f128 { extend(a) } #[aapcs_on_arm] - #[ppc_alias = __extenddfkf2] + #[ppc_name = __extenddfkf2] #[cfg(f128_enabled)] pub extern "C" fn __extenddftf2(a: f64) -> f128 { extend(a) diff --git a/library/compiler-builtins/compiler-builtins/src/float/mul.rs b/library/compiler-builtins/compiler-builtins/src/float/mul.rs index ffba2dc41f8a0..6780d8397959b 100644 --- a/library/compiler-builtins/compiler-builtins/src/float/mul.rs +++ b/library/compiler-builtins/compiler-builtins/src/float/mul.rs @@ -196,7 +196,7 @@ intrinsics! { mul(a, b) } - #[ppc_alias = __mulkf3] + #[ppc_name = __mulkf3] #[cfg(f128_enabled)] pub extern "C" fn __multf3(a: f128, b: f128) -> f128 { mul(a, b) diff --git a/library/compiler-builtins/compiler-builtins/src/float/pow.rs b/library/compiler-builtins/compiler-builtins/src/float/pow.rs index 2c92971d31397..50a27055a849f 100644 --- a/library/compiler-builtins/compiler-builtins/src/float/pow.rs +++ b/library/compiler-builtins/compiler-builtins/src/float/pow.rs @@ -29,7 +29,7 @@ intrinsics! { pow(a, b) } - #[ppc_alias = __powikf2] + #[ppc_name = __powikf2] #[cfg(f128_enabled)] pub extern "C" fn __powitf2(a: f128, b: i32) -> f128 { pow(a, b) diff --git a/library/compiler-builtins/compiler-builtins/src/float/sub.rs b/library/compiler-builtins/compiler-builtins/src/float/sub.rs index 11dd3b77d5d1c..7028b2ff8a80c 100644 --- a/library/compiler-builtins/compiler-builtins/src/float/sub.rs +++ b/library/compiler-builtins/compiler-builtins/src/float/sub.rs @@ -16,7 +16,7 @@ intrinsics! { crate::float::add::__adddf3(a, f64::from_bits(b.to_bits() ^ f64::SIGN_MASK)) } - #[ppc_alias = __subkf3] + #[ppc_name = __subkf3] #[cfg(f128_enabled)] pub extern "C" fn __subtf3(a: f128, b: f128) -> f128 { #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] diff --git a/library/compiler-builtins/compiler-builtins/src/float/trunc.rs b/library/compiler-builtins/compiler-builtins/src/float/trunc.rs index 1a88b0649fda3..0fa698e5fc5b1 100644 --- a/library/compiler-builtins/compiler-builtins/src/float/trunc.rs +++ b/library/compiler-builtins/compiler-builtins/src/float/trunc.rs @@ -146,21 +146,21 @@ intrinsics! { } #[aapcs_on_arm] - #[ppc_alias = __trunckfhf2] + #[ppc_name = __trunckfhf2] #[cfg(all(f16_enabled, f128_enabled))] pub extern "C" fn __trunctfhf2(a: f128) -> f16 { trunc(a) } #[aapcs_on_arm] - #[ppc_alias = __trunckfsf2] + #[ppc_name = __trunckfsf2] #[cfg(f128_enabled)] pub extern "C" fn __trunctfsf2(a: f128) -> f32 { trunc(a) } #[aapcs_on_arm] - #[ppc_alias = __trunckfdf2] + #[ppc_name = __trunckfdf2] #[cfg(f128_enabled)] pub extern "C" fn __trunctfdf2(a: f128) -> f64 { trunc(a) diff --git a/library/compiler-builtins/compiler-builtins/src/macros.rs b/library/compiler-builtins/compiler-builtins/src/macros.rs index 25bdbcf3f975e..0155c2799bc60 100644 --- a/library/compiler-builtins/compiler-builtins/src/macros.rs +++ b/library/compiler-builtins/compiler-builtins/src/macros.rs @@ -46,7 +46,7 @@ /// `"unadjusted"` abi on Win64 and the specified abi elsewhere. /// * `arm_aeabi_alias` - handles the "aliasing" of various intrinsics on ARM /// their otherwise typical names to other prefixed ones. -/// * `ppc_alias` - changes the name of the symbol on PowerPC platforms without +/// * `ppc_name` - changes the name of the symbol on PowerPC platforms without /// changing any other behavior. This is mostly for `f128`, which is `tf` on /// most platforms but `kf` on PowerPC. macro_rules! intrinsics { @@ -352,9 +352,9 @@ macro_rules! intrinsics { ); // PowerPC usually uses `kf` rather than `tf` for `f128`. This is just an easy - // way to add an alias on those targets. + // way to change the name on those targets. ( - #[ppc_alias = $alias:ident] + #[ppc_name = $ppc_name:ident] $(#[$($attr:tt)*])* pub extern $abi:tt fn $name:ident( $($argname:ident: $ty:ty),* ) $(-> $ret:ty)? { $($body:tt)* @@ -373,7 +373,7 @@ macro_rules! intrinsics { #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] intrinsics! { $(#[$($attr)*])* - pub extern $abi fn $alias( $($argname: $ty),* ) $(-> $ret)? { + pub extern $abi fn $ppc_name( $($argname: $ty),* ) $(-> $ret)? { $($body)* } } From 18af4dd14de636877ddd71dbc23b1aefd5b0a08b Mon Sep 17 00:00:00 2001 From: beetrees Date: Tue, 18 Aug 2026 15:08:45 +0100 Subject: [PATCH 13/28] c-b: Remove `#[aapcs_on_arm]` Fixes rust-lang/compiler-builtins#1271 by removing `#[aapcs_on_arm]`: `compiler-rt` only does the equivalent on ARM soft-float targets where the `"C"` ABI is already AAPCS. [ add PR description to commit - Trevor ] --- .../compiler-builtins/src/float/add.rs | 2 - .../compiler-builtins/src/float/extend.rs | 7 ---- .../compiler-builtins/src/float/mul.rs | 2 - .../compiler-builtins/src/float/trunc.rs | 7 ---- .../compiler-builtins/src/macros.rs | 38 +------------------ 5 files changed, 2 insertions(+), 54 deletions(-) diff --git a/library/compiler-builtins/compiler-builtins/src/float/add.rs b/library/compiler-builtins/compiler-builtins/src/float/add.rs index 6d51d32780cde..6503bc37dd75f 100644 --- a/library/compiler-builtins/compiler-builtins/src/float/add.rs +++ b/library/compiler-builtins/compiler-builtins/src/float/add.rs @@ -195,13 +195,11 @@ intrinsics! { add(a, b) } - #[aapcs_on_arm] #[arm_aeabi_alias = __aeabi_fadd] pub extern "C" fn __addsf3(a: f32, b: f32) -> f32 { add(a, b) } - #[aapcs_on_arm] #[arm_aeabi_alias = __aeabi_dadd] pub extern "C" fn __adddf3(a: f64, b: f64) -> f64 { add(a, b) diff --git a/library/compiler-builtins/compiler-builtins/src/float/extend.rs b/library/compiler-builtins/compiler-builtins/src/float/extend.rs index f6095ed1156f3..b0f5cdd6534de 100644 --- a/library/compiler-builtins/compiler-builtins/src/float/extend.rs +++ b/library/compiler-builtins/compiler-builtins/src/float/extend.rs @@ -69,7 +69,6 @@ where } intrinsics! { - #[aapcs_on_arm] #[arm_aeabi_alias = __aeabi_f2d] pub extern "C" fn __extendsfdf2(a: f32) -> f64 { extend(a) @@ -77,7 +76,6 @@ intrinsics! { } intrinsics! { - #[aapcs_on_arm] #[apple_f16_arg_abi] #[arm_aeabi_alias = __aeabi_h2f] #[cfg(f16_enabled)] @@ -85,35 +83,30 @@ intrinsics! { extend(a) } - #[aapcs_on_arm] #[apple_f16_arg_abi] #[cfg(f16_enabled)] pub extern "C" fn __gnu_h2f_ieee(a: f16) -> f32 { extend(a) } - #[aapcs_on_arm] #[apple_f16_arg_abi] #[cfg(f16_enabled)] pub extern "C" fn __extendhfdf2(a: f16) -> f64 { extend(a) } - #[aapcs_on_arm] #[ppc_name = __extendhfkf2] #[cfg(all(f16_enabled, f128_enabled))] pub extern "C" fn __extendhftf2(a: f16) -> f128 { extend(a) } - #[aapcs_on_arm] #[ppc_name = __extendsfkf2] #[cfg(f128_enabled)] pub extern "C" fn __extendsftf2(a: f32) -> f128 { extend(a) } - #[aapcs_on_arm] #[ppc_name = __extenddfkf2] #[cfg(f128_enabled)] pub extern "C" fn __extenddftf2(a: f64) -> f128 { diff --git a/library/compiler-builtins/compiler-builtins/src/float/mul.rs b/library/compiler-builtins/compiler-builtins/src/float/mul.rs index 6780d8397959b..1d5eb1a032d29 100644 --- a/library/compiler-builtins/compiler-builtins/src/float/mul.rs +++ b/library/compiler-builtins/compiler-builtins/src/float/mul.rs @@ -184,13 +184,11 @@ intrinsics! { mul(a, b) } - #[aapcs_on_arm] #[arm_aeabi_alias = __aeabi_fmul] pub extern "C" fn __mulsf3(a: f32, b: f32) -> f32 { mul(a, b) } - #[aapcs_on_arm] #[arm_aeabi_alias = __aeabi_dmul] pub extern "C" fn __muldf3(a: f64, b: f64) -> f64 { mul(a, b) diff --git a/library/compiler-builtins/compiler-builtins/src/float/trunc.rs b/library/compiler-builtins/compiler-builtins/src/float/trunc.rs index 0fa698e5fc5b1..1bac7b0957cd5 100644 --- a/library/compiler-builtins/compiler-builtins/src/float/trunc.rs +++ b/library/compiler-builtins/compiler-builtins/src/float/trunc.rs @@ -114,7 +114,6 @@ where } intrinsics! { - #[aapcs_on_arm] #[arm_aeabi_alias = __aeabi_d2f] pub extern "C" fn __truncdfsf2(a: f64) -> f32 { trunc(a) @@ -122,7 +121,6 @@ intrinsics! { } intrinsics! { - #[aapcs_on_arm] #[apple_f16_ret_abi] #[arm_aeabi_alias = __aeabi_f2h] #[cfg(f16_enabled)] @@ -130,14 +128,12 @@ intrinsics! { trunc(a) } - #[aapcs_on_arm] #[apple_f16_ret_abi] #[cfg(f16_enabled)] pub extern "C" fn __gnu_f2h_ieee(a: f32) -> f16 { trunc(a) } - #[aapcs_on_arm] #[apple_f16_ret_abi] #[arm_aeabi_alias = __aeabi_d2h] #[cfg(f16_enabled)] @@ -145,21 +141,18 @@ intrinsics! { trunc(a) } - #[aapcs_on_arm] #[ppc_name = __trunckfhf2] #[cfg(all(f16_enabled, f128_enabled))] pub extern "C" fn __trunctfhf2(a: f128) -> f16 { trunc(a) } - #[aapcs_on_arm] #[ppc_name = __trunckfsf2] #[cfg(f128_enabled)] pub extern "C" fn __trunctfsf2(a: f128) -> f32 { trunc(a) } - #[aapcs_on_arm] #[ppc_name = __trunckfdf2] #[cfg(f128_enabled)] pub extern "C" fn __trunctfdf2(a: f128) -> f64 { diff --git a/library/compiler-builtins/compiler-builtins/src/macros.rs b/library/compiler-builtins/compiler-builtins/src/macros.rs index 0155c2799bc60..42895773d3d92 100644 --- a/library/compiler-builtins/compiler-builtins/src/macros.rs +++ b/library/compiler-builtins/compiler-builtins/src/macros.rs @@ -38,12 +38,9 @@ /// /// A quick overview of attributes supported right now are: /// +// FIXME: Add missing attributes. /// * `maybe_use_optimized_c_shim` - indicates that the Rust implementation is /// ignored if an optimized C version was compiled. -/// * `aapcs_on_arm` - forces the ABI of the function to be `"aapcs"` on ARM and -/// the specified ABI everywhere else. -/// * `unadjusted_on_win64` - like `aapcs_on_arm` this switches to the -/// `"unadjusted"` abi on Win64 and the specified abi elsewhere. /// * `arm_aeabi_alias` - handles the "aliasing" of various intrinsics on ARM /// their otherwise typical names to other prefixed ones. /// * `ppc_name` - changes the name of the symbol on PowerPC platforms without @@ -170,38 +167,7 @@ macro_rules! intrinsics { intrinsics!($($rest)*); ); - // We recognize the `#[aapcs_on_arm]` attribute here and generate the - // same intrinsic but force it to have the `"aapcs"` calling convention on - // ARM and `"C"` elsewhere. - ( - #[aapcs_on_arm] - $(#[$($attr:tt)*])* - pub extern $abi:tt fn $name:ident( $($argname:ident: $ty:ty),* ) $(-> $ret:ty)? { - $($body:tt)* - } - - $($rest:tt)* - ) => ( - #[cfg(target_arch = "arm")] - intrinsics! { - $(#[$($attr)*])* - pub extern "aapcs" fn $name( $($argname: $ty),* ) $(-> $ret)? { - $($body)* - } - } - - #[cfg(not(target_arch = "arm"))] - intrinsics! { - $(#[$($attr)*])* - pub extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? { - $($body)* - } - } - - intrinsics!($($rest)*); - ); - - // `arm_aeabi_alias` would conflict with `f16_apple_{arg,ret}_abi` not handled here. Avoid macro ambiguity by combining in a + // `arm_aeabi_alias` would conflict with `apple_f16_{arg,ret}_abi` not handled here. Avoid macro ambiguity by combining in a // single `#[]`. ( #[apple_f16_arg_abi] From c757f718fa00edeaa8d9101dd3467ed9343e4c91 Mon Sep 17 00:00:00 2001 From: The rustc-josh-sync Cronjob Bot Date: Thu, 20 Aug 2026 04:20:57 +0000 Subject: [PATCH 14/28] Prepare for merging from rust-lang/rust This updates the rust-version file to f7d782a3be46d6bb4b9792fe69a61db389ba1769. --- 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 2f175e966812d..9ff8b0c27d19c 100644 --- a/library/compiler-builtins/rust-version +++ b/library/compiler-builtins/rust-version @@ -1 +1 @@ -2c39ff499469be916d4e45506d1afed69bbaddb7 +f7d782a3be46d6bb4b9792fe69a61db389ba1769 From c49aa70e57c3577fc82d7c88109a4f5485cf6b6b Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Thu, 20 Aug 2026 02:14:14 -0500 Subject: [PATCH 15/28] bench: Update pinned nightly to 2026-08-19 Some PRs want to make use of newer features. --- 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 9e44cbc4a4f16..f3bd5f8223e10 100644 --- a/library/compiler-builtins/.github/workflows/main.yaml +++ b/library/compiler-builtins/.github/workflows/main.yaml @@ -16,7 +16,7 @@ env: RUSTDOCFLAGS: -Dwarnings RUSTFLAGS: -Dwarnings -Dlinker_messages RUST_BACKTRACE: full - BENCHMARK_RUSTC: nightly-2026-08-06 # Pin the toolchain for reproducable results + BENCHMARK_RUSTC: nightly-2026-08-19 # Pin the toolchain for reproducable results defaults: run: From 20da4a39cff7d1174f89190eba108a3a6fbfe38f Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Sun, 23 Aug 2026 14:14:01 -0400 Subject: [PATCH 16/28] Revert "ci: Add a patch for compiler-rt execstack" This reverts commit 4feca6f3e62151f5cedacf3a5877b6200fb5af43. The patch has landed in the 23.1-2026-07-22 branch. --- .../.github/workflows/main.yaml | 2 +- ...ble-executable-stack-on-aeabi_u-read.patch | 95 ------------------- .../ci/download-compiler-rt.sh | 6 -- 3 files changed, 1 insertion(+), 102 deletions(-) delete mode 100644 library/compiler-builtins/ci/compiler-rt-patches/0001-compiler-rt-Disable-executable-stack-on-aeabi_u-read.patch diff --git a/library/compiler-builtins/.github/workflows/main.yaml b/library/compiler-builtins/.github/workflows/main.yaml index f3bd5f8223e10..eca717c13f5ef 100644 --- a/library/compiler-builtins/.github/workflows/main.yaml +++ b/library/compiler-builtins/.github/workflows/main.yaml @@ -162,7 +162,7 @@ jobs: uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: path: compiler-rt - key: ${{ runner.os }}-compiler-rt-${{ hashFiles('ci/download-compiler-rt.sh', 'ci/compiler-rt-patches') }} + key: ${{ runner.os }}-compiler-rt-${{ hashFiles('ci/download-compiler-rt.sh') }} - name: Download compiler-rt reference sources if: steps.cache-compiler-rt.outputs.cache-hit != 'true' run: ./ci/download-compiler-rt.sh diff --git a/library/compiler-builtins/ci/compiler-rt-patches/0001-compiler-rt-Disable-executable-stack-on-aeabi_u-read.patch b/library/compiler-builtins/ci/compiler-rt-patches/0001-compiler-rt-Disable-executable-stack-on-aeabi_u-read.patch deleted file mode 100644 index 13f4bc31d08f7..0000000000000 --- a/library/compiler-builtins/ci/compiler-rt-patches/0001-compiler-rt-Disable-executable-stack-on-aeabi_u-read.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 849c51e082b0958524246a0a880f46d468a55147 Mon Sep 17 00:00:00 2001 -From: Trevor Gross -Date: Thu, 6 Aug 2026 09:08:27 -0400 -Subject: [PATCH] [compiler-rt] Disable executable stack on - `aeabi_u{read,write}*.S` (#214465) - -These were missing `NO_EXEC_STACK_DIRECTIVE` to add `.note.GNU-stack`; -without it, a binary including any of these files will have the stack -marked executable. Add the directive here, matching other similar files. - -Symtab diff before: - -$ clang compiler-rt/lib/builtins/arm/aeabi_uread4.S ---target=arm-unknown-linux-gnueabi -c - $ llvm-readelf aeabi_uread4.o -S - There are 5 section headers, starting at offset 0xe4: - - Section Headers: -[Nr] Name Type Address Off Size ES Flg Lk Inf Al -[ 0] NULL 00000000 000000 000000 00 0 0 0 -[ 1] .strtab STRTAB 00000000 0000a8 000039 00 0 0 1 -[ 2] .text PROGBITS 00000000 000034 000020 00 AX 0 0 4 -[ 3] .ARM.attributes ARM_ATTRIBUTES 00000000 000054 000022 00 0 0 1 -[ 4] .symtab SYMTAB 00000000 000078 000030 10 1 2 4 - -After: - -$ clang compiler-rt/lib/builtins/arm/aeabi_uread4.S ---target=arm-unknown-linux-gnueabi -c - $ llvm-readelf aeabi_uread4.o -S - There are 6 section headers, starting at offset 0xf4: - - Section Headers: -[Nr] Name Type Address Off Size ES Flg Lk Inf Al -[ 0] NULL 00000000 000000 000000 00 0 0 0 -[ 1] .strtab STRTAB 00000000 0000a8 000049 00 0 0 1 -[ 2] .text PROGBITS 00000000 000034 000020 00 AX 0 0 4 -[ 3] .note.GNU-stack PROGBITS 00000000 000054 000000 00 0 0 1 -[ 4] .ARM.attributes ARM_ATTRIBUTES 00000000 000054 000022 00 0 0 1 -[ 5] .symtab SYMTAB 00000000 000078 000030 10 1 2 4 - -Fixes: 39413af931a7 ("[Compiler-rt] Implement AEABI Unaligned Read/Write - Helpers in compiler-rt (#167913)") ---- - -Add this patch to avoid a symcheck failure until the LLVM update can work -through. - - compiler-rt/lib/builtins/arm/aeabi_uread4.S | 1 + - compiler-rt/lib/builtins/arm/aeabi_uread8.S | 2 ++ - compiler-rt/lib/builtins/arm/aeabi_uwrite4.S | 2 ++ - compiler-rt/lib/builtins/arm/aeabi_uwrite8.S | 2 ++ - 4 files changed, 7 insertions(+) - -diff --git a/compiler-rt/lib/builtins/arm/aeabi_uread4.S b/compiler-rt/lib/builtins/arm/aeabi_uread4.S -index 4a54890fdf83..05e476a17905 100644 ---- a/compiler-rt/lib/builtins/arm/aeabi_uread4.S -+++ b/compiler-rt/lib/builtins/arm/aeabi_uread4.S -@@ -61,3 +61,4 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_uread4) - #endif - END_COMPILERRT_FUNCTION(__aeabi_uread4) - -+NO_EXEC_STACK_DIRECTIVE -diff --git a/compiler-rt/lib/builtins/arm/aeabi_uread8.S b/compiler-rt/lib/builtins/arm/aeabi_uread8.S -index 32844b8b3c7e..0b12c48ae46f 100644 ---- a/compiler-rt/lib/builtins/arm/aeabi_uread8.S -+++ b/compiler-rt/lib/builtins/arm/aeabi_uread8.S -@@ -98,3 +98,5 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_uread8) - #endif - - END_COMPILERRT_FUNCTION(__aeabi_uread8) -+ -+NO_EXEC_STACK_DIRECTIVE -diff --git a/compiler-rt/lib/builtins/arm/aeabi_uwrite4.S b/compiler-rt/lib/builtins/arm/aeabi_uwrite4.S -index 9f749695910b..7e9a0337b781 100644 ---- a/compiler-rt/lib/builtins/arm/aeabi_uwrite4.S -+++ b/compiler-rt/lib/builtins/arm/aeabi_uwrite4.S -@@ -33,3 +33,5 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_uwrite4) - #endif - bx lr - END_COMPILERRT_FUNCTION(__aeabi_uwrite4) -+ -+NO_EXEC_STACK_DIRECTIVE -diff --git a/compiler-rt/lib/builtins/arm/aeabi_uwrite8.S b/compiler-rt/lib/builtins/arm/aeabi_uwrite8.S -index 8188032fc3bd..763f42ff7ed0 100644 ---- a/compiler-rt/lib/builtins/arm/aeabi_uwrite8.S -+++ b/compiler-rt/lib/builtins/arm/aeabi_uwrite8.S -@@ -49,3 +49,5 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_uwrite8) - #endif - bx lr - END_COMPILERRT_FUNCTION(__aeabi_uwrite8) -+ -+NO_EXEC_STACK_DIRECTIVE --- -2.50.1 (Apple Git-155) diff --git a/library/compiler-builtins/ci/download-compiler-rt.sh b/library/compiler-builtins/ci/download-compiler-rt.sh index 55498c61d54b4..414e75c0dd6b7 100755 --- a/library/compiler-builtins/ci/download-compiler-rt.sh +++ b/library/compiler-builtins/ci/download-compiler-rt.sh @@ -8,9 +8,3 @@ rust_llvm_version=23.1-2026-07-22 curl -L --retry 3 -o code.tar.gz "https://github.com/rust-lang/llvm-project/archive/rustc/${rust_llvm_version}.tar.gz" tar xzf code.tar.gz --strip-components 1 llvm-project-rustc-${rust_llvm_version}/compiler-rt - -cd compiler-rt - -for p in ../ci/compiler-rt-patches/*; do - cat "$p" | patch -p 2 -done From 467cc0c3dbb8238cd4c168bae00bfa514722618a Mon Sep 17 00:00:00 2001 From: Aelin Reidel Date: Fri, 7 Aug 2026 12:18:19 +0200 Subject: [PATCH 17/28] ci: Disable install-action fallback for nextest This should make it fall back to a system-wide cargo-nextest install or running the tests without nextest, which is probably still faster than building nextest from source. --- library/compiler-builtins/.github/workflows/main.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/library/compiler-builtins/.github/workflows/main.yaml b/library/compiler-builtins/.github/workflows/main.yaml index eca717c13f5ef..4ee8bbe3e54f8 100644 --- a/library/compiler-builtins/.github/workflows/main.yaml +++ b/library/compiler-builtins/.github/workflows/main.yaml @@ -140,8 +140,13 @@ jobs: run: ./ci/install-test-deps.sh "$JOB_TARGET" "$JOB_CHANNEL" "$RUN_IN_DOCKER" - uses: taiki-e/install-action@7f4eb899022d8fe70b20c4f3de697aa85c309026 # v2.85.11 + continue-on-error: true with: tool: nextest@0.9.131 + # On platforms without prebuilts, nextest can be installed system-wide + # or omitted. Building it probably takes longer than running tests + # without it + fallback: none - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 with: From 3d8ae4ded52521f0f661d05cec923f46a7821550 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Tue, 25 Aug 2026 01:36:05 -0500 Subject: [PATCH 18/28] test: Allow Clippy's `needless-range-loop` This error started appearing in the latest nightly: error: the loop variable `i` is used to index `ret.0` --> builtins-test/tests/mem.rs:149:14 | 149 | for i in 0..N { | ^^^^ | note: for this index operation --> builtins-test/tests/mem.rs:150:9 | 150 | ret.0[i] = i as u8; | ^^^^^^^^ = help: for further information visit https://rust-lang.github.io/rust-clippy/main/index.html#needless_range_loop = note: `-D clippy::needless-range-loop` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::needless_range_loop)]` help: consider using an iterator and `.enumerate()` | 149 - for i in 0..N { 149 + for (i, ) in ret.0.iter_mut().enumerate().take(N) { | --- library/compiler-builtins/builtins-test/Cargo.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library/compiler-builtins/builtins-test/Cargo.toml b/library/compiler-builtins/builtins-test/Cargo.toml index f1a5be415675d..b3227b5751164 100644 --- a/library/compiler-builtins/builtins-test/Cargo.toml +++ b/library/compiler-builtins/builtins-test/Cargo.toml @@ -37,6 +37,10 @@ icount = ["dep:gungraun"] benchmarking-reports = ["walltime", "criterion/plotters", "criterion/html_reports"] walltime = ["dep:criterion"] +[lints.clippy] +# This sometimes reads better +needless-range-loop = "allow" + [[bench]] name = "float_add" harness = false From c620c1c568a6d26dddc5569d72f392fa48ac9110 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 17 Aug 2026 10:14:38 +0200 Subject: [PATCH 19/28] implement `Complex` mul and div --- .../builtins-test/tests/complex.rs | 426 ++++++++++++++++++ .../compiler-builtins/README.md | 28 +- .../compiler-builtins/build.rs | 13 +- .../src/float/complex/div.rs | 74 +++ .../src/float/complex/mod.rs | 2 + .../src/float/complex/mul.rs | 80 ++++ .../compiler-builtins/src/float/mod.rs | 1 + .../compiler-builtins/src/lib.rs | 1 + .../compiler-builtins/libm/src/math/mod.rs | 2 +- .../libm/src/math/support/float_traits.rs | 6 + 10 files changed, 607 insertions(+), 26 deletions(-) create mode 100644 library/compiler-builtins/builtins-test/tests/complex.rs create mode 100644 library/compiler-builtins/compiler-builtins/src/float/complex/div.rs create mode 100644 library/compiler-builtins/compiler-builtins/src/float/complex/mod.rs create mode 100644 library/compiler-builtins/compiler-builtins/src/float/complex/mul.rs diff --git a/library/compiler-builtins/builtins-test/tests/complex.rs b/library/compiler-builtins/builtins-test/tests/complex.rs new file mode 100644 index 0000000000000..a67a1b3c58783 --- /dev/null +++ b/library/compiler-builtins/builtins-test/tests/complex.rs @@ -0,0 +1,426 @@ +#![cfg_attr(f16_enabled, feature(f16))] +#![cfg_attr(f128_enabled, feature(f128))] +#![feature(complex_numbers)] +#![allow(unused_features)] + +mod complex { + use core::num::Complex; + + use compiler_builtins::support::Float; + + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + enum Class { + /// Both components are NaN. + NaN, + /// At least one component is infinite. + Infinite, + /// Both components are zero. + Zero, + /// One component is a "regular" number, the other is NaN. + NonZeroAndNaN, + /// Both components are "regular" numbers. + NonZero, + } + + fn classify(c: Complex) -> Class { + if c.re == F::ZERO && c.im == F::ZERO { + Class::Zero + } else if c.re.is_infinite() || c.im.is_infinite() { + Class::Infinite + } else if c.re.is_nan() && c.im.is_nan() { + Class::NaN + } else if c.re.is_nan() { + if c.im == F::ZERO { + Class::NaN + } else { + Class::NonZeroAndNaN + } + } else if c.im.is_nan() { + if c.re == F::ZERO { + Class::NaN + } else { + Class::NonZeroAndNaN + } + } else { + Class::NonZero + } + } + + fn test_mul(p: Complex, q: Complex, actual: Complex, tolerance: F) -> bool { + let expected = match classify(p) { + Class::Zero => match classify(q) { + Class::Zero | Class::NonZero => Class::Zero, + Class::Infinite | Class::NaN | Class::NonZeroAndNaN => Class::NaN, + }, + + Class::NonZero => match classify(q) { + Class::Zero => Class::Zero, + Class::NonZero => { + if classify(actual) != Class::NonZero { + return true; + } + + let Complex { re: a, im: b } = p; + let Complex { re: c, im: d } = q; + + let z = Complex::new(a * c - b * d, a * d + b * c); + let r = actual; + + let diff_re = r.re - z.re; + let diff_im = r.im - z.im; + + let diff_sq = diff_re * diff_re + diff_im * diff_im; + let mag_sq = r.re * r.re + r.im * r.im; + + if diff_sq > (tolerance * tolerance) * mag_sq { + return true; + } + + return false; + } + Class::Infinite => Class::Infinite, + Class::NaN | Class::NonZeroAndNaN => Class::NaN, + }, + + Class::Infinite => match classify(q) { + Class::Zero | Class::NaN => Class::NaN, + Class::NonZero | Class::Infinite | Class::NonZeroAndNaN => Class::Infinite, + }, + + Class::NaN => Class::NaN, + + Class::NonZeroAndNaN => match classify(q) { + Class::Infinite => Class::Infinite, + Class::Zero | Class::NonZero | Class::NaN | Class::NonZeroAndNaN => Class::NaN, + }, + }; + + classify(actual) != expected + } + + fn test_div( + dividend: Complex, + divisor: Complex, + actual: Complex, + tolerance: F, + ) -> bool { + let expected = match classify(dividend) { + Class::Zero => match classify(divisor) { + Class::Zero => Class::NaN, + Class::NonZero => Class::Zero, + Class::Infinite => Class::Zero, + Class::NaN => Class::NaN, + Class::NonZeroAndNaN => Class::NaN, + }, + + Class::NonZero => match classify(divisor) { + Class::Zero => Class::Infinite, + Class::NonZero => { + if classify(actual) != Class::NonZero { + return true; + } + + let Complex { re: a, im: b } = dividend; + let Complex { re: c, im: d } = divisor; + + let denominator = c * c + d * d; + let z = Complex::new( + (a * c + b * d) / denominator, // + (b * c - a * d) / denominator, + ); + + let r = actual; + + let diff_re = r.re - z.re; + let diff_im = r.im - z.im; + + let diff_sq = diff_re * diff_re + diff_im * diff_im; + let mag_sq = r.re * r.re + r.im * r.im; + + if diff_sq > (tolerance * tolerance) * mag_sq { + return true; + } + + return false; + } + Class::Infinite => Class::Zero, + Class::NaN => Class::NaN, + Class::NonZeroAndNaN => Class::NaN, + }, + + Class::Infinite => match classify(divisor) { + Class::Zero | Class::NonZero => Class::Infinite, + Class::Infinite | Class::NaN | Class::NonZeroAndNaN => Class::NaN, + }, + + Class::NaN => Class::NaN, + + Class::NonZeroAndNaN => match classify(divisor) { + Class::Zero => Class::Infinite, + Class::NonZero | Class::Infinite | Class::NaN | Class::NonZeroAndNaN => Class::NaN, + }, + }; + + classify(actual) != expected + } + + macro_rules! complex_test_data { + ($f:ty) => {{ + const INFINITY: $f = <$f>::INFINITY; + const NEG_INFINITY: $f = <$f>::NEG_INFINITY; + const NAN: $f = <$f>::NAN; + const SNAN: $f = <$f>::SNAN; + + #[allow(overflowing_literals)] + let (small, big) = if size_of::<$f>() == 2 { + (1.0e-2, 1.0e2) + } else { + (1.0e-6, 1.0e6) + }; + + [ + Complex::new(small, small), + Complex::new(-small, small), + Complex::new(-small, -small), + Complex::new(small, -small), + Complex::new(big, small), + Complex::new(-big, small), + Complex::new(-big, -small), + Complex::new(big, -small), + Complex::new(small, big), + Complex::new(-small, big), + Complex::new(-small, -big), + Complex::new(small, -big), + Complex::new(big, big), + Complex::new(-big, big), + Complex::new(-big, -big), + Complex::new(big, -big), + Complex::new(NAN, NAN), + Complex::new(NEG_INFINITY, NAN), + Complex::new(-2., NAN), + Complex::new(-1., NAN), + Complex::new(-0.5, NAN), + Complex::new(-0., NAN), + Complex::new(0., NAN), + Complex::new(0.5, NAN), + Complex::new(1., NAN), + Complex::new(2., NAN), + Complex::new(INFINITY, NAN), + Complex::new(NAN, NEG_INFINITY), + Complex::new(NEG_INFINITY, NEG_INFINITY), + Complex::new(-2., NEG_INFINITY), + Complex::new(-1., NEG_INFINITY), + Complex::new(-0.5, NEG_INFINITY), + Complex::new(-0., NEG_INFINITY), + Complex::new(0., NEG_INFINITY), + Complex::new(0.5, NEG_INFINITY), + Complex::new(1., NEG_INFINITY), + Complex::new(2., NEG_INFINITY), + Complex::new(INFINITY, NEG_INFINITY), + Complex::new(NAN, -2.), + Complex::new(NEG_INFINITY, -2.), + Complex::new(-2., -2.), + Complex::new(-1., -2.), + Complex::new(-0.5, -2.), + Complex::new(-0., -2.), + Complex::new(0., -2.), + Complex::new(0.5, -2.), + Complex::new(1., -2.), + Complex::new(2., -2.), + Complex::new(INFINITY, -2.), + Complex::new(NAN, -1.), + Complex::new(NEG_INFINITY, -1.), + Complex::new(-2., -1.), + Complex::new(-1., -1.), + Complex::new(-0.5, -1.), + Complex::new(-0., -1.), + Complex::new(0., -1.), + Complex::new(0.5, -1.), + Complex::new(1., -1.), + Complex::new(2., -1.), + Complex::new(INFINITY, -1.), + Complex::new(NAN, -0.5), + Complex::new(NEG_INFINITY, -0.5), + Complex::new(-2., -0.5), + Complex::new(-1., -0.5), + Complex::new(-0.5, -0.5), + Complex::new(-0., -0.5), + Complex::new(0., -0.5), + Complex::new(0.5, -0.5), + Complex::new(1., -0.5), + Complex::new(2., -0.5), + Complex::new(INFINITY, -0.5), + Complex::new(NAN, -0.), + Complex::new(NEG_INFINITY, -0.), + Complex::new(-2., -0.), + Complex::new(-1., -0.), + Complex::new(-0.5, -0.), + Complex::new(-0., -0.), + Complex::new(0., -0.), + Complex::new(0.5, -0.), + Complex::new(1., -0.), + Complex::new(2., -0.), + Complex::new(INFINITY, -0.), + Complex::new(NAN, 0.), + Complex::new(NEG_INFINITY, 0.), + Complex::new(-2., 0.), + Complex::new(-1., 0.), + Complex::new(-0.5, 0.), + Complex::new(-0., 0.), + Complex::new(0., 0.), + Complex::new(0.5, 0.), + Complex::new(1., 0.), + Complex::new(2., 0.), + Complex::new(INFINITY, 0.), + Complex::new(NAN, 0.5), + Complex::new(NEG_INFINITY, 0.5), + Complex::new(-2., 0.5), + Complex::new(-1., 0.5), + Complex::new(-0.5, 0.5), + Complex::new(-0., 0.5), + Complex::new(0., 0.5), + Complex::new(0.5, 0.5), + Complex::new(1., 0.5), + Complex::new(2., 0.5), + Complex::new(INFINITY, 0.5), + Complex::new(NAN, 1.), + Complex::new(NEG_INFINITY, 1.), + Complex::new(-2., 1.), + Complex::new(-1., 1.), + Complex::new(-0.5, 1.), + Complex::new(-0., 1.), + Complex::new(0., 1.), + Complex::new(0.5, 1.), + Complex::new(1., 1.), + Complex::new(2., 1.), + Complex::new(INFINITY, 1.), + Complex::new(NAN, 2.), + Complex::new(NEG_INFINITY, 2.), + Complex::new(-2., 2.), + Complex::new(-1., 2.), + Complex::new(-0.5, 2.), + Complex::new(-0., 2.), + Complex::new(0., 2.), + Complex::new(0.5, 2.), + Complex::new(1., 2.), + Complex::new(2., 2.), + Complex::new(INFINITY, 2.), + Complex::new(NAN, INFINITY), + Complex::new(NEG_INFINITY, INFINITY), + Complex::new(-2., INFINITY), + Complex::new(-1., INFINITY), + Complex::new(-0.5, INFINITY), + Complex::new(-0., INFINITY), + Complex::new(0., INFINITY), + Complex::new(0.5, INFINITY), + Complex::new(1., INFINITY), + Complex::new(2., INFINITY), + Complex::new(INFINITY, INFINITY), + Complex::new(INFINITY, SNAN), + ] + }}; + } + + macro_rules! complex_mul { + ($($f:ty, $fn:ident, $tolerance:literal);*;) => { + + $( + #[test] + fn $fn() { + use compiler_builtins::float::complex::mul::$fn; + + let input = complex_test_data!($f); + + for p in input { + for q in input { + let Complex{ re: a, im: b } = p; + let Complex{ re: c, im: d } = q; + + let actual = $fn(a, b, c, d); + + assert!( + !test_mul(p, q, actual, $tolerance), + "{func}({a:?}, {b:?}, {c:?}, {d:?}): incorrect ({:?}, {:?})", + actual.re, + actual.im, + func = stringify!($fn), + ); + } + } + } + )* + }; + } + + macro_rules! complex_div { + ($($f:ty, $fn:ident, $tolerance:literal);*;) => { + $( + #[test] + fn $fn() { + use compiler_builtins::float::complex::div::$fn; + + let input = complex_test_data!($f); + + for p in input { + for q in input { + let Complex{ re: a, im: b } = p; + let Complex{ re: c, im: d } = q; + + let actual = $fn(a, b, c, d); + + assert!( + !test_div(p, q, actual, $tolerance), + "{func}({a:?}, {b:?}, {c:?}, {d:?}): incorrect ({:?}, {:?})", + actual.re, + actual.im, + func = stringify!($fn), + ); + } + } + } + )* + }; + } + + #[cfg(all(f16_enabled, not(x86_no_sse2)))] + complex_mul! { + f16, __rust_mulhc3, 1.0e-3; + } + + #[cfg(all(f16_enabled, not(x86_no_sse2)))] + complex_div! { + f16, __rust_divhc3, 1.0e-3; + } + + complex_mul! { + f32, __rust_mulsc3, 1.0e-6; + f64, __rust_muldc3, 1.0e-9; + } + + complex_div! { + f32, __rust_divsc3, 1.0e-6; + f64, __rust_divdc3, 1.0e-9; + } + + #[cfg(f128_enabled)] + cfg_select! { + any(target_arch = "powerpc", target_arch = "powerpc64") => { + complex_mul! { + f128, __rust_mulkc3, 1.0e-12; + } + + complex_div! { + f128, __rust_divkc3, 1.0e-12; + } + } + _ => { + complex_mul! { + f128, __rust_multc3, 1.0e-12; + } + + complex_div! { + f128, __rust_divtc3, 1.0e-12; + } + } + } +} diff --git a/library/compiler-builtins/compiler-builtins/README.md b/library/compiler-builtins/compiler-builtins/README.md index 63cbf33d2aea2..72faec3dc5c97 100644 --- a/library/compiler-builtins/compiler-builtins/README.md +++ b/library/compiler-builtins/compiler-builtins/README.md @@ -174,6 +174,15 @@ of being added to Rust. - [x] trunctfhf2.c - [x] trunctfsf2.c +These builtins involve complex floating-point types that are in the process of +being added to Rust. + +- [x] divdc3.c +- [x] divsc3.c +- [x] divtc3.c +- [x] muldc3.c +- [x] mulsc3.c +- [x] multc3.c These builtins are used by the Hexagon DSP @@ -223,6 +232,12 @@ by Rust. - ~~i386/floatundixf.S~~ - ~~x86_64/floatdixf.c~~ - ~~x86_64/floatundixf.S~~ +- ~~powixf2.c~~ + +These builtins are for complex X87 `f80` floating-point numbers. + +- ~~divxc3.c~~ +- ~~mulxc3.c~~ These builtins are for IBM "extended double" non-IEEE 128-bit floating-point numbers. @@ -248,19 +263,6 @@ supported by Rust. - ~~truncsfbf2.c~~ - ~~trunctfxf2.c~~ -These builtins involve complex floating-point types that are not supported by -Rust. - -- ~~divdc3.c~~ -- ~~divsc3.c~~ -- ~~divtc3.c~~ -- ~~divxc3.c~~ -- ~~muldc3.c~~ -- ~~mulsc3.c~~ -- ~~multc3.c~~ -- ~~mulxc3.c~~ -- ~~powixf2.c~~ - These builtins are never called by LLVM. - ~~absvdi2.c~~ diff --git a/library/compiler-builtins/compiler-builtins/build.rs b/library/compiler-builtins/compiler-builtins/build.rs index 8869add9f5ee4..64a4e3b6c9e9c 100644 --- a/library/compiler-builtins/compiler-builtins/build.rs +++ b/library/compiler-builtins/compiler-builtins/build.rs @@ -297,14 +297,7 @@ mod c { ]); if consider_float_intrinsics { - sources.extend(&[ - ("__divdc3", "divdc3.c"), - ("__divsc3", "divsc3.c"), - ("__muldc3", "muldc3.c"), - ("__mulsc3", "mulsc3.c"), - ("__negdf2", "negdf2.c"), - ("__negsf2", "negsf2.c"), - ]); + sources.extend(&[("__negdf2", "negdf2.c"), ("__negsf2", "negsf2.c")]); } // On iOS and 32-bit OSX these are all just empty intrinsics, no need to @@ -460,10 +453,6 @@ mod c { ("__fe_getround", "fp_mode.c"), ("__fe_raise_inexact", "fp_mode.c"), ]); - - if cfg.target_os != "windows" && cfg.target_os != "cygwin" { - sources.extend(&[("__multc3", "multc3.c")]); - } } if cfg.target_arch == "mips" || cfg.target_arch == "riscv32" || cfg.target_arch == "riscv64" diff --git a/library/compiler-builtins/compiler-builtins/src/float/complex/div.rs b/library/compiler-builtins/compiler-builtins/src/float/complex/div.rs new file mode 100644 index 0000000000000..4a8d6b7231c67 --- /dev/null +++ b/library/compiler-builtins/compiler-builtins/src/float/complex/div.rs @@ -0,0 +1,74 @@ +use core::num::Complex; + +use crate::math::libm_math::generic::{fmax, ilogb, scalbn}; +use crate::support::{CastInto, Float}; + +/// Returns the quotient of `(a + ib)` and `(c + id)`. +/// +/// This implementation uses the standard formula, but has special behavior when the output +/// of that formula has both a real and imaginary component that are NaN. +fn complex_div(mut a: F, mut b: F, mut c: F, mut d: F) -> Complex +where + u32: CastInto, +{ + let max = fmax(c.abs(), d.abs()); + let mut ilogbw = 0; + if max.is_finite() && max != F::ZERO { + ilogbw = ilogb(max); + c = scalbn(c, -ilogbw); + d = scalbn(d, -ilogbw); + } + + let denom = c * c + d * d; + let mut z = Complex::new( + scalbn((a * c + b * d) / denom, -ilogbw), + scalbn((b * c - a * d) / denom, -ilogbw), + ); + + // The fast path: exit when at least one component is not NaN. + if !(z.re.is_nan() && z.im.is_nan()) { + return z; + } + + let signed_unit_if_inf = |x: F| { + let mag = if x.is_infinite() { F::ONE } else { F::ZERO }; + mag.copysign(x) + }; + + if denom == F::ZERO && (!a.is_nan() || !b.is_nan()) { + z.re = F::INFINITY.copysign(c) * a; + z.im = F::INFINITY.copysign(c) * b; + } else if (a.is_infinite() || b.is_infinite()) && c.is_finite() && d.is_finite() { + a = signed_unit_if_inf(a); + b = signed_unit_if_inf(b); + z.re = F::INFINITY * (a * c + b * d); + z.im = F::INFINITY * (b * c - a * d); + } else if max.is_infinite() && a.is_finite() && b.is_finite() { + c = signed_unit_if_inf(c); + d = signed_unit_if_inf(d); + z.re = F::ZERO * (a * c + b * d); + z.im = F::ZERO * (b * c - a * d); + } + + z +} + +intrinsics! { + #[cfg(all(f16_enabled, not(x86_no_sse2)))] + pub extern "C" fn __rust_divhc3(a: f16, b: f16, c: f16, d: f16) -> core::num::Complex { + complex_div(a, b, c, d) + } + + pub extern "C" fn __rust_divsc3(a: f32, b: f32, c: f32, d: f32) -> core::num::Complex { + complex_div(a, b, c, d) + } + + pub extern "C" fn __rust_divdc3(a: f64, b: f64, c: f64, d: f64) -> core::num::Complex { + complex_div(a, b, c, d) + } + + #[cfg(f128_enabled)] + pub extern "C" fn __rust_divtc3(a: f128, b: f128, c: f128, d: f128) -> core::num::Complex { + complex_div(a, b, c, d) + } +} diff --git a/library/compiler-builtins/compiler-builtins/src/float/complex/mod.rs b/library/compiler-builtins/compiler-builtins/src/float/complex/mod.rs new file mode 100644 index 0000000000000..5e67fbb85b206 --- /dev/null +++ b/library/compiler-builtins/compiler-builtins/src/float/complex/mod.rs @@ -0,0 +1,2 @@ +pub mod div; +pub mod mul; diff --git a/library/compiler-builtins/compiler-builtins/src/float/complex/mul.rs b/library/compiler-builtins/compiler-builtins/src/float/complex/mul.rs new file mode 100644 index 0000000000000..66c5d42baab3b --- /dev/null +++ b/library/compiler-builtins/compiler-builtins/src/float/complex/mul.rs @@ -0,0 +1,80 @@ +use core::num::Complex; + +use crate::support::Float; + +/// Returns the product of `a + ib` and `c + id`. +/// +/// The standard formula is `(ac - bd) + (ad + bc)i`, but this function has custom behavior when +/// both the real and imaginary components of that expression are NaN. +fn complex_mul(mut a: F, mut b: F, mut c: F, mut d: F) -> Complex { + let ac = a * c; + let bd = b * d; + let ad = a * d; + let bc = b * c; + + let z = Complex::new(ac - bd, ad + bc); + + // The fast path: exit when at least one component is not NaN. + if !(z.re.is_nan() && z.im.is_nan()) { + return z; + } + + let zero_if_nan = |x: F| if x.is_nan() { F::ZERO.copysign(x) } else { x }; + + let signed_unit_if_inf = |x: F| { + let mag = if x.is_infinite() { F::ONE } else { F::ZERO }; + mag.copysign(x) + }; + + let mut recalc = false; + + if a.is_infinite() || b.is_infinite() { + a = signed_unit_if_inf(a); + b = signed_unit_if_inf(b); + c = zero_if_nan(c); + d = zero_if_nan(d); + recalc = true; + } + + if c.is_infinite() || d.is_infinite() { + c = signed_unit_if_inf(c); + d = signed_unit_if_inf(d); + a = zero_if_nan(a); + b = zero_if_nan(b); + recalc = true; + } + + if !recalc && (ac.is_infinite() || bd.is_infinite() || ad.is_infinite() || bc.is_infinite()) { + a = zero_if_nan(a); + b = zero_if_nan(b); + c = zero_if_nan(c); + d = zero_if_nan(d); + recalc = true; + } + + if !recalc { + return z; + } + + Complex::new(F::INFINITY * (a * c - b * d), F::INFINITY * (a * d + b * c)) +} + +intrinsics! { + #[cfg(all(f16_enabled, not(x86_no_sse2)))] + pub extern "C" fn __rust_mulhc3(a: f16, b: f16, c: f16, d: f16) -> core::num::Complex { + complex_mul(a, b, c, d) + } + + pub extern "C" fn __rust_mulsc3(a: f32, b: f32, c: f32, d: f32) -> core::num::Complex { + complex_mul(a, b, c, d) + } + + pub extern "C" fn __rust_muldc3(a: f64, b: f64, c: f64, d: f64) -> core::num::Complex { + complex_mul(a, b, c, d) + } + + #[cfg(f128_enabled)] + pub extern "C" fn __rust_multc3(a: f128, b: f128, c: f128, d: f128) -> core::num::Complex { + complex_mul(a, b, c, d) + } +} diff --git a/library/compiler-builtins/compiler-builtins/src/float/mod.rs b/library/compiler-builtins/compiler-builtins/src/float/mod.rs index 15318c4928804..df45d0603fc14 100644 --- a/library/compiler-builtins/compiler-builtins/src/float/mod.rs +++ b/library/compiler-builtins/compiler-builtins/src/float/mod.rs @@ -1,5 +1,6 @@ pub mod add; pub mod cmp; +pub mod complex; pub mod conv; pub mod div; pub mod extend; diff --git a/library/compiler-builtins/compiler-builtins/src/lib.rs b/library/compiler-builtins/compiler-builtins/src/lib.rs index 829475dcd42e2..0d25495abf8aa 100644 --- a/library/compiler-builtins/compiler-builtins/src/lib.rs +++ b/library/compiler-builtins/compiler-builtins/src/lib.rs @@ -7,6 +7,7 @@ #![feature(asm_experimental_arch)] #![feature(cfg_target_has_atomic)] #![feature(compiler_builtins)] +#![feature(complex_numbers)] #![feature(core_intrinsics)] #![feature(linkage)] #![feature(repr_simd)] diff --git a/library/compiler-builtins/libm/src/math/mod.rs b/library/compiler-builtins/libm/src/math/mod.rs index 50b42e0c07972..51a3417c8b151 100644 --- a/library/compiler-builtins/libm/src/math/mod.rs +++ b/library/compiler-builtins/libm/src/math/mod.rs @@ -72,7 +72,7 @@ cfg_select_nofmt! { pub mod generic; } _ => { - mod generic; + pub(crate) mod generic; } } 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 f802f4be6c2d7..1bded45ea930e 100644 --- a/library/compiler-builtins/libm/src/math/support/float_traits.rs +++ b/library/compiler-builtins/libm/src/math/support/float_traits.rs @@ -153,6 +153,12 @@ pub trait Float: /// Returns true if the value is +inf or -inf. fn is_infinite(self) -> bool; + /// Returns true if this number is neither infinite nor NaN. + #[allow(dead_code)] + fn is_finite(self) -> bool { + self.abs() < Self::INFINITY + } + /// Returns true if the sign is negative. Extracts the sign bit regardless of zero or NaN. fn is_sign_negative(self) -> bool; From e853a108a672b433b6e07e81de5ae7a74c9b4f9a Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Tue, 25 Aug 2026 23:34:04 -0500 Subject: [PATCH 20/28] test: Move `AlignedSlice` from the benchmark to `builtins-test` Prepare for reuse elsewhere. --- .../builtins-test/benches/mem_icount.rs | 55 ++------------ .../builtins-test/src/lib.rs | 1 + .../builtins-test/src/mem.rs | 75 +++++++++++++++++++ .../builtins-test/tests/mem.rs | 1 - 4 files changed, 82 insertions(+), 50 deletions(-) create mode 100644 library/compiler-builtins/builtins-test/src/mem.rs diff --git a/library/compiler-builtins/builtins-test/benches/mem_icount.rs b/library/compiler-builtins/builtins-test/benches/mem_icount.rs index 7a3cad09b4044..2e4dc2c03a723 100644 --- a/library/compiler-builtins/builtins-test/benches/mem_icount.rs +++ b/library/compiler-builtins/builtins-test/benches/mem_icount.rs @@ -2,57 +2,11 @@ //! is stable enough to be tested in CI. use std::hint::black_box; -use std::{ops, slice}; +use builtins_test::mem::{AlignedSlice, MAX_TESTED_ALIGN, MEG1}; use compiler_builtins::mem::{memcmp, memcpy, memmove, memset}; use gungraun::{library_benchmark, library_benchmark_group, main}; -const PAGE_SIZE: usize = 0x1000; // 4 kiB -const MAX_ALIGN: usize = 512; // assume we may use avx512 operations one day -const MEG1: usize = 1 << 20; // 1 MiB - -#[derive(Clone)] -#[repr(C, align(0x1000))] -struct Page([u8; PAGE_SIZE]); - -/// A buffer that is page-aligned by default, with an optional offset to create a -/// misalignment. -struct AlignedSlice { - buf: Box<[Page]>, - len: usize, - offset: usize, -} - -impl AlignedSlice { - /// Allocate a slice aligned to ALIGN with at least `len` items, with `offset` from - /// page alignment. - fn new_zeroed(len: usize, offset: usize) -> Self { - assert!(offset < PAGE_SIZE); - let total_len = len + offset; - let items = (total_len / PAGE_SIZE) + if total_len % PAGE_SIZE > 0 { 1 } else { 0 }; - let buf = vec![Page([0u8; PAGE_SIZE]); items].into_boxed_slice(); - AlignedSlice { buf, len, offset } - } -} - -impl ops::Deref for AlignedSlice { - type Target = [u8]; - fn deref(&self) -> &Self::Target { - unsafe { slice::from_raw_parts(self.buf.as_ptr().cast::().add(self.offset), self.len) } - } -} - -impl ops::DerefMut for AlignedSlice { - fn deref_mut(&mut self) -> &mut Self::Target { - unsafe { - slice::from_raw_parts_mut( - self.buf.as_mut_ptr().cast::().add(self.offset), - self.len, - ) - } - } -} - mod mcpy { use super::*; @@ -265,8 +219,11 @@ mod mmove { match spread { // Note that this test doesn't make sense for lengths less than len=128 Aligned => { - assert!(len > MAX_ALIGN, "aligned memset would have no overlap"); - MAX_ALIGN + assert!( + len > MAX_TESTED_ALIGN, + "aligned memset would have no overlap" + ); + MAX_TESTED_ALIGN } Small => 1, Medium => (len / 2) + 1, // add 1 so all are misaligned diff --git a/library/compiler-builtins/builtins-test/src/lib.rs b/library/compiler-builtins/builtins-test/src/lib.rs index 56c04e551df9d..ebd0162dfae05 100644 --- a/library/compiler-builtins/builtins-test/src/lib.rs +++ b/library/compiler-builtins/builtins-test/src/lib.rs @@ -17,6 +17,7 @@ #![cfg_attr(f16_enabled, feature(f16))] pub mod bench; +pub mod mem; extern crate alloc; use compiler_builtins::support::{Float, Int, MinInt}; diff --git a/library/compiler-builtins/builtins-test/src/mem.rs b/library/compiler-builtins/builtins-test/src/mem.rs new file mode 100644 index 0000000000000..237f8322e64ee --- /dev/null +++ b/library/compiler-builtins/builtins-test/src/mem.rs @@ -0,0 +1,75 @@ +extern crate alloc; + +use alloc::boxed::Box; +use alloc::vec; +use core::{ops, slice}; + +/// 4 kiB +pub const PAGE_SIZE: usize = 0x1000; +/// 1 MiB +pub const MEG1: usize = 1 << 20; +/// When we want to test behavior that may depend on aligned reads/writes, use this value. Large +/// enough for AVX512. +pub const MAX_TESTED_ALIGN: usize = 512; + +#[derive(Clone)] +#[repr(C, align(0x1000))] +struct Page([u8; PAGE_SIZE]); + +/// A buffer that is page-aligned by default and dereferences to a slice, with an optional offset +/// for the deref to create a misaligned buffer. +pub struct AlignedSlice { + buf: Box<[Page]>, + len: usize, + offset: usize, +} + +impl AlignedSlice { + /// Allocate a slice aligned to ALIGN with at least `len` items, with `offset` from + /// page alignment. + pub fn new_zeroed(len: usize, offset: usize) -> Self { + assert!(offset < PAGE_SIZE); + let total_len = len + offset; + let limbs = total_len.div_ceil(PAGE_SIZE); + let buf = vec![Page([0u8; PAGE_SIZE]); limbs].into_boxed_slice(); + AlignedSlice { buf, len, offset } + } +} + +impl ops::Deref for AlignedSlice { + type Target = [u8]; + fn deref(&self) -> &Self::Target { + unsafe { slice::from_raw_parts(self.buf.as_ptr().cast::().add(self.offset), self.len) } + } +} + +impl ops::DerefMut for AlignedSlice { + fn deref_mut(&mut self) -> &mut Self::Target { + unsafe { + slice::from_raw_parts_mut( + self.buf.as_mut_ptr().cast::().add(self.offset), + self.len, + ) + } + } +} + +#[test] +fn test_alignment() { + let v = AlignedSlice::new_zeroed(1, 0); + assert_eq!(v.len(), 1); + assert_eq!(v.as_ptr().addr() % PAGE_SIZE, 0); + + let v = AlignedSlice::new_zeroed(PAGE_SIZE + 1, 0); + assert_eq!(v.len(), PAGE_SIZE + 1); + assert_eq!(v.as_ptr().addr() % PAGE_SIZE, 0); + + let v = AlignedSlice::new_zeroed(1, 1); + assert_eq!(v.len(), 1); + assert_eq!(v.as_ptr().addr() % 2, 1); + + let v = AlignedSlice::new_zeroed(1, 64); + assert_eq!(v.len(), 1); + assert_eq!(v.as_ptr().addr() % 64, 0); + assert_eq!(v.as_ptr().addr() % 128, 64); +} diff --git a/library/compiler-builtins/builtins-test/tests/mem.rs b/library/compiler-builtins/builtins-test/tests/mem.rs index d838ef159a024..5d6f7d225bd9e 100644 --- a/library/compiler-builtins/builtins-test/tests/mem.rs +++ b/library/compiler-builtins/builtins-test/tests/mem.rs @@ -1,4 +1,3 @@ -extern crate compiler_builtins; use compiler_builtins::mem::{memcmp, memcpy, memmove, memset}; const WORD_SIZE: usize = core::mem::size_of::(); From 53e4a92e1f23dba379aacd56261c355ac563b6c0 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Wed, 26 Aug 2026 00:46:22 -0500 Subject: [PATCH 21/28] test: Move `mem` config and setup functions to `builtins-test` Prepare for reuse elsewhere. --- .../builtins-test/benches/mem_icount.rs | 118 ++---------------- .../builtins-test/src/mem.rs | 116 +++++++++++++++++ 2 files changed, 129 insertions(+), 105 deletions(-) diff --git a/library/compiler-builtins/builtins-test/benches/mem_icount.rs b/library/compiler-builtins/builtins-test/benches/mem_icount.rs index 2e4dc2c03a723..b0f0b77a8beb1 100644 --- a/library/compiler-builtins/builtins-test/benches/mem_icount.rs +++ b/library/compiler-builtins/builtins-test/benches/mem_icount.rs @@ -3,27 +3,14 @@ use std::hint::black_box; -use builtins_test::mem::{AlignedSlice, MAX_TESTED_ALIGN, MEG1}; -use compiler_builtins::mem::{memcmp, memcpy, memmove, memset}; +use builtins_test::mem::{AlignedSlice, MEG1}; use gungraun::{library_benchmark, library_benchmark_group, main}; mod mcpy { - use super::*; - - struct Cfg { - len: usize, - s_off: usize, - d_off: usize, - } + use builtins_test::mem::mcpy::{Cfg, setup}; + use compiler_builtins::mem::memcpy; - fn setup(cfg: Cfg) -> (usize, AlignedSlice, AlignedSlice) { - let Cfg { len, s_off, d_off } = cfg; - println!("bytes: {len} bytes, src offset: {s_off}, dst offset: {d_off}"); - let mut src = AlignedSlice::new_zeroed(len, s_off); - let dst = AlignedSlice::new_zeroed(len, d_off); - src.fill(1); - (len, src, dst) - } + use super::*; #[library_benchmark] #[benches::aligned( @@ -39,7 +26,7 @@ mod mcpy { setup = setup, )] #[benches::offset( - // Both at the same offset + // Both unaligned but at the same offset args = [ Cfg { len: 16, s_off: 65, d_off: 65 }, Cfg { len: 32, s_off: 65, d_off: 65 }, @@ -76,17 +63,10 @@ mod mcpy { } mod mset { - use super::*; + use builtins_test::mem::mset::{Cfg, setup}; + use compiler_builtins::mem::memset; - struct Cfg { - len: usize, - offset: usize, - } - - fn setup(Cfg { len, offset }: Cfg) -> (usize, AlignedSlice) { - println!("bytes: {len}, offset: {offset}"); - (len, AlignedSlice::new_zeroed(len, offset)) - } + use super::*; #[library_benchmark] #[benches::aligned( @@ -125,22 +105,10 @@ mod mset { } mod mcmp { - use super::*; - - struct Cfg { - len: usize, - s_off: usize, - d_off: usize, - } + use builtins_test::mem::mcmp::{Cfg, setup}; + use compiler_builtins::mem::memcmp; - fn setup(cfg: Cfg) -> (usize, AlignedSlice, AlignedSlice) { - let Cfg { len, s_off, d_off } = cfg; - println!("bytes: {len}, src offset: {s_off}, dst offset: {d_off}"); - let b1 = AlignedSlice::new_zeroed(len, s_off); - let mut b2 = AlignedSlice::new_zeroed(len, d_off); - b2[len - 1] = 1; - (len, b1, b2) - } + use super::*; #[library_benchmark] #[benches::aligned( @@ -194,71 +162,11 @@ mod mcmp { mod mmove { use Spread::{Aligned, Large, Medium, Small}; + use builtins_test::mem::mmove::{Cfg, Spread, setup_backward, setup_forward}; + use compiler_builtins::mem::memmove; use super::*; - struct Cfg { - len: usize, - spread: Spread, - off: usize, - } - - enum Spread { - /// `src` and `dst` are close and have the same alignment (or offset). - Aligned, - /// `src` and `dst` are close. - Small, - /// `src` and `dst` are halfway offset in the buffer. - Medium, - /// `src` and `dst` only overlap by a single byte. - Large, - } - - // Note that small and large are - fn calculate_spread(len: usize, spread: Spread) -> usize { - match spread { - // Note that this test doesn't make sense for lengths less than len=128 - Aligned => { - assert!( - len > MAX_TESTED_ALIGN, - "aligned memset would have no overlap" - ); - MAX_TESTED_ALIGN - } - Small => 1, - Medium => (len / 2) + 1, // add 1 so all are misaligned - Large => len - 1, - } - } - - fn setup_forward(cfg: Cfg) -> (usize, usize, AlignedSlice) { - let Cfg { len, spread, off } = cfg; - let spread = calculate_spread(len, spread); - println!("bytes: {len}, spread: {spread}, offset: {off}, forward"); - assert!(spread < len, "memmove tests should have some overlap"); - let mut buf = AlignedSlice::new_zeroed(len + spread, off); - let mut fill: usize = 0; - buf[..len].fill_with(|| { - fill += 1; - fill as u8 - }); - (len, spread, buf) - } - - fn setup_backward(cfg: Cfg) -> (usize, usize, AlignedSlice) { - let Cfg { len, spread, off } = cfg; - let spread = calculate_spread(len, spread); - println!("bytes: {len}, spread: {spread}, offset: {off}, backward"); - assert!(spread < len, "memmove tests should have some overlap"); - let mut buf = AlignedSlice::new_zeroed(len + spread, off); - let mut fill: usize = 0; - buf[spread..].fill_with(|| { - fill += 1; - fill as u8 - }); - (len, spread, buf) - } - #[library_benchmark] #[benches::aligned( args = [ diff --git a/library/compiler-builtins/builtins-test/src/mem.rs b/library/compiler-builtins/builtins-test/src/mem.rs index 237f8322e64ee..bf26d2ee168c3 100644 --- a/library/compiler-builtins/builtins-test/src/mem.rs +++ b/library/compiler-builtins/builtins-test/src/mem.rs @@ -54,6 +54,122 @@ impl ops::DerefMut for AlignedSlice { } } +pub mod mcpy { + use super::*; + + pub struct Cfg { + pub len: usize, + pub s_off: usize, + pub d_off: usize, + } + + /// Return `(len, src, dst)` for a cfg. + pub fn setup(cfg: Cfg) -> (usize, AlignedSlice, AlignedSlice) { + let Cfg { len, s_off, d_off } = cfg; + let mut src = AlignedSlice::new_zeroed(len, s_off); + let dst = AlignedSlice::new_zeroed(len, d_off); + src.fill(1); + (len, src, dst) + } +} + +pub mod mset { + use super::*; + + pub struct Cfg { + pub len: usize, + pub offset: usize, + } + + pub fn setup(Cfg { len, offset }: Cfg) -> (usize, AlignedSlice) { + (len, AlignedSlice::new_zeroed(len, offset)) + } +} + +pub mod mcmp { + use super::*; + + pub struct Cfg { + pub len: usize, + pub s_off: usize, + pub d_off: usize, + } + + pub fn setup(cfg: Cfg) -> (usize, AlignedSlice, AlignedSlice) { + let Cfg { len, s_off, d_off } = cfg; + let b1 = AlignedSlice::new_zeroed(len, s_off); + let mut b2 = AlignedSlice::new_zeroed(len, d_off); + b2[len - 1] = 1; + (len, b1, b2) + } +} + +pub mod mmove { + use Spread::{Aligned, Large, Medium, Small}; + + use super::*; + + pub struct Cfg { + pub len: usize, + pub spread: Spread, + pub off: usize, + } + + pub enum Spread { + /// `src` and `dst` are close and have the same alignment (or offset). + Aligned, + /// `src` and `dst` are close. + Small, + /// `src` and `dst` are halfway offset in the buffer. + Medium, + /// `src` and `dst` only overlap by a single byte. + Large, + } + + // Note that small and large are + pub fn calculate_spread(len: usize, spread: Spread) -> usize { + match spread { + // Note that this test doesn't make sense for lengths less than len=128 + Aligned => { + assert!( + len > MAX_TESTED_ALIGN, + "aligned memset would have no overlap" + ); + MAX_TESTED_ALIGN + } + Small => 1, + Medium => (len / 2) + 1, // add 1 so all are misaligned + Large => len - 1, + } + } + + pub fn setup_forward(cfg: Cfg) -> (usize, usize, AlignedSlice) { + let Cfg { len, spread, off } = cfg; + let spread = calculate_spread(len, spread); + assert!(spread < len, "memmove tests should have some overlap"); + let mut buf = AlignedSlice::new_zeroed(len + spread, off); + let mut fill: usize = 0; + buf[..len].fill_with(|| { + fill += 1; + fill as u8 + }); + (len, spread, buf) + } + + pub fn setup_backward(cfg: Cfg) -> (usize, usize, AlignedSlice) { + let Cfg { len, spread, off } = cfg; + let spread = calculate_spread(len, spread); + assert!(spread < len, "memmove tests should have some overlap"); + let mut buf = AlignedSlice::new_zeroed(len + spread, off); + let mut fill: usize = 0; + buf[spread..].fill_with(|| { + fill += 1; + fill as u8 + }); + (len, spread, buf) + } +} + #[test] fn test_alignment() { let v = AlignedSlice::new_zeroed(1, 0); From 6fcc4fc5b79b5614e9c3777e25c9242a8c5bb757 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Tue, 25 Aug 2026 23:51:41 -0500 Subject: [PATCH 22/28] bench: Move `mem` from `AlignedVec` to `AlignedSlice` Remove a mostly redundant type. There are some minor differences in the `memcmp` benches because the slices are now the same length (`let s2: &[u8] = black_box(&v2[1..]);` was trimming one). --- .../builtins-test/benches/mem.rs | 91 ++++++------------- .../builtins-test/src/mem.rs | 9 +- 2 files changed, 37 insertions(+), 63 deletions(-) diff --git a/library/compiler-builtins/builtins-test/benches/mem.rs b/library/compiler-builtins/builtins-test/benches/mem.rs index 3f83926b6c5a2..875e4b8699778 100644 --- a/library/compiler-builtins/builtins-test/benches/mem.rs +++ b/library/compiler-builtins/builtins-test/benches/mem.rs @@ -1,72 +1,39 @@ #![feature(test)] extern crate test; +use builtins_test::mem::AlignedSlice; use test::{Bencher, black_box}; extern crate compiler_builtins; use compiler_builtins::mem::{memcmp, memcpy, memmove, memset}; -const WORD_SIZE: usize = core::mem::size_of::(); - -struct AlignedVec { - vec: Vec, - size: usize, -} - -impl AlignedVec { - fn new(fill: u8, size: usize) -> Self { - let mut broadcast = fill as usize; - let mut bits = 8; - while bits < WORD_SIZE * 8 { - broadcast |= broadcast << bits; - bits *= 2; - } - - let vec = vec![broadcast; (size + WORD_SIZE - 1) & !WORD_SIZE]; - AlignedVec { vec, size } - } -} - -impl core::ops::Deref for AlignedVec { - type Target = [u8]; - fn deref(&self) -> &[u8] { - unsafe { core::slice::from_raw_parts(self.vec.as_ptr() as *const u8, self.size) } - } -} - -impl core::ops::DerefMut for AlignedVec { - fn deref_mut(&mut self) -> &mut [u8] { - unsafe { core::slice::from_raw_parts_mut(self.vec.as_mut_ptr() as *mut u8, self.size) } - } -} - fn memcpy_builtin(b: &mut Bencher, n: usize, offset1: usize, offset2: usize) { - let v1 = AlignedVec::new(1, n + offset1); - let mut v2 = AlignedVec::new(0, n + offset2); + let v1 = AlignedSlice::new(1, n, offset1); + let mut v2 = AlignedSlice::new(0, n, offset2); b.bytes = n as u64; b.iter(|| { - let src: &[u8] = black_box(&v1[offset1..]); - let dst: &mut [u8] = black_box(&mut v2[offset2..]); + let src: &[u8] = black_box(&v1); + let dst: &mut [u8] = black_box(&mut v2); dst.copy_from_slice(src); }) } fn memcpy_rust(b: &mut Bencher, n: usize, offset1: usize, offset2: usize) { - let v1 = AlignedVec::new(1, n + offset1); - let mut v2 = AlignedVec::new(0, n + offset2); + let v1 = AlignedSlice::new(1, n, offset1); + let mut v2 = AlignedSlice::new(0, n, offset2); b.bytes = n as u64; b.iter(|| { - let src: &[u8] = black_box(&v1[offset1..]); - let dst: &mut [u8] = black_box(&mut v2[offset2..]); + let src: &[u8] = black_box(&v1); + let dst: &mut [u8] = black_box(&mut v2); unsafe { memcpy(dst.as_mut_ptr(), src.as_ptr(), n) } }) } fn memset_builtin(b: &mut Bencher, n: usize, offset: usize) { - let mut v1 = AlignedVec::new(0, n + offset); + let mut v1 = AlignedSlice::new(0, n, offset); b.bytes = n as u64; b.iter(|| { - let dst: &mut [u8] = black_box(&mut v1[offset..]); + let dst: &mut [u8] = black_box(&mut v1); let val: u8 = black_box(27); for b in dst { *b = val; @@ -75,18 +42,18 @@ fn memset_builtin(b: &mut Bencher, n: usize, offset: usize) { } fn memset_rust(b: &mut Bencher, n: usize, offset: usize) { - let mut v1 = AlignedVec::new(0, n + offset); + let mut v1 = AlignedSlice::new(0, n, offset); b.bytes = n as u64; b.iter(|| { - let dst: &mut [u8] = black_box(&mut v1[offset..]); + let dst: &mut [u8] = black_box(&mut v1); let val = black_box(27); unsafe { memset(dst.as_mut_ptr(), val, n) } }) } fn memcmp_builtin(b: &mut Bencher, n: usize) { - let v1 = AlignedVec::new(0, n); - let mut v2 = AlignedVec::new(0, n); + let v1 = AlignedSlice::new(0, n, 0); + let mut v2 = AlignedSlice::new(0, n, 0); v2[n - 1] = 1; b.bytes = n as u64; b.iter(|| { @@ -97,20 +64,20 @@ fn memcmp_builtin(b: &mut Bencher, n: usize) { } fn memcmp_builtin_unaligned(b: &mut Bencher, n: usize) { - let v1 = AlignedVec::new(0, n); - let mut v2 = AlignedVec::new(0, n); + let v1 = AlignedSlice::new(0, n, 0); + let mut v2 = AlignedSlice::new(0, n, 1); v2[n - 1] = 1; b.bytes = n as u64; b.iter(|| { - let s1: &[u8] = black_box(&v1[0..]); - let s2: &[u8] = black_box(&v2[1..]); + let s1: &[u8] = black_box(&v1); + let s2: &[u8] = black_box(&v2); s1.cmp(s2) }) } fn memcmp_rust(b: &mut Bencher, n: usize) { - let v1 = AlignedVec::new(0, n); - let mut v2 = AlignedVec::new(0, n); + let v1 = AlignedSlice::new(0, n, 0); + let mut v2 = AlignedSlice::new(0, n, 0); v2[n - 1] = 1; b.bytes = n as u64; b.iter(|| { @@ -121,19 +88,20 @@ fn memcmp_rust(b: &mut Bencher, n: usize) { } fn memcmp_rust_unaligned(b: &mut Bencher, n: usize) { - let v1 = AlignedVec::new(0, n); - let mut v2 = AlignedVec::new(0, n); + let v1 = AlignedSlice::new(0, n, 0); + let mut v2 = AlignedSlice::new(0, n, 1); v2[n - 1] = 1; b.bytes = n as u64; b.iter(|| { - let s1: &[u8] = black_box(&v1[0..]); - let s2: &[u8] = black_box(&v2[1..]); - unsafe { memcmp(s1.as_ptr(), s2.as_ptr(), n - 1) } + let s1: &[u8] = black_box(&v1); + let s2: &[u8] = black_box(&v2); + unsafe { memcmp(s1.as_ptr(), s2.as_ptr(), n) } }) } fn memmove_builtin(b: &mut Bencher, n: usize, offset: usize) { - let mut v = AlignedVec::new(0, n + n / 2 + offset); + // Aligned source, misaligned dest + let mut v = AlignedSlice::new(0, n + n / 2 + offset, 0); b.bytes = n as u64; b.iter(|| { let s: &mut [u8] = black_box(&mut v); @@ -142,7 +110,8 @@ fn memmove_builtin(b: &mut Bencher, n: usize, offset: usize) { } fn memmove_rust(b: &mut Bencher, n: usize, offset: usize) { - let mut v = AlignedVec::new(0, n + n / 2 + offset); + // Aligned source, misaligned dest + let mut v = AlignedSlice::new(0, n + n / 2 + offset, 0); b.bytes = n as u64; b.iter(|| { let dst: *mut u8 = black_box(&mut v[n / 2 + offset..]).as_mut_ptr(); diff --git a/library/compiler-builtins/builtins-test/src/mem.rs b/library/compiler-builtins/builtins-test/src/mem.rs index bf26d2ee168c3..45b5dc3530058 100644 --- a/library/compiler-builtins/builtins-test/src/mem.rs +++ b/library/compiler-builtins/builtins-test/src/mem.rs @@ -27,13 +27,18 @@ pub struct AlignedSlice { impl AlignedSlice { /// Allocate a slice aligned to ALIGN with at least `len` items, with `offset` from /// page alignment. - pub fn new_zeroed(len: usize, offset: usize) -> Self { + pub fn new(fill: u8, len: usize, offset: usize) -> Self { assert!(offset < PAGE_SIZE); let total_len = len + offset; let limbs = total_len.div_ceil(PAGE_SIZE); - let buf = vec![Page([0u8; PAGE_SIZE]); limbs].into_boxed_slice(); + let buf = vec![Page([fill; PAGE_SIZE]); limbs].into_boxed_slice(); AlignedSlice { buf, len, offset } } + + /// Same as [`new`] but with 0 as the value. + pub fn new_zeroed(len: usize, offset: usize) -> Self { + AlignedSlice::new(0, len, offset) + } } impl ops::Deref for AlignedSlice { From 8c6c020130aaed26816ba91cf32b3acfa8fbfb33 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Wed, 26 Aug 2026 01:01:47 -0500 Subject: [PATCH 23/28] test: Add a test and icount benchmark for `strlen` --- .../builtins-test/benches/mem_icount.rs | 43 ++++++++++++++++++- .../builtins-test/src/mem.rs | 16 +++++++ .../builtins-test/tests/mem.rs | 12 +++++- 3 files changed, 69 insertions(+), 2 deletions(-) diff --git a/library/compiler-builtins/builtins-test/benches/mem_icount.rs b/library/compiler-builtins/builtins-test/benches/mem_icount.rs index b0f0b77a8beb1..ff03269dc7142 100644 --- a/library/compiler-builtins/builtins-test/benches/mem_icount.rs +++ b/library/compiler-builtins/builtins-test/benches/mem_icount.rs @@ -357,9 +357,50 @@ mod mmove { library_benchmark_group!(name = memmove, benchmarks = [forward_move, backward_move]); } +mod slen { + use builtins_test::mem::slen::{Cfg, setup}; + use compiler_builtins::mem::strlen; + + use super::*; + + #[library_benchmark] + #[benches::aligned( + args = [ + Cfg { len: 1, offset: 0 }, + Cfg { len: 16, offset: 0 }, + Cfg { len: 32, offset: 0 }, + Cfg { len: 64, offset: 0 }, + Cfg { len: 512, offset: 0 }, + Cfg { len: 4096, offset: 0 }, + Cfg { len: MEG1, offset: 0 }, + ], + setup = setup, + )] + #[benches::offset( + args = [ + Cfg { len: 1, offset: 65 }, + Cfg { len: 16, offset: 65 }, + Cfg { len: 32, offset: 65 }, + Cfg { len: 64, offset: 65 }, + Cfg { len: 512, offset: 65 }, + Cfg { len: 4096, offset: 65 }, + Cfg { len: MEG1, offset: 65 }, + ], + setup = setup, + )] + fn bench_strlen(s: AlignedSlice) { + unsafe { + black_box(strlen(black_box(s.as_ptr().cast::()))); + } + } + + library_benchmark_group!(name = strlen, benchmarks = [bench_strlen]); +} + use mcmp::memcmp; use mcpy::memcpy; use mmove::memmove; use mset::memset; +use slen::strlen; -main!(library_benchmark_groups = [memcpy, memset, memcmp, memmove]); +main!(library_benchmark_groups = [memcpy, memset, memcmp, memmove, strlen]); diff --git a/library/compiler-builtins/builtins-test/src/mem.rs b/library/compiler-builtins/builtins-test/src/mem.rs index 45b5dc3530058..aa66890d56180 100644 --- a/library/compiler-builtins/builtins-test/src/mem.rs +++ b/library/compiler-builtins/builtins-test/src/mem.rs @@ -175,6 +175,22 @@ pub mod mmove { } } +pub mod slen { + use super::*; + + pub struct Cfg { + pub len: usize, + pub offset: usize, + } + + pub fn setup(Cfg { len, offset }: Cfg) -> AlignedSlice { + assert!(len > 0, "must have one byte for the \\0"); + let mut ret = AlignedSlice::new(b'x', len, offset); + ret[len - 1] = 0; + ret + } +} + #[test] fn test_alignment() { let v = AlignedSlice::new_zeroed(1, 0); diff --git a/library/compiler-builtins/builtins-test/tests/mem.rs b/library/compiler-builtins/builtins-test/tests/mem.rs index 5d6f7d225bd9e..a10dddbd19c1f 100644 --- a/library/compiler-builtins/builtins-test/tests/mem.rs +++ b/library/compiler-builtins/builtins-test/tests/mem.rs @@ -1,4 +1,4 @@ -use compiler_builtins::mem::{memcmp, memcpy, memmove, memset}; +use compiler_builtins::mem::{memcmp, memcpy, memmove, memset, strlen}; const WORD_SIZE: usize = core::mem::size_of::(); @@ -283,3 +283,13 @@ fn memset_backward_aligned() { assert_eq!(arr.0, reference.0); } } + +#[test] +fn test_strlen() { + unsafe { + let s = c""; + assert_eq!(strlen(s.as_ptr()), 0); + let s = c"hello, world!"; + assert_eq!(strlen(s.as_ptr()), 13); + } +} From 1e4d3fddd5897405838f5c0be2628ea5e02b94b3 Mon Sep 17 00:00:00 2001 From: MarcoIeni <11428655+MarcoIeni@users.noreply.github.com> Date: Thu, 9 Jul 2026 12:02:54 +0200 Subject: [PATCH 24/28] ci: build and test with s390x-resolute runner We'd like to this add new `s390x` runner to `compiler-builtins`. This new runner is provided by Canonical. After some iteration alongside with Canonical folks, the `large` runner offers hardware spec similar to the existing s390x provided by IBM and [delivers similar build times](https://github.com/rust-lang/compiler-builtins/actions/runs/31516313575/job/93862267593?pr=1227). Moreover, it runs on ubuntu-26.04 rather than ubuntu-24.04, and it features a Github integration more friendly to `t-infra`, since the related Github App requires less permissions to run. We don't need to remove the s390x IBM runners right now. We propose having both s390x runners running side by side for a while and circle back after a few PRs, sticking with the Canonical one afterwards if everything goes well. --- library/compiler-builtins/.github/workflows/main.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/compiler-builtins/.github/workflows/main.yaml b/library/compiler-builtins/.github/workflows/main.yaml index 4ee8bbe3e54f8..a069590d61c1d 100644 --- a/library/compiler-builtins/.github/workflows/main.yaml +++ b/library/compiler-builtins/.github/workflows/main.yaml @@ -92,6 +92,8 @@ jobs: # os: ["self-hosted", "linux", "riscv64"] - target: riscv64gc-unknown-linux-gnu os: ubuntu-26.04 + - target: s390x-unknown-linux-gnu + os: self-hosted-linux-s390x-resolute-large-rust # resolute == ubuntu-26.04 - target: s390x-unknown-linux-gnu os: ubuntu-24.04-s390x - target: thumbv6m-none-eabi From ccc0ca9bd481d42d735f354634259a73f3a4147f Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Wed, 26 Aug 2026 11:37:00 -0500 Subject: [PATCH 25/28] libm: Remove an MSRV hack that is no longer needed --- .../libm/src/math/support/hex_float.rs | 189 ++++++++---------- 1 file changed, 85 insertions(+), 104 deletions(-) diff --git a/library/compiler-builtins/libm/src/math/support/hex_float.rs b/library/compiler-builtins/libm/src/math/support/hex_float.rs index 607ba7964023b..5040c3fae7933 100644 --- a/library/compiler-builtins/libm/src/math/support/hex_float.rs +++ b/library/compiler-builtins/libm/src/math/support/hex_float.rs @@ -698,62 +698,48 @@ mod parse_tests { } } } - // HACK(msrv): 1.63 rejects unknown width float literals at an AST level, so use a macro to - // hide them from the AST. + #[test] #[cfg(f16_enabled)] - macro_rules! f16_tests { - () => { - #[test] - fn test_f16() { - let checks = [ - ("0x.1234p+16", (0x1234 as f16).to_bits()), - ("0x1.234p+12", (0x1234 as f16).to_bits()), - ("0x12.34p+8", (0x1234 as f16).to_bits()), - ("0x123.4p+4", (0x1234 as f16).to_bits()), - ("0x1234p+0", (0x1234 as f16).to_bits()), - ("0x1234.p+0", (0x1234 as f16).to_bits()), - ("0x1234.0p+0", (0x1234 as f16).to_bits()), - ("0x1.ffcp+15", f16::MAX.to_bits()), - ("0x1.0p+1", 2.0f16.to_bits()), - ("0x1.0p+0", 1.0f16.to_bits()), - ("0x1.ffp+8", 0x5ffc), - ("+0x1.ffp+8", 0x5ffc), - ("0x1p+0", 0x3c00), - ("0x1.998p-4", 0x2e66), - ("0x1.9p+6", 0x5640), - ("0x0.0p0", 0.0f16.to_bits()), - ("-0x0.0p0", (-0.0f16).to_bits()), - ("0x1.0p0", 1.0f16.to_bits()), - ("0x1.998p-4", (0.1f16).to_bits()), - ("-0x1.998p-4", (-0.1f16).to_bits()), - ("0x0.123p-12", 0x0123), - ("0x1p-24", 0x0001), - ("nan", f16::NAN.to_bits()), - ("-nan", (-f16::NAN).to_bits()), - ("inf", f16::INFINITY.to_bits()), - ("-inf", f16::NEG_INFINITY.to_bits()), - ]; - for (s, exp) in checks { - println!("parsing {s}"); - assert!(rounding_properties(s).is_ok()); - let act = hf16(s).to_bits(); - assert_eq!( - act, exp, - "parsing {s}: {act:#06x} != {exp:#06x}\nact: {act:#018b}\nexp: {exp:#018b}" - ); - } - } - - #[test] - fn test_macros_f16() { - assert_eq!(hf16!("0x1.ffp+8").to_bits(), 0x5ffc_u16); - } - }; + fn test_f16() { + let checks = [ + ("0x.1234p+16", (0x1234 as f16).to_bits()), + ("0x1.234p+12", (0x1234 as f16).to_bits()), + ("0x12.34p+8", (0x1234 as f16).to_bits()), + ("0x123.4p+4", (0x1234 as f16).to_bits()), + ("0x1234p+0", (0x1234 as f16).to_bits()), + ("0x1234.p+0", (0x1234 as f16).to_bits()), + ("0x1234.0p+0", (0x1234 as f16).to_bits()), + ("0x1.ffcp+15", f16::MAX.to_bits()), + ("0x1.0p+1", 2.0f16.to_bits()), + ("0x1.0p+0", 1.0f16.to_bits()), + ("0x1.ffp+8", 0x5ffc), + ("+0x1.ffp+8", 0x5ffc), + ("0x1p+0", 0x3c00), + ("0x1.998p-4", 0x2e66), + ("0x1.9p+6", 0x5640), + ("0x0.0p0", 0.0f16.to_bits()), + ("-0x0.0p0", (-0.0f16).to_bits()), + ("0x1.0p0", 1.0f16.to_bits()), + ("0x1.998p-4", (0.1f16).to_bits()), + ("-0x1.998p-4", (-0.1f16).to_bits()), + ("0x0.123p-12", 0x0123), + ("0x1p-24", 0x0001), + ("nan", f16::NAN.to_bits()), + ("-nan", (-f16::NAN).to_bits()), + ("inf", f16::INFINITY.to_bits()), + ("-inf", f16::NEG_INFINITY.to_bits()), + ]; + for (s, exp) in checks { + println!("parsing {s}"); + assert!(rounding_properties(s).is_ok()); + let act = hf16(s).to_bits(); + assert_eq!( + act, exp, + "parsing {s}: {act:#06x} != {exp:#06x}\nact: {act:#018b}\nexp: {exp:#018b}" + ); + } } - #[cfg(f16_enabled)] - f16_tests!(); - #[test] fn test_f32() { let checks = [ @@ -840,61 +826,56 @@ mod parse_tests { } } - // HACK(msrv): 1.63 rejects unknown width float literals at an AST level, so use a macro to - // hide them from the AST. + #[test] #[cfg(f128_enabled)] - macro_rules! f128_tests { - () => { - #[test] - fn test_f128() { - let checks = [ - ("0x.1234p+16", (0x1234 as f128).to_bits()), - ("0x1.234p+12", (0x1234 as f128).to_bits()), - ("0x12.34p+8", (0x1234 as f128).to_bits()), - ("0x123.4p+4", (0x1234 as f128).to_bits()), - ("0x1234p+0", (0x1234 as f128).to_bits()), - ("0x1234.p+0", (0x1234 as f128).to_bits()), - ("0x1234.0p+0", (0x1234 as f128).to_bits()), - ("0x1.ffffffffffffffffffffffffffffp+16383", f128::MAX.to_bits()), - ("0x1.0p+1", 2.0f128.to_bits()), - ("0x1.0p+0", 1.0f128.to_bits()), - ("0x1.ffep+8", 0x4007ffe0000000000000000000000000), - ("+0x1.ffep+8", 0x4007ffe0000000000000000000000000), - ("0x1p+0", 0x3fff0000000000000000000000000000), - ("0x1.999999999999999999999999999ap-4", 0x3ffb999999999999999999999999999a), - ("0x1.9p+6", 0x40059000000000000000000000000000), - ("0x0.0p0", 0.0f128.to_bits()), - ("-0x0.0p0", (-0.0f128).to_bits()), - ("0x1.0p0", 1.0f128.to_bits()), - ("0x1.999999999999999999999999999ap-4", (0.1f128).to_bits()), - ("-0x1.999999999999999999999999999ap-4", (-0.1f128).to_bits()), - ("0x0.abcdef0123456789abcdef012345p-16382", 0x0000abcdef0123456789abcdef012345), - ("0x1p-16494", 0x00000000000000000000000000000001), - ("nan", f128::NAN.to_bits()), - ("-nan", (-f128::NAN).to_bits()), - ("inf", f128::INFINITY.to_bits()), - ("-inf", f128::NEG_INFINITY.to_bits()), - ]; - for (s, exp) in checks { - println!("parsing {s}"); - let act = hf128(s).to_bits(); - assert_eq!( - act, exp, - "parsing {s}: {act:#034x} != {exp:#034x}\nact: {act:#0130b}\nexp: {exp:#0130b}" - ); - } - } - - #[test] - fn test_macros_f128() { - assert_eq!(hf128!("0x1.ffep+8").to_bits(), 0x4007ffe0000000000000000000000000_u128); - } + fn test_f128() { + let checks = [ + ("0x.1234p+16", (0x1234 as f128).to_bits()), + ("0x1.234p+12", (0x1234 as f128).to_bits()), + ("0x12.34p+8", (0x1234 as f128).to_bits()), + ("0x123.4p+4", (0x1234 as f128).to_bits()), + ("0x1234p+0", (0x1234 as f128).to_bits()), + ("0x1234.p+0", (0x1234 as f128).to_bits()), + ("0x1234.0p+0", (0x1234 as f128).to_bits()), + ( + "0x1.ffffffffffffffffffffffffffffp+16383", + f128::MAX.to_bits(), + ), + ("0x1.0p+1", 2.0f128.to_bits()), + ("0x1.0p+0", 1.0f128.to_bits()), + ("0x1.ffep+8", 0x4007ffe0000000000000000000000000), + ("+0x1.ffep+8", 0x4007ffe0000000000000000000000000), + ("0x1p+0", 0x3fff0000000000000000000000000000), + ( + "0x1.999999999999999999999999999ap-4", + 0x3ffb999999999999999999999999999a, + ), + ("0x1.9p+6", 0x40059000000000000000000000000000), + ("0x0.0p0", 0.0f128.to_bits()), + ("-0x0.0p0", (-0.0f128).to_bits()), + ("0x1.0p0", 1.0f128.to_bits()), + ("0x1.999999999999999999999999999ap-4", (0.1f128).to_bits()), + ("-0x1.999999999999999999999999999ap-4", (-0.1f128).to_bits()), + ( + "0x0.abcdef0123456789abcdef012345p-16382", + 0x0000abcdef0123456789abcdef012345, + ), + ("0x1p-16494", 0x00000000000000000000000000000001), + ("nan", f128::NAN.to_bits()), + ("-nan", (-f128::NAN).to_bits()), + ("inf", f128::INFINITY.to_bits()), + ("-inf", f128::NEG_INFINITY.to_bits()), + ]; + for (s, exp) in checks { + println!("parsing {s}"); + let act = hf128(s).to_bits(); + assert_eq!( + act, exp, + "parsing {s}: {act:#034x} != {exp:#034x}\nact: {act:#0130b}\nexp: {exp:#0130b}" + ); } } - #[cfg(f128_enabled)] - f128_tests!(); - #[test] fn test_macros() { #[cfg(f16_enabled)] From 61dec2208f5d0a6ea9aa22f19c2f1c14584c8daf Mon Sep 17 00:00:00 2001 From: HuzaifaAbdulRehman <143286445+HuzaifaAbdulRehman@users.noreply.github.com> Date: Mon, 31 Aug 2026 02:17:42 +0500 Subject: [PATCH 26/28] c-b: Drop the removed `abi_unadjusted` feature gate --- library/compiler-builtins/compiler-builtins/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/library/compiler-builtins/compiler-builtins/src/lib.rs b/library/compiler-builtins/compiler-builtins/src/lib.rs index 0d25495abf8aa..5dfc6733befec 100644 --- a/library/compiler-builtins/compiler-builtins/src/lib.rs +++ b/library/compiler-builtins/compiler-builtins/src/lib.rs @@ -3,7 +3,6 @@ #![no_std] // #![feature(abi_custom)] -#![feature(abi_unadjusted)] #![feature(asm_experimental_arch)] #![feature(cfg_target_has_atomic)] #![feature(compiler_builtins)] From 7b98255ea37f2557b1e79c1729b86fcdd5122ee3 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Mon, 31 Aug 2026 04:56:06 +0000 Subject: [PATCH 27/28] ci: Disable the i686-pc-windows-gnu job There doesn't seem to be a straightforward way to build and test this target anymore. Disable it for now since CI is broken. Link: https://github.com/rust-lang/compiler-builtins/issues/1306 --- library/compiler-builtins/.github/workflows/main.yaml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/library/compiler-builtins/.github/workflows/main.yaml b/library/compiler-builtins/.github/workflows/main.yaml index a069590d61c1d..51d0734a4c4df 100644 --- a/library/compiler-builtins/.github/workflows/main.yaml +++ b/library/compiler-builtins/.github/workflows/main.yaml @@ -114,9 +114,10 @@ jobs: os: windows-2025-vs2026 - target: x86_64-pc-windows-msvc os: windows-2025-vs2026 - - target: i686-pc-windows-gnu - os: windows-2025-vs2026 - channel: nightly-i686-gnu + # FIXME(rust-lang/compiler-builtins#1306): disabled due to broken environment + # - target: i686-pc-windows-gnu + # os: windows-2025-vs2026 + # channel: nightly-i686-gnu - target: x86_64-pc-windows-gnu os: windows-2025-vs2026 channel: nightly-x86_64-gnu From 12a11b5722e5e6517d09ebc43747a495e7f9fd9c Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 31 Aug 2026 17:07:38 +0200 Subject: [PATCH 28/28] Prepare for merging from rust-lang/rust This updates the rust-version file to 45f215f136e00d8a74c69afde2f71be3f16837cf. --- 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 9ff8b0c27d19c..6c07d50b9c4b3 100644 --- a/library/compiler-builtins/rust-version +++ b/library/compiler-builtins/rust-version @@ -1 +1 @@ -f7d782a3be46d6bb4b9792fe69a61db389ba1769 +45f215f136e00d8a74c69afde2f71be3f16837cf