84 lines
3 KiB
Rust
84 lines
3 KiB
Rust
//! 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
|
|
}
|
|
}
|