summaryrefslogtreecommitdiffstats
path: root/src/test/codegen
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/codegen')
-rw-r--r--src/test/codegen/abi-main-signature-32bit-c-int.rs2
-rw-r--r--src/test/codegen/binary-search-index-no-bound-check.rs20
-rw-r--r--src/test/codegen/deduced-param-attrs.rs60
-rw-r--r--src/test/codegen/function-arguments.rs2
-rw-r--r--src/test/codegen/mem-replace-direct-memcpy.rs1
-rw-r--r--src/test/codegen/sanitizer_scs_attr_check.rs6
-rw-r--r--src/test/codegen/slice-iter-len-eq-zero.rs14
-rw-r--r--src/test/codegen/slice_as_from_ptr_range.rs23
-rw-r--r--src/test/codegen/stack-probes-call.rs24
-rw-r--r--src/test/codegen/stack-probes-inline.rs32
-rw-r--r--src/test/codegen/stack-probes.rs22
-rw-r--r--src/test/codegen/vec-calloc.rs19
-rw-r--r--src/test/codegen/vec-in-place.rs2
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,