diff options
Diffstat (limited to 'src/test/codegen')
-rw-r--r-- | src/test/codegen/abi-main-signature-32bit-c-int.rs | 2 | ||||
-rw-r--r-- | src/test/codegen/binary-search-index-no-bound-check.rs | 20 | ||||
-rw-r--r-- | src/test/codegen/deduced-param-attrs.rs | 60 | ||||
-rw-r--r-- | src/test/codegen/function-arguments.rs | 2 | ||||
-rw-r--r-- | src/test/codegen/mem-replace-direct-memcpy.rs | 1 | ||||
-rw-r--r-- | src/test/codegen/sanitizer_scs_attr_check.rs | 6 | ||||
-rw-r--r-- | src/test/codegen/slice-iter-len-eq-zero.rs | 14 | ||||
-rw-r--r-- | src/test/codegen/slice_as_from_ptr_range.rs | 23 | ||||
-rw-r--r-- | src/test/codegen/stack-probes-call.rs | 24 | ||||
-rw-r--r-- | src/test/codegen/stack-probes-inline.rs | 32 | ||||
-rw-r--r-- | src/test/codegen/stack-probes.rs | 22 | ||||
-rw-r--r-- | src/test/codegen/vec-calloc.rs | 19 | ||||
-rw-r--r-- | src/test/codegen/vec-in-place.rs | 2 |
13 files changed, 198 insertions, 29 deletions
diff --git a/src/test/codegen/abi-main-signature-32bit-c-int.rs b/src/test/codegen/abi-main-signature-32bit-c-int.rs index 31b19a542..7f22ddcfc 100644 --- a/src/test/codegen/abi-main-signature-32bit-c-int.rs +++ b/src/test/codegen/abi-main-signature-32bit-c-int.rs @@ -7,4 +7,4 @@ fn main() { } -// CHECK: define i32 @main(i32{{( %0)?}}, {{i8\*\*|ptr}}{{( %1)?}}) +// CHECK: define{{( hidden)?}} i32 @main(i32{{( %0)?}}, {{i8\*\*|ptr}}{{( %1)?}}) diff --git a/src/test/codegen/binary-search-index-no-bound-check.rs b/src/test/codegen/binary-search-index-no-bound-check.rs index 2deabcaa6..c1766a4a4 100644 --- a/src/test/codegen/binary-search-index-no-bound-check.rs +++ b/src/test/codegen/binary-search-index-no-bound-check.rs @@ -16,3 +16,23 @@ pub fn binary_search_index_no_bounds_check(s: &[u8]) -> u8 { 42 } } + +// Similarly, check that `partition_point` is known to return a valid fencepost. + +// CHECK-LABEL: @unknown_split +#[no_mangle] +pub fn unknown_split(x: &[i32], i: usize) -> (&[i32], &[i32]) { + // This just makes sure that the subsequent function is looking for the + // absence of something that might actually be there. + + // CHECK: call core::panicking::panic + x.split_at(i) +} + +// CHECK-LABEL: @partition_point_split_no_bounds_check +#[no_mangle] +pub fn partition_point_split_no_bounds_check(x: &[i32], needle: i32) -> (&[i32], &[i32]) { + // CHECK-NOT: call core::panicking::panic + let i = x.partition_point(|p| p < &needle); + x.split_at(i) +} diff --git a/src/test/codegen/deduced-param-attrs.rs b/src/test/codegen/deduced-param-attrs.rs new file mode 100644 index 000000000..153046eef --- /dev/null +++ b/src/test/codegen/deduced-param-attrs.rs @@ -0,0 +1,60 @@ +// compile-flags: -O + +#![crate_type = "lib"] +#![allow(incomplete_features)] +#![feature(unsized_locals, unsized_fn_params)] + +use std::cell::Cell; +use std::hint; + +// Check to make sure that we can deduce the `readonly` attribute from function bodies for +// parameters passed indirectly. + +pub struct BigStruct { + blah: [i32; 1024], +} + +pub struct BigCellContainer { + blah: [Cell<i32>; 1024], +} + +// The by-value parameter for this big struct can be marked readonly. +// +// CHECK: @use_big_struct_immutably({{.*}} readonly {{.*}} %big_struct) +#[no_mangle] +pub fn use_big_struct_immutably(big_struct: BigStruct) { + hint::black_box(&big_struct); +} + +// The by-value parameter for this big struct can't be marked readonly, because we mutate it. +// +// CHECK-NOT: @use_big_struct_mutably({{.*}} readonly {{.*}} %big_struct) +#[no_mangle] +pub fn use_big_struct_mutably(mut big_struct: BigStruct) { + big_struct.blah[987] = 654; + hint::black_box(&big_struct); +} + +// The by-value parameter for this big struct can't be marked readonly, because it contains +// UnsafeCell. +// +// CHECK-NOT: @use_big_cell_container({{.*}} readonly {{.*}} %big_cell_container) +#[no_mangle] +pub fn use_big_cell_container(big_cell_container: BigCellContainer) { + hint::black_box(&big_cell_container); +} + +// Make sure that we don't mistakenly mark a big struct as `readonly` when passed through a generic +// type parameter if it contains UnsafeCell. +// +// CHECK-NOT: @use_something({{.*}} readonly {{.*}} %something) +#[no_mangle] +#[inline(never)] +pub fn use_something<T>(something: T) { + hint::black_box(&something); +} + +#[no_mangle] +pub fn forward_big_cell_container(big_cell_container: BigCellContainer) { + use_something(big_cell_container) +} diff --git a/src/test/codegen/function-arguments.rs b/src/test/codegen/function-arguments.rs index bc650ebf5..44fee9523 100644 --- a/src/test/codegen/function-arguments.rs +++ b/src/test/codegen/function-arguments.rs @@ -127,7 +127,7 @@ pub fn mutable_notunpin_borrow(_: &mut NotUnpin) { pub fn notunpin_borrow(_: &NotUnpin) { } -// CHECK: @indirect_struct({{%S\*|ptr}} noalias nocapture noundef dereferenceable(32) %_1) +// CHECK: @indirect_struct({{%S\*|ptr}} noalias nocapture noundef readonly dereferenceable(32) %_1) #[no_mangle] pub fn indirect_struct(_: S) { } diff --git a/src/test/codegen/mem-replace-direct-memcpy.rs b/src/test/codegen/mem-replace-direct-memcpy.rs index b41ef538d..4318e926e 100644 --- a/src/test/codegen/mem-replace-direct-memcpy.rs +++ b/src/test/codegen/mem-replace-direct-memcpy.rs @@ -4,6 +4,7 @@ // known to be `1` after inlining). // compile-flags: -C no-prepopulate-passes -Zinline-mir=no +// ignore-debug: the debug assertions get in the way #![crate_type = "lib"] diff --git a/src/test/codegen/sanitizer_scs_attr_check.rs b/src/test/codegen/sanitizer_scs_attr_check.rs index 0b53db3b7..a885d9117 100644 --- a/src/test/codegen/sanitizer_scs_attr_check.rs +++ b/src/test/codegen/sanitizer_scs_attr_check.rs @@ -7,11 +7,11 @@ #![crate_type = "lib"] #![feature(no_sanitize)] -// CHECK: ; Function Attrs:{{.*}}shadowcallstack -// CHECK-NEXT: scs +// CHECK: ; sanitizer_scs_attr_check::scs +// CHECK-NEXT: ; Function Attrs:{{.*}}shadowcallstack pub fn scs() {} +// CHECK: ; sanitizer_scs_attr_check::no_scs // CHECK-NOT: ; Function Attrs:{{.*}}shadowcallstack -// CHECK-NEXT: no_scs #[no_sanitize(shadow_call_stack)] pub fn no_scs() {} diff --git a/src/test/codegen/slice-iter-len-eq-zero.rs b/src/test/codegen/slice-iter-len-eq-zero.rs index fd19e624c..112402825 100644 --- a/src/test/codegen/slice-iter-len-eq-zero.rs +++ b/src/test/codegen/slice-iter-len-eq-zero.rs @@ -1,5 +1,6 @@ // no-system-llvm // compile-flags: -O +// ignore-debug: the debug assertions add extra comparisons #![crate_type = "lib"] type Demo = [u8; 3]; @@ -12,3 +13,16 @@ pub fn slice_iter_len_eq_zero(y: std::slice::Iter<'_, Demo>) -> bool { // CHECK: ret i1 %2 y.len() == 0 } + +// CHECK-LABEL: @array_into_iter_len_eq_zero +#[no_mangle] +pub fn array_into_iter_len_eq_zero(y: std::array::IntoIter<Demo, 123>) -> bool { + // This should be able to just check that the indexes are equal, and not + // need any subtractions or comparisons to handle `start > end`. + + // CHECK-NOT: icmp + // CHECK-NOT: sub + // CHECK: %1 = icmp eq {{i16|i32|i64}} + // CHECK: ret i1 %1 + y.len() == 0 +} diff --git a/src/test/codegen/slice_as_from_ptr_range.rs b/src/test/codegen/slice_as_from_ptr_range.rs new file mode 100644 index 000000000..0e3fefd97 --- /dev/null +++ b/src/test/codegen/slice_as_from_ptr_range.rs @@ -0,0 +1,23 @@ +// compile-flags: -O +// only-64bit (because we're using [ui]size) +// ignore-debug (because the assertions get in the way) +// min-llvm-version: 15.0 (because this is a relatively new instcombine) + +#![crate_type = "lib"] +#![feature(slice_from_ptr_range)] + +// This is intentionally using a non-power-of-two array length, +// as that's where the optimization differences show up + +// CHECK-LABEL: @flatten_via_ptr_range +#[no_mangle] +pub fn flatten_via_ptr_range(slice_of_arrays: &[[i32; 13]]) -> &[i32] { + // CHECK-NOT: lshr + // CHECK-NOT: udiv + // CHECK: mul nuw nsw i64 %{{.+}}, 13 + // CHECK-NOT: lshr + // CHECK-NOT: udiv + let r = slice_of_arrays.as_ptr_range(); + let r = r.start.cast()..r.end.cast(); + unsafe { core::slice::from_ptr_range(r) } +} diff --git a/src/test/codegen/stack-probes-call.rs b/src/test/codegen/stack-probes-call.rs new file mode 100644 index 000000000..a18fd41c2 --- /dev/null +++ b/src/test/codegen/stack-probes-call.rs @@ -0,0 +1,24 @@ +// Check the "probe-stack" attribute for targets with `StackProbeType::Call`, +// or `StackProbeType::InlineOrCall` when running on older LLVM. + +// compile-flags: -C no-prepopulate-passes +// revisions: i686 x86_64 +//[i686] compile-flags: --target i686-unknown-linux-gnu +//[i686] needs-llvm-components: x86 +//[i686] ignore-llvm-version: 16 - 99 +//[x86_64] compile-flags: --target x86_64-unknown-linux-gnu +//[x86_64] needs-llvm-components: x86 +//[x86_64] ignore-llvm-version: 16 - 99 + +#![crate_type = "rlib"] +#![feature(no_core, lang_items)] +#![no_core] + +#[lang = "sized"] +trait Sized {} + +#[no_mangle] +pub fn foo() { +// CHECK: @foo() unnamed_addr #0 +// CHECK: attributes #0 = { {{.*}}"probe-stack"="__rust_probestack"{{.*}} } +} diff --git a/src/test/codegen/stack-probes-inline.rs b/src/test/codegen/stack-probes-inline.rs new file mode 100644 index 000000000..a6b781de5 --- /dev/null +++ b/src/test/codegen/stack-probes-inline.rs @@ -0,0 +1,32 @@ +// Check the "probe-stack" attribute for targets with `StackProbeType::Inline`, +// or `StackProbeType::InlineOrCall` when running on newer LLVM. + +// compile-flags: -C no-prepopulate-passes +// revisions: powerpc powerpc64 powerpc64le s390x i686 x86_64 +//[powerpc] compile-flags: --target powerpc-unknown-linux-gnu +//[powerpc] needs-llvm-components: powerpc +//[powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu +//[powerpc64] needs-llvm-components: powerpc +//[powerpc64le] compile-flags: --target powerpc64le-unknown-linux-gnu +//[powerpc64le] needs-llvm-components: powerpc +//[s390x] compile-flags: --target s390x-unknown-linux-gnu +//[s390x] needs-llvm-components: systemz +//[i686] compile-flags: --target i686-unknown-linux-gnu +//[i686] needs-llvm-components: x86 +//[i686] min-llvm-version: 16 +//[x86_64] compile-flags: --target x86_64-unknown-linux-gnu +//[x86_64] needs-llvm-components: x86 +//[x86_64] min-llvm-version: 16 + +#![crate_type = "rlib"] +#![feature(no_core, lang_items)] +#![no_core] + +#[lang = "sized"] +trait Sized {} + +#[no_mangle] +pub fn foo() { +// CHECK: @foo() unnamed_addr #0 +// CHECK: attributes #0 = { {{.*}}"probe-stack"="inline-asm"{{.*}} } +} diff --git a/src/test/codegen/stack-probes.rs b/src/test/codegen/stack-probes.rs deleted file mode 100644 index 9bd351df3..000000000 --- a/src/test/codegen/stack-probes.rs +++ /dev/null @@ -1,22 +0,0 @@ -// ignore-arm -// ignore-aarch64 -// ignore-mips -// ignore-mips64 -// ignore-powerpc -// ignore-powerpc64 -// ignore-powerpc64le -// ignore-riscv64 -// ignore-s390x -// ignore-sparc -// ignore-sparc64 -// ignore-wasm -// ignore-emscripten -// ignore-windows -// compile-flags: -C no-prepopulate-passes - -#![crate_type = "lib"] - -#[no_mangle] -pub fn foo() { -// CHECK: @foo() unnamed_addr #0 -} diff --git a/src/test/codegen/vec-calloc.rs b/src/test/codegen/vec-calloc.rs index 435a4ab51..ae6e448f1 100644 --- a/src/test/codegen/vec-calloc.rs +++ b/src/test/codegen/vec-calloc.rs @@ -1,4 +1,4 @@ -// compile-flags: -O +// compile-flags: -O -Z merge-functions=disabled // only-x86_64 // ignore-debug // min-llvm-version: 15.0 @@ -144,6 +144,23 @@ pub fn vec_non_zero_tuple(n: usize) -> Vec<(i16, u8, char)> { vec![(0, 0, 'A'); n] } +// CHECK-LABEL: @vec_option_bool +#[no_mangle] +pub fn vec_option_bool(n: usize) -> Vec<Option<bool>> { + // CHECK-NOT: call {{.*}}alloc::vec::from_elem + // CHECK-NOT: call {{.*}}reserve + // CHECK-NOT: call {{.*}}__rust_alloc( + + // CHECK: call {{.*}}__rust_alloc_zeroed( + + // CHECK-NOT: call {{.*}}alloc::vec::from_elem + // CHECK-NOT: call {{.*}}reserve + // CHECK-NOT: call {{.*}}__rust_alloc( + + // CHECK: ret void + vec![Some(false); n] +} + // Ensure that __rust_alloc_zeroed gets the right attributes for LLVM to optimize it away. // CHECK: declare noalias ptr @__rust_alloc_zeroed(i64, i64 allocalign) unnamed_addr [[RUST_ALLOC_ZEROED_ATTRS:#[0-9]+]] diff --git a/src/test/codegen/vec-in-place.rs b/src/test/codegen/vec-in-place.rs index 62139aa9b..5df366905 100644 --- a/src/test/codegen/vec-in-place.rs +++ b/src/test/codegen/vec-in-place.rs @@ -17,7 +17,7 @@ pub struct Foo { // Going from an aggregate struct to another type currently requires Copy to // enable the TrustedRandomAccess specialization. Without it optimizations do not yet -// reliably recognize the loops as noop for for repr(C) or non-Copy structs. +// reliably recognize the loops as noop for repr(C) or non-Copy structs. #[derive(Copy, Clone)] pub struct Bar { a: u64, |