Skip to content

Commit 5497a36

Browse files
committed
Auto merge of #149658 - Enselic:non-zero-opt, r=Mark-Simulacrum
tests/codegen-llvm/some-non-zero-from-atomic-optimization.rs: New test Closes #60044 which has one 👍 and one ❤️ vote and just **E-needs-test**.
2 parents 8a24a20 + 55833a9 commit 5497a36

File tree

1 file changed

+84
-0
lines changed

1 file changed

+84
-0
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
//! Regression test for <https://github.com/rust-lang/rust/issues/60044>.
2+
3+
// We want to check that `unreachable!()` is optimized away.
4+
//@ compile-flags: -O
5+
6+
// Don't de-duplicate `some_non_zero_from_atomic_get2()` since we want its LLVM IR.
7+
//@ compile-flags: -Zmerge-functions=disabled
8+
9+
// So we don't have to worry about usize.
10+
//@ only-64bit
11+
12+
#![crate_type = "lib"]
13+
14+
use std::num::NonZeroUsize;
15+
use std::sync::atomic::AtomicUsize;
16+
use std::sync::atomic::Ordering::Relaxed;
17+
18+
pub static X: AtomicUsize = AtomicUsize::new(1);
19+
20+
/// We don't need to check the LLVM IR of this function, but we expect its LLVM
21+
/// IR to be identical to `some_non_zero_from_atomic_get2()`.
22+
#[no_mangle]
23+
pub unsafe fn some_non_zero_from_atomic_get() -> Option<NonZeroUsize> {
24+
let x = X.load(Relaxed);
25+
Some(NonZeroUsize::new_unchecked(x))
26+
}
27+
28+
/// We want to test that the `unreachable!()` branch is optimized out.
29+
///
30+
/// When that does not happen, the LLVM IR will look like this:
31+
///
32+
/// ```sh
33+
/// rustc +nightly-2024-02-08 --emit=llvm-ir -O -Zmerge-functions=disabled \
34+
/// tests/codegen-llvm/some-non-zero-from-atomic-optimization.rs && \
35+
/// grep -B 1 -A 13 '@some_non_zero_from_atomic_get2()' some-non-zero-from-atomic-optimization.ll
36+
/// ```
37+
/// ```llvm
38+
/// ; Function Attrs: nonlazybind uwtable
39+
/// define noundef i64 @some_non_zero_from_atomic_get2() unnamed_addr #1 {
40+
/// start:
41+
/// %0 = load atomic i64, ptr @_ZN38some_non_zero_from_atomic_optimization1X17h monotonic, align 8
42+
/// %1 = icmp eq i64 %0, 0
43+
/// br i1 %1, label %bb2, label %bb3
44+
///
45+
/// bb2: ; preds = %start
46+
/// ; call core::panicking::panic
47+
/// tail call void @_ZN4core9panicking5panic17h0cc48E(..., ..., ... ) #3
48+
/// unreachable
49+
///
50+
/// bb3: ; preds = %start
51+
/// ret i64 %0
52+
/// }
53+
/// ```
54+
///
55+
/// When it _is_ optimized out, the LLVM IR will look like this:
56+
///
57+
/// ```sh
58+
/// rustc +nightly-2024-02-09 --emit=llvm-ir -O -Zmerge-functions=disabled \
59+
/// tests/codegen-llvm/some-non-zero-from-atomic-optimization.rs && \
60+
/// grep -B 1 -A 6 '@some_non_zero_from_atomic_get2()' some-non-zero-from-atomic-optimization.ll
61+
/// ```
62+
/// ```llvm
63+
/// ; Function Attrs: mustprogress nofree nounwind nonlazybind willreturn memory(...) uwtable
64+
/// define noundef i64 @some_non_zero_from_atomic_get2() unnamed_addr #0 {
65+
/// bb3:
66+
/// %0 = load atomic i64, ptr @_ZN38some_non_zero_from_atomic_optimization1X17h monotonic, align 8
67+
/// %1 = icmp ne i64 %0, 0
68+
/// tail call void @llvm.assume(i1 %1)
69+
/// ret i64 %0
70+
/// }
71+
/// ```
72+
///
73+
/// The way we check that the LLVM IR is correct is by making sure that neither
74+
/// `panic` nor `unreachable` is part of the LLVM IR:
75+
// CHECK-LABEL: define {{.*}} i64 @some_non_zero_from_atomic_get2() {{.*}} {
76+
// CHECK-NOT: panic
77+
// CHECK-NOT: unreachable
78+
#[no_mangle]
79+
pub unsafe fn some_non_zero_from_atomic_get2() -> usize {
80+
match some_non_zero_from_atomic_get() {
81+
Some(x) => x.get(),
82+
None => unreachable!(), // shall be optimized out
83+
}
84+
}

0 commit comments

Comments
 (0)