//! Regression test for . // 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 { 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 } }