Skip to content

Commit

Permalink
x86_64: Add portable_atomic_vmovdqa_atomic cfg
Browse files Browse the repository at this point in the history
  • Loading branch information
taiki-e committed Feb 6, 2023
1 parent c7d0428 commit 4634d09
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 28 deletions.
43 changes: 43 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,31 @@ jobs:
RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-feature=+cmpxchg16b ${{ env.RANDOMIZE_LAYOUT }}
if: (matrix.target == '' || startsWith(matrix.target, 'x86_64')) && !startsWith(matrix.os, 'macos') && startsWith(matrix.rust, 'nightly') && !(contains(matrix.target, '-musl') || contains(matrix.target, '-android'))

# +cmpxchg16b,+avx with portable_atomic_vmovdqa_atomic cfg
- run: cargo test -vv --workspace --exclude bench --all-features $TARGET $BUILD_STD $DOCTEST_XCOMPILE
env:
RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-feature=+cmpxchg16b,+avx --cfg portable_atomic_vmovdqa_atomic
RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-feature=+cmpxchg16b,+avx --cfg portable_atomic_vmovdqa_atomic
if: matrix.target == '' || startsWith(matrix.target, 'x86_64')
- run: cargo test -vv --workspace --exclude bench --all-features --release $TARGET $BUILD_STD $DOCTEST_XCOMPILE
env:
RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-feature=+cmpxchg16b,+avx --cfg portable_atomic_vmovdqa_atomic
RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-feature=+cmpxchg16b,+avx --cfg portable_atomic_vmovdqa_atomic
if: matrix.target == '' || startsWith(matrix.target, 'x86_64')
# LTO + doctests is very slow on some platforms
- run: cargo test -vv --workspace --exclude bench --all-features --release $TARGET $BUILD_STD $DOCTEST_XCOMPILE --tests
env:
CARGO_PROFILE_RELEASE_CODEGEN_UNITS: 1
CARGO_PROFILE_RELEASE_LTO: fat
RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-feature=+cmpxchg16b,+avx --cfg portable_atomic_vmovdqa_atomic ${{ env.RANDOMIZE_LAYOUT }}
RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-feature=+cmpxchg16b,+avx --cfg portable_atomic_vmovdqa_atomic ${{ env.RANDOMIZE_LAYOUT }}
if: matrix.target == '' || startsWith(matrix.target, 'x86_64')
- run: cargo careful test -vv --workspace --exclude bench --all-features $TARGET $DOCTEST_XCOMPILE
env:
RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-feature=+cmpxchg16b,+avx --cfg portable_atomic_vmovdqa_atomic
RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-feature=+cmpxchg16b,+avx --cfg portable_atomic_vmovdqa_atomic
if: (matrix.target == '' || startsWith(matrix.target, 'x86_64')) && startsWith(matrix.rust, 'nightly')

# +lse
- run: $cargo test -vv --workspace --all-features $EXCLUDE $TARGET $DOCTEST_XCOMPILE $BUILD_STD
env:
Expand Down Expand Up @@ -440,6 +465,7 @@ jobs:
- name: Install Rust
run: rustup toolchain add nightly --no-self-update --component rust-src && rustup default nightly
- uses: taiki-e/install-action@valgrind

# doctests on Valgrind are very slow
- run: cargo test -vv --workspace --all-features --tests $EXCLUDE
env:
Expand All @@ -455,6 +481,7 @@ jobs:
CARGO_PROFILE_RELEASE_LTO: fat
RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} --cfg valgrind
RUSTFLAGS: ${{ env.RUSTFLAGS }} --cfg valgrind

# +cmpxchg16b
- run: cargo test -vv --workspace --all-features --tests $EXCLUDE
env:
Expand All @@ -471,6 +498,22 @@ jobs:
RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-feature=+cmpxchg16b --cfg valgrind
RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-feature=+cmpxchg16b --cfg valgrind

# Sandy Bridge (the first Intel chip that introduced AVX) with portable_atomic_vmovdqa_atomic cfg
- run: cargo test -vv --workspace --exclude bench --all-features --tests
env:
RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-feature=+cmpxchg16b,+avx --cfg portable_atomic_vmovdqa_atomic --cfg valgrind
RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-feature=+cmpxchg16b,+avx --cfg portable_atomic_vmovdqa_atomic --cfg valgrind
- run: cargo test -vv --workspace --exclude bench --all-features --release --tests
env:
RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-feature=+cmpxchg16b,+avx --cfg portable_atomic_vmovdqa_atomic --cfg valgrind
RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-feature=+cmpxchg16b,+avx --cfg portable_atomic_vmovdqa_atomic --cfg valgrind
- run: cargo test -vv --workspace --exclude bench --all-features --release --tests
env:
CARGO_PROFILE_RELEASE_CODEGEN_UNITS: 1
CARGO_PROFILE_RELEASE_LTO: fat
RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-feature=+cmpxchg16b,+avx --cfg portable_atomic_vmovdqa_atomic --cfg valgrind
RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-feature=+cmpxchg16b,+avx --cfg portable_atomic_vmovdqa_atomic --cfg valgrind

codegen:
runs-on: ubuntu-latest
timeout-minutes: 60
Expand Down
3 changes: 2 additions & 1 deletion src/imp/atomic128/detect/x86_64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
any(
portable_atomic_no_outline_atomics,
not(target_feature = "sse"),
portable_atomic_vmovdqa_atomic,
miri,
portable_atomic_sanitize_thread
portable_atomic_sanitize_thread,
),
allow(dead_code)
)]
Expand Down
83 changes: 56 additions & 27 deletions src/imp/atomic128/x86_64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
// - x86 and amd64 instruction reference https://www.felixcloutier.com/x86
//
// Generated asm:
// - x86_64 (+cmpxchg16b) https://godbolt.org/z/vbz7bG156
// - x86_64 (+cmpxchg16b) https://godbolt.org/z/Kc5s5xaMY
// - x86_64 (+cmpxchg16b,+avx,vmovdqa_atomic) https://godbolt.org/z/4WYG9fasM

include!("macros.rs");

Expand Down Expand Up @@ -292,7 +293,10 @@ unsafe fn atomic_load(src: *mut u128, order: Ordering) -> u128 {
// https://doc.rust-lang.org/nightly/rustc/platform-support/x86_64-unknown-none.html
// Miri and Sanitizer do not support inline assembly.
#[cfg(any(
portable_atomic_no_outline_atomics,
all(
portable_atomic_no_outline_atomics,
not(all(portable_atomic_vmovdqa_atomic, target_feature = "avx"))
),
not(target_feature = "sse"),
miri,
portable_atomic_sanitize_thread
Expand All @@ -302,22 +306,33 @@ unsafe fn atomic_load(src: *mut u128, order: Ordering) -> u128 {
_atomic_load_cmpxchg16b(src, order)
}
#[cfg(not(any(
portable_atomic_no_outline_atomics,
all(
portable_atomic_no_outline_atomics,
not(all(portable_atomic_vmovdqa_atomic, target_feature = "avx"))
),
not(target_feature = "sse"),
miri,
portable_atomic_sanitize_thread
)))]
// SAFETY: the caller must uphold the safety contract for `atomic_load`.
unsafe {
ifunc!(unsafe fn(src: *mut u128, order: Ordering) -> u128 {
// Check CMPXCHG16B anyway to prevent mixing atomic and non-atomic access.
let cpuid = detect::detect();
if cpuid.has_cmpxchg16b() && cpuid.has_vmovdqa_atomic() {
_atomic_load_vmovdqa
} else {
_atomic_load_cmpxchg16b
}
})
{
#[cfg(all(portable_atomic_vmovdqa_atomic, target_feature = "avx"))]
// SAFETY: the caller must uphold the safety contract for `atomic_load`.
unsafe {
_atomic_load_vmovdqa(src, order)
}
#[cfg(not(all(portable_atomic_vmovdqa_atomic, target_feature = "avx")))]
// SAFETY: the caller must uphold the safety contract for `atomic_load`.
unsafe {
ifunc!(unsafe fn(src: *mut u128, order: Ordering) -> u128 {
// Check CMPXCHG16B anyway to prevent mixing atomic and non-atomic access.
let cpuid = detect::detect();
if cpuid.has_cmpxchg16b() && cpuid.has_vmovdqa_atomic() {
_atomic_load_vmovdqa
} else {
_atomic_load_cmpxchg16b
}
})
}
}
}

Expand All @@ -335,7 +350,10 @@ unsafe fn atomic_store(dst: *mut u128, val: u128, order: Ordering) {
// https://doc.rust-lang.org/nightly/rustc/platform-support/x86_64-unknown-none.html
// Miri and Sanitizer do not support inline assembly.
#[cfg(any(
portable_atomic_no_outline_atomics,
all(
portable_atomic_no_outline_atomics,
not(all(portable_atomic_vmovdqa_atomic, target_feature = "avx"))
),
not(target_feature = "sse"),
miri,
portable_atomic_sanitize_thread
Expand All @@ -345,22 +363,33 @@ unsafe fn atomic_store(dst: *mut u128, val: u128, order: Ordering) {
_atomic_store_cmpxchg16b(dst, val, order);
}
#[cfg(not(any(
portable_atomic_no_outline_atomics,
all(
portable_atomic_no_outline_atomics,
not(all(portable_atomic_vmovdqa_atomic, target_feature = "avx"))
),
not(target_feature = "sse"),
miri,
portable_atomic_sanitize_thread
)))]
// SAFETY: the caller must uphold the safety contract for `atomic_store`.
unsafe {
ifunc!(unsafe fn(dst: *mut u128, val: u128, order: Ordering) {
// Check CMPXCHG16B anyway to prevent mixing atomic and non-atomic access.
let cpuid = detect::detect();
if cpuid.has_cmpxchg16b() && cpuid.has_vmovdqa_atomic() {
_atomic_store_vmovdqa
} else {
_atomic_store_cmpxchg16b
}
});
{
#[cfg(all(portable_atomic_vmovdqa_atomic, target_feature = "avx"))]
// SAFETY: the caller must uphold the safety contract for `atomic_store`.
unsafe {
_atomic_store_vmovdqa(dst, val, order);
}
#[cfg(not(all(portable_atomic_vmovdqa_atomic, target_feature = "avx")))]
// SAFETY: the caller must uphold the safety contract for `atomic_store`.
unsafe {
ifunc!(unsafe fn(dst: *mut u128, val: u128, order: Ordering) {
// Check CMPXCHG16B anyway to prevent mixing atomic and non-atomic access.
let cpuid = detect::detect();
if cpuid.has_cmpxchg16b() && cpuid.has_vmovdqa_atomic() {
_atomic_store_vmovdqa
} else {
_atomic_store_cmpxchg16b
}
});
}
}
}

Expand Down
7 changes: 7 additions & 0 deletions tools/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ known_cfgs=(
portable_atomic_s_mode
portable_atomic_disable_fiq
portable_atomic_no_outline_atomics
portable_atomic_vmovdqa_atomic
)

x() {
Expand Down Expand Up @@ -336,6 +337,12 @@ build() {
x_cargo "${args[@]}" "$@"
;;
esac
# TODO: "LLVM ERROR: Do not know how to split the result of this operator!" on 1.66-stable and 1.67-beta
if [[ -n "${nightly}" ]] || [[ "${target}" != "x86_64-unknown-none" ]]; then
# +cmpxchg16b,+avx with portable_atomic_vmovdqa_atomic cfg
RUSTFLAGS="${target_rustflags} -C target-feature=+cmpxchg16b,+avx --cfg portable_atomic_vmovdqa_atomic" \
x_cargo "${args[@]}" --target-dir target/vmovdqa_atomic "$@"
fi
;;
aarch64* | arm64*)
# macOS is skipped because it is +lse,+lse2 by default
Expand Down

0 comments on commit 4634d09

Please sign in to comment.