tests/codegen-llvm/some-non-zero-from-atomic-optimization.rs: New test
This commit is contained in:
parent
83e49b75e7
commit
55833a9a6d
1 changed files with 84 additions and 0 deletions
84
tests/codegen-llvm/some-non-zero-from-atomic-optimization.rs
Normal file
84
tests/codegen-llvm/some-non-zero-from-atomic-optimization.rs
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
//! Regression test for <https://github.com/rust-lang/rust/issues/60044>.
|
||||
|
||||
// We want to check that `unreachable!()` is optimized away.
|
||||
//@ compile-flags: -O
|
||||
|
||||
// Don't de-duplicate `some_non_zero_from_atomic_get2()` since we want its LLVM IR.
|
||||
//@ compile-flags: -Zmerge-functions=disabled
|
||||
|
||||
// So we don't have to worry about usize.
|
||||
//@ only-64bit
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
use std::num::NonZeroUsize;
|
||||
use std::sync::atomic::AtomicUsize;
|
||||
use std::sync::atomic::Ordering::Relaxed;
|
||||
|
||||
pub static X: AtomicUsize = AtomicUsize::new(1);
|
||||
|
||||
/// We don't need to check the LLVM IR of this function, but we expect its LLVM
|
||||
/// IR to be identical to `some_non_zero_from_atomic_get2()`.
|
||||
#[no_mangle]
|
||||
pub unsafe fn some_non_zero_from_atomic_get() -> Option<NonZeroUsize> {
|
||||
let x = X.load(Relaxed);
|
||||
Some(NonZeroUsize::new_unchecked(x))
|
||||
}
|
||||
|
||||
/// We want to test that the `unreachable!()` branch is optimized out.
|
||||
///
|
||||
/// When that does not happen, the LLVM IR will look like this:
|
||||
///
|
||||
/// ```sh
|
||||
/// rustc +nightly-2024-02-08 --emit=llvm-ir -O -Zmerge-functions=disabled \
|
||||
/// tests/codegen-llvm/some-non-zero-from-atomic-optimization.rs && \
|
||||
/// grep -B 1 -A 13 '@some_non_zero_from_atomic_get2()' some-non-zero-from-atomic-optimization.ll
|
||||
/// ```
|
||||
/// ```llvm
|
||||
/// ; Function Attrs: nonlazybind uwtable
|
||||
/// define noundef i64 @some_non_zero_from_atomic_get2() unnamed_addr #1 {
|
||||
/// start:
|
||||
/// %0 = load atomic i64, ptr @_ZN38some_non_zero_from_atomic_optimization1X17h monotonic, align 8
|
||||
/// %1 = icmp eq i64 %0, 0
|
||||
/// br i1 %1, label %bb2, label %bb3
|
||||
///
|
||||
/// bb2: ; preds = %start
|
||||
/// ; call core::panicking::panic
|
||||
/// tail call void @_ZN4core9panicking5panic17h0cc48E(..., ..., ... ) #3
|
||||
/// unreachable
|
||||
///
|
||||
/// bb3: ; preds = %start
|
||||
/// ret i64 %0
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// When it _is_ optimized out, the LLVM IR will look like this:
|
||||
///
|
||||
/// ```sh
|
||||
/// rustc +nightly-2024-02-09 --emit=llvm-ir -O -Zmerge-functions=disabled \
|
||||
/// tests/codegen-llvm/some-non-zero-from-atomic-optimization.rs && \
|
||||
/// grep -B 1 -A 6 '@some_non_zero_from_atomic_get2()' some-non-zero-from-atomic-optimization.ll
|
||||
/// ```
|
||||
/// ```llvm
|
||||
/// ; Function Attrs: mustprogress nofree nounwind nonlazybind willreturn memory(...) uwtable
|
||||
/// define noundef i64 @some_non_zero_from_atomic_get2() unnamed_addr #0 {
|
||||
/// bb3:
|
||||
/// %0 = load atomic i64, ptr @_ZN38some_non_zero_from_atomic_optimization1X17h monotonic, align 8
|
||||
/// %1 = icmp ne i64 %0, 0
|
||||
/// tail call void @llvm.assume(i1 %1)
|
||||
/// ret i64 %0
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// The way we check that the LLVM IR is correct is by making sure that neither
|
||||
/// `panic` nor `unreachable` is part of the LLVM IR:
|
||||
// CHECK-LABEL: define {{.*}} i64 @some_non_zero_from_atomic_get2() {{.*}} {
|
||||
// CHECK-NOT: panic
|
||||
// CHECK-NOT: unreachable
|
||||
#[no_mangle]
|
||||
pub unsafe fn some_non_zero_from_atomic_get2() -> usize {
|
||||
match some_non_zero_from_atomic_get() {
|
||||
Some(x) => x.get(),
|
||||
None => unreachable!(), // shall be optimized out
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue