diff options
Diffstat (limited to 'tests/codegen')
| -rw-r--r-- | tests/codegen/enum/enum-two-variants-match.rs | 51 | ||||
| -rw-r--r-- | tests/codegen/intrinsics/cold_path2.rs | 3 | ||||
| -rw-r--r-- | tests/codegen/intrinsics/transmute.rs | 25 | ||||
| -rw-r--r-- | tests/codegen/issues/issue-101082.rs | 1 | ||||
| -rw-r--r-- | tests/codegen/issues/issue-122600-ptr-discriminant-update.rs | 29 | ||||
| -rw-r--r-- | tests/codegen/target-feature-inline-closure.rs | 8 | ||||
| -rw-r--r-- | tests/codegen/try_question_mark_nop.rs | 8 |
7 files changed, 111 insertions, 14 deletions
diff --git a/tests/codegen/enum/enum-two-variants-match.rs b/tests/codegen/enum/enum-two-variants-match.rs new file mode 100644 index 00000000000..e5978bfc761 --- /dev/null +++ b/tests/codegen/enum/enum-two-variants-match.rs @@ -0,0 +1,51 @@ +//@ compile-flags: -Copt-level=3 -C no-prepopulate-passes +//@ min-llvm-version: 19 (for trunc nuw) +//@ only-x86_64 (because these discriminants are isize) + +#![crate_type = "lib"] + +// CHECK-LABEL: @option_match +#[no_mangle] +pub fn option_match(x: Option<i32>) -> u16 { + // CHECK: %x = alloca [8 x i8] + // CHECK: store i32 %0, ptr %x + // CHECK: %[[TAG:.+]] = load i32, ptr %x + // CHECK-SAME: !range ![[ZERO_ONE_32:[0-9]+]] + // CHECK: %[[DISCR:.+]] = zext i32 %[[TAG]] to i64 + // CHECK: %[[COND:.+]] = trunc nuw i64 %[[DISCR]] to i1 + // CHECK: br i1 %[[COND]], label %[[TRUE:[a-z0-9]+]], label %[[FALSE:[a-z0-9]+]] + + // CHECK: [[TRUE]]: + // CHECK: store i16 13 + + // CHECK: [[FALSE]]: + // CHECK: store i16 42 + match x { + Some(_) => 13, + None => 42, + } +} + +// CHECK-LABEL: @result_match +#[no_mangle] +pub fn result_match(x: Result<u64, i64>) -> u16 { + // CHECK: %x = alloca [16 x i8] + // CHECK: store i64 %0, ptr %x + // CHECK: %[[DISCR:.+]] = load i64, ptr %x + // CHECK-SAME: !range ![[ZERO_ONE_64:[0-9]+]] + // CHECK: %[[COND:.+]] = trunc nuw i64 %[[DISCR]] to i1 + // CHECK: br i1 %[[COND]], label %[[TRUE:[a-z0-9]+]], label %[[FALSE:[a-z0-9]+]] + + // CHECK: [[TRUE]]: + // CHECK: store i16 13 + + // CHECK: [[FALSE]]: + // CHECK: store i16 42 + match x { + Err(_) => 13, + Ok(_) => 42, + } +} + +// CHECK: ![[ZERO_ONE_32]] = !{i32 0, i32 2} +// CHECK: ![[ZERO_ONE_64]] = !{i64 0, i64 2} diff --git a/tests/codegen/intrinsics/cold_path2.rs b/tests/codegen/intrinsics/cold_path2.rs index 1e7e0478f4f..54ee473e620 100644 --- a/tests/codegen/intrinsics/cold_path2.rs +++ b/tests/codegen/intrinsics/cold_path2.rs @@ -26,7 +26,8 @@ pub fn test(x: Option<bool>) { } // CHECK-LABEL: @test( - // CHECK: br i1 %1, label %bb2, label %bb1, !prof ![[NUM:[0-9]+]] + // CHECK: %[[IS_NONE:.+]] = icmp eq i8 %0, 2 + // CHECK: br i1 %[[IS_NONE]], label %bb2, label %bb1, !prof ![[NUM:[0-9]+]] // CHECK: bb1: // CHECK: path_a // CHECK: bb2: diff --git a/tests/codegen/intrinsics/transmute.rs b/tests/codegen/intrinsics/transmute.rs index ff297b27065..4849b88c09c 100644 --- a/tests/codegen/intrinsics/transmute.rs +++ b/tests/codegen/intrinsics/transmute.rs @@ -10,6 +10,7 @@ use std::intrinsics::mir::*; use std::intrinsics::{transmute, transmute_unchecked}; use std::mem::MaybeUninit; +use std::num::NonZero; // FIXME(LLVM18REMOVED): `trunc nuw` doesn't exist in LLVM 18, so once we no // longer support it the optional flag checks can be changed to required. @@ -470,3 +471,27 @@ pub unsafe fn check_from_overalign(x: HighAlignScalar) -> u64 { // CHECK: ret i64 %[[VAL]] transmute(x) } + +#[repr(transparent)] +struct Level1(std::num::NonZero<u32>); +#[repr(transparent)] +struct Level2(Level1); +#[repr(transparent)] +struct Level3(Level2); + +// CHECK-LABEL: @repeatedly_transparent_transmute +// CHECK-SAME: (i32{{.+}}%[[ARG:[^)]+]]) +#[no_mangle] +#[custom_mir(dialect = "runtime", phase = "optimized")] +pub unsafe fn repeatedly_transparent_transmute(x: NonZero<u32>) -> Level3 { + // CHECK: start + // CHECK-NEXT: ret i32 %[[ARG]] + mir! { + { + let A = CastTransmute::<NonZero<u32>, Level1>(x); + let B = CastTransmute::<Level1, Level2>(A); + RET = CastTransmute::<Level2, Level3>(B); + Return() + } + } +} diff --git a/tests/codegen/issues/issue-101082.rs b/tests/codegen/issues/issue-101082.rs index 048b69d207b..7fb850ca253 100644 --- a/tests/codegen/issues/issue-101082.rs +++ b/tests/codegen/issues/issue-101082.rs @@ -1,5 +1,6 @@ //@ compile-flags: -Copt-level=3 //@ revisions: host x86-64-v3 +//@ min-llvm-version: 20 // This particular CPU regressed in #131563 //@[x86-64-v3] only-x86_64 diff --git a/tests/codegen/issues/issue-122600-ptr-discriminant-update.rs b/tests/codegen/issues/issue-122600-ptr-discriminant-update.rs index fdb8f06df80..fbea4ee8979 100644 --- a/tests/codegen/issues/issue-122600-ptr-discriminant-update.rs +++ b/tests/codegen/issues/issue-122600-ptr-discriminant-update.rs @@ -3,6 +3,11 @@ #![crate_type = "lib"] +// The bug here was that it was loading and storing the whole value. +// It's ok for it to load the discriminant, +// to preserve the UB from `unreachable_unchecked`, +// but it better only store the constant discriminant of `B`. + pub enum State { A([u8; 753]), B([u8; 753]), @@ -11,9 +16,27 @@ pub enum State { // CHECK-LABEL: @update #[no_mangle] pub unsafe fn update(s: *mut State) { - // CHECK-NEXT: start: - // CHECK-NEXT: store i8 - // CHECK-NEXT: ret + // CHECK-NOT: alloca + + // CHECK-NOT: load + // CHECK-NOT: store + // CHECK-NOT: memcpy + // CHECK-NOT: 75{{3|4}} + + // CHECK: %[[TAG:.+]] = load i8, ptr %s, align 1 + // CHECK-NEXT: trunc nuw i8 %[[TAG]] to i1 + + // CHECK-NOT: load + // CHECK-NOT: store + // CHECK-NOT: memcpy + // CHECK-NOT: 75{{3|4}} + + // CHECK: store i8 1, ptr %s, align 1 + + // CHECK-NOT: load + // CHECK-NOT: store + // CHECK-NOT: memcpy + // CHECK-NOT: 75{{3|4}} let State::A(v) = s.read() else { std::hint::unreachable_unchecked() }; s.write(State::B(v)); } diff --git a/tests/codegen/target-feature-inline-closure.rs b/tests/codegen/target-feature-inline-closure.rs index 73bdbc0e1a8..5d54444f994 100644 --- a/tests/codegen/target-feature-inline-closure.rs +++ b/tests/codegen/target-feature-inline-closure.rs @@ -12,7 +12,7 @@ use std::arch::x86_64::*; #[cfg(target_arch = "x86_64")] #[target_feature(enable = "avx")] fn with_avx(x: __m256) -> __m256 { - // CHECK: fadd + // CHECK: fadd <8 x float> let add = { #[inline(always)] |x, y| unsafe { _mm256_add_ps(x, y) } @@ -24,14 +24,10 @@ fn with_avx(x: __m256) -> __m256 { #[no_mangle] #[cfg(target_arch = "x86_64")] unsafe fn without_avx(x: __m256) -> __m256 { - // CHECK-NOT: fadd + // CHECK-NOT: fadd <8 x float> let add = { #[inline(always)] |x, y| unsafe { _mm256_add_ps(x, y) } }; add(x, x) } - -// Don't allow the above CHECK-NOT to accidentally match a commit hash in the -// compiler version. -// CHECK-LABEL: rustc version diff --git a/tests/codegen/try_question_mark_nop.rs b/tests/codegen/try_question_mark_nop.rs index 751d7ca9311..ca15e510173 100644 --- a/tests/codegen/try_question_mark_nop.rs +++ b/tests/codegen/try_question_mark_nop.rs @@ -16,8 +16,8 @@ use std::ptr::NonNull; #[no_mangle] pub fn option_nop_match_32(x: Option<u32>) -> Option<u32> { // CHECK: start: - // TWENTY-NEXT: %trunc = trunc nuw i32 %0 to i1 - // TWENTY-NEXT: %.2 = select i1 %trunc, i32 %1, i32 undef + // TWENTY-NEXT: %[[IS_SOME:.+]] = trunc nuw i32 %0 to i1 + // TWENTY-NEXT: %.2 = select i1 %[[IS_SOME]], i32 %1, i32 undef // CHECK-NEXT: [[REG1:%.*]] = insertvalue { i32, i32 } poison, i32 %0, 0 // NINETEEN-NEXT: [[REG2:%.*]] = insertvalue { i32, i32 } [[REG1]], i32 %1, 1 // TWENTY-NEXT: [[REG2:%.*]] = insertvalue { i32, i32 } [[REG1]], i32 %.2, 1 @@ -32,8 +32,8 @@ pub fn option_nop_match_32(x: Option<u32>) -> Option<u32> { #[no_mangle] pub fn option_nop_traits_32(x: Option<u32>) -> Option<u32> { // CHECK: start: - // TWENTY-NEXT: %trunc = trunc nuw i32 %0 to i1 - // TWENTY-NEXT: %.1 = select i1 %trunc, i32 %1, i32 undef + // TWENTY-NEXT: %[[IS_SOME:.+]] = trunc nuw i32 %0 to i1 + // TWENTY-NEXT: %.1 = select i1 %[[IS_SOME]], i32 %1, i32 undef // CHECK-NEXT: insertvalue { i32, i32 } // CHECK-NEXT: insertvalue { i32, i32 } // CHECK-NEXT: ret { i32, i32 } |
