diff options
| author | The Miri Cronjob Bot <miri@cron.bot> | 2024-03-14 05:01:33 +0000 |
|---|---|---|
| committer | The Miri Cronjob Bot <miri@cron.bot> | 2024-03-14 05:01:33 +0000 |
| commit | 06ca3abc5ab06894fd2e15f78140eacccca3a5e9 (patch) | |
| tree | ca240256a0323f4bbf16f86e7de5c1c78e47c98a /tests/codegen | |
| parent | f5bb34f4605bc83c02c2c0a7a128d706d6031f11 (diff) | |
| parent | ac1b8575c017b6cc99cf389ceffe853d7b53a694 (diff) | |
| download | rust-06ca3abc5ab06894fd2e15f78140eacccca3a5e9.tar.gz rust-06ca3abc5ab06894fd2e15f78140eacccca3a5e9.zip | |
Merge from rustc
Diffstat (limited to 'tests/codegen')
| -rw-r--r-- | tests/codegen/common_prim_int_ptr.rs | 51 | ||||
| -rw-r--r-- | tests/codegen/intrinsics/transmute.rs | 4 | ||||
| -rw-r--r-- | tests/codegen/precondition-checks.rs | 27 | ||||
| -rw-r--r-- | tests/codegen/skip-mono-inside-if-false.rs | 41 | ||||
| -rw-r--r-- | tests/codegen/transmute-scalar.rs | 2 | ||||
| -rw-r--r-- | tests/codegen/try_question_mark_nop.rs | 104 |
6 files changed, 214 insertions, 15 deletions
diff --git a/tests/codegen/common_prim_int_ptr.rs b/tests/codegen/common_prim_int_ptr.rs new file mode 100644 index 00000000000..87fa89abb86 --- /dev/null +++ b/tests/codegen/common_prim_int_ptr.rs @@ -0,0 +1,51 @@ +//@ compile-flags: -O + +#![crate_type = "lib"] +#![feature(core_intrinsics)] + +// Tests that codegen works properly when enums like `Result<usize, Box<()>>` +// are represented as `{ u64, ptr }`, i.e., for `Ok(123)`, `123` is stored +// as a pointer. + +// CHECK-LABEL: @insert_int +#[no_mangle] +pub fn insert_int(x: usize) -> Result<usize, Box<()>> { + // CHECK: start: + // CHECK-NEXT: inttoptr i{{[0-9]+}} %x to ptr + // CHECK-NEXT: insertvalue + // CHECK-NEXT: ret { i{{[0-9]+}}, ptr } + Ok(x) +} + +// CHECK-LABEL: @insert_box +#[no_mangle] +pub fn insert_box(x: Box<()>) -> Result<usize, Box<()>> { + // CHECK: start: + // CHECK-NEXT: insertvalue { i{{[0-9]+}}, ptr } + // CHECK-NEXT: ret + Err(x) +} + +// CHECK-LABEL: @extract_int +// CHECK-NOT: nonnull +// CHECK-SAME: (i{{[0-9]+}} {{[^,]+}} [[DISCRIMINANT:%[0-9]+]], ptr {{[^,]+}} [[PAYLOAD:%[0-9]+]]) +#[no_mangle] +pub unsafe fn extract_int(x: Result<usize, Box<()>>) -> usize { + // CHECK: [[TEMP:%.+]] = ptrtoint ptr [[PAYLOAD]] to [[USIZE:i[0-9]+]] + // CHECK: ret [[USIZE]] [[TEMP]] + match x { + Ok(v) => v, + Err(_) => std::intrinsics::unreachable(), + } +} + +// CHECK-LABEL: @extract_box +// CHECK-SAME: (i{{[0-9]+}} {{[^,]+}} [[DISCRIMINANT:%[0-9]+]], ptr {{[^,]+}} [[PAYLOAD:%[0-9]+]]) +#[no_mangle] +pub unsafe fn extract_box(x: Result<usize, Box<i32>>) -> Box<i32> { + // CHECK: ret ptr [[PAYLOAD]] + match x { + Ok(_) => std::intrinsics::unreachable(), + Err(e) => e, + } +} diff --git a/tests/codegen/intrinsics/transmute.rs b/tests/codegen/intrinsics/transmute.rs index 5a503e86010..f858562b5f1 100644 --- a/tests/codegen/intrinsics/transmute.rs +++ b/tests/codegen/intrinsics/transmute.rs @@ -296,7 +296,7 @@ pub unsafe fn check_pair_with_bool(x: (u8, bool)) -> (bool, i8) { pub unsafe fn check_float_to_pointer(x: f64) -> *const () { // CHECK-NOT: alloca // CHECK: %0 = bitcast double %x to i64 - // CHECK: %_0 = inttoptr i64 %0 to ptr + // CHECK: %_0 = getelementptr i8, ptr null, i64 %0 // CHECK: ret ptr %_0 transmute(x) } @@ -371,7 +371,7 @@ pub unsafe fn check_issue_110005(x: (usize, bool)) -> Option<Box<[u8]>> { // CHECK-LABEL: @check_pair_to_dst_ref( #[no_mangle] pub unsafe fn check_pair_to_dst_ref<'a>(x: (usize, usize)) -> &'a [u8] { - // CHECK: %_0.0 = inttoptr i64 %x.0 to ptr + // CHECK: %_0.0 = getelementptr i8, ptr null, i64 %x.0 // CHECK: %0 = insertvalue { ptr, i64 } poison, ptr %_0.0, 0 // CHECK: %1 = insertvalue { ptr, i64 } %0, i64 %x.1, 1 // CHECK: ret { ptr, i64 } %1 diff --git a/tests/codegen/precondition-checks.rs b/tests/codegen/precondition-checks.rs new file mode 100644 index 00000000000..19149445003 --- /dev/null +++ b/tests/codegen/precondition-checks.rs @@ -0,0 +1,27 @@ +//@ compile-flags: -Cno-prepopulate-passes -Copt-level=0 -Cdebug-assertions=no + +// This test ensures that in a debug build which turns off debug assertions, we do not monomorphize +// any of the standard library's unsafe precondition checks. +// The naive codegen of those checks contains the actual check underneath an `if false`, which +// could be optimized out if optimizations are enabled. But if we rely on optimizations to remove +// panic branches, then we can't link compiler_builtins without optimizing it, which means that +// -Zbuild-std doesn't work with -Copt-level=0. +// +// In other words, this tests for a mandatory optimization. + +#![crate_type = "lib"] + +use std::ptr::NonNull; + +// CHECK-LABEL: ; core::ptr::non_null::NonNull<T>::new_unchecked +// CHECK-NOT: call +// CHECK: } + +// CHECK-LABEL: @nonnull_new +#[no_mangle] +pub unsafe fn nonnull_new(ptr: *mut u8) -> NonNull<u8> { + // CHECK: ; call core::ptr::non_null::NonNull<T>::new_unchecked + unsafe { + NonNull::new_unchecked(ptr) + } +} diff --git a/tests/codegen/skip-mono-inside-if-false.rs b/tests/codegen/skip-mono-inside-if-false.rs new file mode 100644 index 00000000000..8b95de99dd3 --- /dev/null +++ b/tests/codegen/skip-mono-inside-if-false.rs @@ -0,0 +1,41 @@ +//@ compile-flags: -Cno-prepopulate-passes -Copt-level=0 + +#![crate_type = "lib"] + +#[no_mangle] +pub fn demo_for_i32() { + generic_impl::<i32>(); +} + +// Two important things here: +// - We replace the "then" block with `unreachable` to avoid linking problems +// - We neither declare nor define the `big_impl` that said block "calls". + +// CHECK-LABEL: ; skip_mono_inside_if_false::generic_impl +// CHECK: start: +// CHECK-NEXT: br label %[[ELSE_BRANCH:bb[0-9]+]] +// CHECK: [[ELSE_BRANCH]]: +// CHECK-NEXT: call skip_mono_inside_if_false::small_impl +// CHECK: bb{{[0-9]+}}: +// CHECK-NEXT: ret void +// CHECK: bb{{[0-9+]}}: +// CHECK-NEXT: unreachable + +fn generic_impl<T>() { + trait MagicTrait { + const IS_BIG: bool; + } + impl<T> MagicTrait for T { + const IS_BIG: bool = std::mem::size_of::<T>() > 10; + } + if T::IS_BIG { + big_impl::<T>(); + } else { + small_impl::<T>(); + } +} + +#[inline(never)] +fn small_impl<T>() {} +#[inline(never)] +fn big_impl<T>() {} diff --git a/tests/codegen/transmute-scalar.rs b/tests/codegen/transmute-scalar.rs index 7a5eb4dfcd5..caaa70962d5 100644 --- a/tests/codegen/transmute-scalar.rs +++ b/tests/codegen/transmute-scalar.rs @@ -49,7 +49,7 @@ pub fn ptr_to_int(p: *mut u16) -> usize { } // CHECK: define{{.*}}ptr @int_to_ptr([[USIZE]] %i) -// CHECK: %_0 = inttoptr [[USIZE]] %i to ptr +// CHECK: %_0 = getelementptr i8, ptr null, [[USIZE]] %i // CHECK-NEXT: ret ptr %_0 #[no_mangle] pub fn int_to_ptr(i: usize) -> *mut u16 { diff --git a/tests/codegen/try_question_mark_nop.rs b/tests/codegen/try_question_mark_nop.rs index 58cd6ff233a..f6cdf955209 100644 --- a/tests/codegen/try_question_mark_nop.rs +++ b/tests/codegen/try_question_mark_nop.rs @@ -4,17 +4,41 @@ #![crate_type = "lib"] #![feature(try_blocks)] -// These are now NOPs in LLVM 15, presumably thanks to nikic's change mentioned in -// <https://github.com/rust-lang/rust/issues/85133#issuecomment-1072168354>. -// Unfortunately, as of 2022-08-17 they're not yet nops for `u64`s nor `Option`. - use std::ops::ControlFlow::{self, Continue, Break}; +use std::ptr::NonNull; + +// CHECK-LABEL: @option_nop_match_32 +#[no_mangle] +pub fn option_nop_match_32(x: Option<u32>) -> Option<u32> { + // CHECK: start: + // CHECK-NEXT: insertvalue { i32, i32 } + // CHECK-NEXT: insertvalue { i32, i32 } + // CHECK-NEXT: ret { i32, i32 } + match x { + Some(x) => Some(x), + None => None, + } +} + +// CHECK-LABEL: @option_nop_traits_32 +#[no_mangle] +pub fn option_nop_traits_32(x: Option<u32>) -> Option<u32> { + // CHECK: start: + // CHECK-NEXT: insertvalue { i32, i32 } + // CHECK-NEXT: insertvalue { i32, i32 } + // CHECK-NEXT: ret { i32, i32 } + try { + x? + } +} // CHECK-LABEL: @result_nop_match_32 #[no_mangle] pub fn result_nop_match_32(x: Result<i32, u32>) -> Result<i32, u32> { - // CHECK: start - // CHECK-NEXT: ret i64 %0 + // CHECK: start: + // CHECK-NEXT: insertvalue { i32, i32 } + // CHECK-NEXT: insertvalue { i32, i32 } + // CHECK-NEXT: ret { i32, i32 } match x { Ok(x) => Ok(x), Err(x) => Err(x), @@ -24,8 +48,60 @@ pub fn result_nop_match_32(x: Result<i32, u32>) -> Result<i32, u32> { // CHECK-LABEL: @result_nop_traits_32 #[no_mangle] pub fn result_nop_traits_32(x: Result<i32, u32>) -> Result<i32, u32> { - // CHECK: start - // CHECK-NEXT: ret i64 %0 + // CHECK: start: + // CHECK-NEXT: insertvalue { i32, i32 } + // CHECK-NEXT: insertvalue { i32, i32 } + // CHECK-NEXT: ret { i32, i32 } + try { + x? + } +} + +// CHECK-LABEL: @result_nop_match_64 +#[no_mangle] +pub fn result_nop_match_64(x: Result<i64, u64>) -> Result<i64, u64> { + // CHECK: start: + // CHECK-NEXT: insertvalue { i64, i64 } + // CHECK-NEXT: insertvalue { i64, i64 } + // CHECK-NEXT: ret { i64, i64 } + match x { + Ok(x) => Ok(x), + Err(x) => Err(x), + } +} + +// CHECK-LABEL: @result_nop_traits_64 +#[no_mangle] +pub fn result_nop_traits_64(x: Result<i64, u64>) -> Result<i64, u64> { + // CHECK: start: + // CHECK-NEXT: insertvalue { i64, i64 } + // CHECK-NEXT: insertvalue { i64, i64 } + // CHECK-NEXT: ret { i64, i64 } + try { + x? + } +} + +// CHECK-LABEL: @result_nop_match_ptr +#[no_mangle] +pub fn result_nop_match_ptr(x: Result<usize, Box<()>>) -> Result<usize, Box<()>> { + // CHECK: start: + // CHECK-NEXT: insertvalue { i{{[0-9]+}}, ptr } + // CHECK-NEXT: insertvalue { i{{[0-9]+}}, ptr } + // CHECK-NEXT: ret + match x { + Ok(x) => Ok(x), + Err(x) => Err(x), + } +} + +// CHECK-LABEL: @result_nop_traits_ptr +#[no_mangle] +pub fn result_nop_traits_ptr(x: Result<u64, NonNull<()>>) -> Result<u64, NonNull<()>> { + // CHECK: start: + // CHECK-NEXT: insertvalue { i{{[0-9]+}}, ptr } + // CHECK-NEXT: insertvalue { i{{[0-9]+}}, ptr } + // CHECK-NEXT: ret try { x? } @@ -34,8 +110,10 @@ pub fn result_nop_traits_32(x: Result<i32, u32>) -> Result<i32, u32> { // CHECK-LABEL: @control_flow_nop_match_32 #[no_mangle] pub fn control_flow_nop_match_32(x: ControlFlow<i32, u32>) -> ControlFlow<i32, u32> { - // CHECK: start - // CHECK-NEXT: ret i64 %0 + // CHECK: start: + // CHECK-NEXT: insertvalue { i32, i32 } + // CHECK-NEXT: insertvalue { i32, i32 } + // CHECK-NEXT: ret { i32, i32 } match x { Continue(x) => Continue(x), Break(x) => Break(x), @@ -45,8 +123,10 @@ pub fn control_flow_nop_match_32(x: ControlFlow<i32, u32>) -> ControlFlow<i32, u // CHECK-LABEL: @control_flow_nop_traits_32 #[no_mangle] pub fn control_flow_nop_traits_32(x: ControlFlow<i32, u32>) -> ControlFlow<i32, u32> { - // CHECK: start - // CHECK-NEXT: ret i64 %0 + // CHECK: start: + // CHECK-NEXT: insertvalue { i32, i32 } + // CHECK-NEXT: insertvalue { i32, i32 } + // CHECK-NEXT: ret { i32, i32 } try { x? } |
