about summary refs log tree commit diff
path: root/tests/codegen-llvm
diff options
context:
space:
mode:
Diffstat (limited to 'tests/codegen-llvm')
-rw-r--r--tests/codegen-llvm/addr-of-mutate.rs6
-rw-r--r--tests/codegen-llvm/array-repeat.rs1
-rw-r--r--tests/codegen-llvm/async-fn-debug-awaitee-field.rs8
-rw-r--r--tests/codegen-llvm/atomicptr.rs1
-rw-r--r--tests/codegen-llvm/cffi/c-variadic-ffi.rs2
-rw-r--r--tests/codegen-llvm/function-arguments.rs4
-rw-r--r--tests/codegen-llvm/issues/and-masked-comparison-131162.rs17
-rw-r--r--tests/codegen-llvm/issues/assert-for-loop-bounds-check-71997.rs18
-rw-r--r--tests/codegen-llvm/issues/elided-division-by-zero-check-74917.rs13
-rw-r--r--tests/codegen-llvm/issues/for-loop-inner-assert-91109.rs18
-rw-r--r--tests/codegen-llvm/issues/issue-118306.rs2
-rw-r--r--tests/codegen-llvm/issues/iter-max-no-unwrap-failed-129583.rs31
-rw-r--r--tests/codegen-llvm/issues/matches-logical-or-141497.rs25
-rw-r--r--tests/codegen-llvm/issues/no-bounds-check-after-assert-110971.rs14
-rw-r--r--tests/codegen-llvm/issues/no-panic-for-pop-after-assert-71257.rs19
-rw-r--r--tests/codegen-llvm/issues/num-is-digit-to-digit-59352.rs14
-rw-r--r--tests/codegen-llvm/issues/slice-index-bounds-check-80075.rs13
-rw-r--r--tests/codegen-llvm/iter-repeat-n-trivial-drop.rs1
-rw-r--r--tests/codegen-llvm/loongarch-abi/loongarch64-lp64d-abi.rs4
19 files changed, 195 insertions, 16 deletions
diff --git a/tests/codegen-llvm/addr-of-mutate.rs b/tests/codegen-llvm/addr-of-mutate.rs
index 71669065289..36d6bf555d1 100644
--- a/tests/codegen-llvm/addr-of-mutate.rs
+++ b/tests/codegen-llvm/addr-of-mutate.rs
@@ -5,7 +5,7 @@
 // Test for the absence of `readonly` on the argument when it is mutated via `&raw const`.
 // See <https://github.com/rust-lang/rust/issues/111502>.
 
-// CHECK: i8 @foo(ptr{{( dead_on_return)?}} noalias{{( nocapture)?}} noundef align 1{{( captures\(none\))?}} dereferenceable(128) %x)
+// CHECK: i8 @foo(ptr{{( dead_on_return)?}} noalias noundef align 1{{( captures\(address\))?}} dereferenceable(128) %x)
 #[no_mangle]
 pub fn foo(x: [u8; 128]) -> u8 {
     let ptr = core::ptr::addr_of!(x).cast_mut();
@@ -15,7 +15,7 @@ pub fn foo(x: [u8; 128]) -> u8 {
     x[0]
 }
 
-// CHECK: i1 @second(ptr{{( dead_on_return)?}} noalias{{( nocapture)?}} noundef align {{[0-9]+}}{{( captures\(none\))?}} dereferenceable({{[0-9]+}}) %a_ptr_and_b)
+// CHECK: i1 @second(ptr{{( dead_on_return)?}} noalias noundef align {{[0-9]+}}{{( captures\(address\))?}} dereferenceable({{[0-9]+}}) %a_ptr_and_b)
 #[no_mangle]
 pub unsafe fn second(a_ptr_and_b: (*mut (i32, bool), (i64, bool))) -> bool {
     let b_bool_ptr = core::ptr::addr_of!(a_ptr_and_b.1.1).cast_mut();
@@ -24,7 +24,7 @@ pub unsafe fn second(a_ptr_and_b: (*mut (i32, bool), (i64, bool))) -> bool {
 }
 
 // If going through a deref (and there are no other mutating accesses), then `readonly` is fine.
-// CHECK: i1 @third(ptr{{( dead_on_return)?}} noalias{{( nocapture)?}} noundef readonly align {{[0-9]+}}{{( captures\(none\))?}} dereferenceable({{[0-9]+}}) %a_ptr_and_b)
+// CHECK: i1 @third(ptr{{( dead_on_return)?}} noalias noundef readonly align {{[0-9]+}}{{( captures\(address\))?}} dereferenceable({{[0-9]+}}) %a_ptr_and_b)
 #[no_mangle]
 pub unsafe fn third(a_ptr_and_b: (*mut (i32, bool), (i64, bool))) -> bool {
     let b_bool_ptr = core::ptr::addr_of!((*a_ptr_and_b.0).1).cast_mut();
diff --git a/tests/codegen-llvm/array-repeat.rs b/tests/codegen-llvm/array-repeat.rs
index 4c755df9390..1c45341d764 100644
--- a/tests/codegen-llvm/array-repeat.rs
+++ b/tests/codegen-llvm/array-repeat.rs
@@ -1,7 +1,6 @@
 //@ compile-flags: -Copt-level=3
 
 #![crate_type = "lib"]
-#![feature(array_repeat)]
 
 use std::array::repeat;
 
diff --git a/tests/codegen-llvm/async-fn-debug-awaitee-field.rs b/tests/codegen-llvm/async-fn-debug-awaitee-field.rs
index 50860c90662..b9d3d9ee66e 100644
--- a/tests/codegen-llvm/async-fn-debug-awaitee-field.rs
+++ b/tests/codegen-llvm/async-fn-debug-awaitee-field.rs
@@ -18,11 +18,11 @@ pub async fn async_fn_test() {
 
 pub async fn foo() {}
 
+// NONMSVC: [[AWAITEE_TYPE:![0-9]*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "{async_fn_env#0}", scope: [[AWAITEE_SCOPE:![0-9]*]],
+// MSVC: [[AWAITEE_TYPE:![0-9]*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<async_fn_debug_awaitee_field::foo::async_fn_env$0>",
+// NONMSVC: [[AWAITEE_SCOPE]] = !DINamespace(name: "foo",
 // NONMSVC: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "{async_fn_env#0}", scope: [[GEN_SCOPE:![0-9]*]],
 // MSVC: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<async_fn_debug_awaitee_field::async_fn_test::async_fn_env$0>",
 // NONMSVC: [[GEN_SCOPE:!.*]] = !DINamespace(name: "async_fn_test",
 // CHECK: [[SUSPEND_STRUCT:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend0", scope: [[GEN]],
-// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "__awaitee", scope: [[SUSPEND_STRUCT]], {{.*}}, baseType: [[AWAITEE_TYPE:![0-9]*]],
-// NONMSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "{async_fn_env#0}", scope: [[AWAITEE_SCOPE:![0-9]*]],
-// MSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<async_fn_debug_awaitee_field::foo::async_fn_env$0>",
-// NONMSVC: [[AWAITEE_SCOPE]] = !DINamespace(name: "foo",
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "__awaitee", scope: [[SUSPEND_STRUCT]], {{.*}}, baseType: [[AWAITEE_TYPE]],
diff --git a/tests/codegen-llvm/atomicptr.rs b/tests/codegen-llvm/atomicptr.rs
index ce6c4aa0d2b..9d5e618fe76 100644
--- a/tests/codegen-llvm/atomicptr.rs
+++ b/tests/codegen-llvm/atomicptr.rs
@@ -6,7 +6,6 @@
 
 //@ compile-flags: -Copt-level=3 -Cno-prepopulate-passes
 #![crate_type = "lib"]
-#![feature(strict_provenance_atomic_ptr)]
 
 use std::ptr::without_provenance_mut;
 use std::sync::atomic::AtomicPtr;
diff --git a/tests/codegen-llvm/cffi/c-variadic-ffi.rs b/tests/codegen-llvm/cffi/c-variadic-ffi.rs
index 3e99c9fb84e..1dee477e9ed 100644
--- a/tests/codegen-llvm/cffi/c-variadic-ffi.rs
+++ b/tests/codegen-llvm/cffi/c-variadic-ffi.rs
@@ -14,7 +14,7 @@
 //@[arm32] needs-llvm-components: arm
 #![crate_type = "lib"]
 #![feature(no_core)]
-#![feature(extended_varargs_abi_support, extern_system_varargs)]
+#![feature(extern_system_varargs)]
 #![no_core]
 
 extern crate minicore;
diff --git a/tests/codegen-llvm/function-arguments.rs b/tests/codegen-llvm/function-arguments.rs
index db508682862..a0744e44c61 100644
--- a/tests/codegen-llvm/function-arguments.rs
+++ b/tests/codegen-llvm/function-arguments.rs
@@ -134,7 +134,7 @@ pub fn mutable_notunpin_borrow(_: &mut NotUnpin) {}
 #[no_mangle]
 pub fn notunpin_borrow(_: &NotUnpin) {}
 
-// CHECK: @indirect_struct(ptr{{( dead_on_return)?}} noalias{{( nocapture)?}} noundef readonly align 4{{( captures\(none\))?}} dereferenceable(32) %_1)
+// CHECK: @indirect_struct(ptr{{( dead_on_return)?}} noalias noundef readonly align 4{{( captures\(address\))?}} dereferenceable(32) %_1)
 #[no_mangle]
 pub fn indirect_struct(_: S) {}
 
@@ -197,7 +197,7 @@ pub fn notunpin_box(x: Box<NotUnpin>) -> Box<NotUnpin> {
     x
 }
 
-// CHECK: @struct_return(ptr{{( dead_on_unwind)?}} noalias{{( nocapture)?}} noundef{{( writable)?}} sret([32 x i8]) align 4{{( captures\(none\))?}} dereferenceable(32){{( %_0)?}})
+// CHECK: @struct_return(ptr{{( dead_on_unwind)?}} noalias noundef{{( writable)?}} sret([32 x i8]) align 4{{( captures\(address\))?}} dereferenceable(32){{( %_0)?}})
 #[no_mangle]
 pub fn struct_return() -> S {
     S { _field: [0, 0, 0, 0, 0, 0, 0, 0] }
diff --git a/tests/codegen-llvm/issues/and-masked-comparison-131162.rs b/tests/codegen-llvm/issues/and-masked-comparison-131162.rs
new file mode 100644
index 00000000000..bdf021092fd
--- /dev/null
+++ b/tests/codegen-llvm/issues/and-masked-comparison-131162.rs
@@ -0,0 +1,17 @@
+//@ compile-flags: -Copt-level=3
+//@ min-llvm-version: 20
+
+#![crate_type = "lib"]
+
+// CHECK-LABEL: @issue_131162
+#[no_mangle]
+pub fn issue_131162(a1: usize, a2: usize) -> bool {
+    const MASK: usize = 1;
+
+    // CHECK-NOT: xor
+    // CHECK-NOT: trunc
+    // CHECK-NOT: and i1
+    // CHECK: icmp
+    // CHECK-NEXT: ret
+    (a1 & !MASK) == (a2 & !MASK) && (a1 & MASK) == (a2 & MASK)
+}
diff --git a/tests/codegen-llvm/issues/assert-for-loop-bounds-check-71997.rs b/tests/codegen-llvm/issues/assert-for-loop-bounds-check-71997.rs
new file mode 100644
index 00000000000..a0c64d607a8
--- /dev/null
+++ b/tests/codegen-llvm/issues/assert-for-loop-bounds-check-71997.rs
@@ -0,0 +1,18 @@
+// Tests that there's no bounds check within for-loop after asserting that
+// the range start and end are within bounds.
+
+//@ compile-flags: -Copt-level=3
+
+#![crate_type = "lib"]
+
+// CHECK-LABEL: @no_bounds_check_after_assert
+#[no_mangle]
+fn no_bounds_check_after_assert(slice: &[u64], start: usize, end: usize) -> u64 {
+    // CHECK-NOT: panic_bounds_check
+    let mut total = 0;
+    assert!(start < end && start < slice.len() && end <= slice.len());
+    for i in start..end {
+        total += slice[i];
+    }
+    total
+}
diff --git a/tests/codegen-llvm/issues/elided-division-by-zero-check-74917.rs b/tests/codegen-llvm/issues/elided-division-by-zero-check-74917.rs
new file mode 100644
index 00000000000..9e890e14852
--- /dev/null
+++ b/tests/codegen-llvm/issues/elided-division-by-zero-check-74917.rs
@@ -0,0 +1,13 @@
+// Tests that there is no check for dividing by zero since the
+// denominator, `(x - y)`, will always be greater than 0 since `x > y`.
+
+//@ compile-flags: -Copt-level=3
+
+#![crate_type = "lib"]
+
+// CHECK-LABEL: @issue_74917
+#[no_mangle]
+pub fn issue_74917(x: u16, y: u16) -> u16 {
+    // CHECK-NOT: panic
+    if x > y { 100 / (x - y) } else { 100 }
+}
diff --git a/tests/codegen-llvm/issues/for-loop-inner-assert-91109.rs b/tests/codegen-llvm/issues/for-loop-inner-assert-91109.rs
new file mode 100644
index 00000000000..bffbcd7d069
--- /dev/null
+++ b/tests/codegen-llvm/issues/for-loop-inner-assert-91109.rs
@@ -0,0 +1,18 @@
+// Tests that there's no bounds check for the inner loop after the assert.
+
+//@ compile-flags: -Copt-level=3
+
+#![crate_type = "lib"]
+
+// CHECK-LABEL: @zero
+#[no_mangle]
+pub fn zero(d: &mut [Vec<i32>]) {
+    // CHECK-NOT: panic_bounds_check
+    let n = d.len();
+    for i in 0..n {
+        assert!(d[i].len() == n);
+        for j in 0..n {
+            d[i][j] = 0;
+        }
+    }
+}
diff --git a/tests/codegen-llvm/issues/issue-118306.rs b/tests/codegen-llvm/issues/issue-118306.rs
index f12dc7cdfe2..934a7687b60 100644
--- a/tests/codegen-llvm/issues/issue-118306.rs
+++ b/tests/codegen-llvm/issues/issue-118306.rs
@@ -11,7 +11,7 @@ pub fn branchy(input: u64) -> u64 {
     // CHECK-LABEL: @branchy(
     // CHECK-NEXT:  start:
     // CHECK-NEXT:    [[_2:%.*]] = and i64 [[INPUT:%.*]], 3
-    // CHECK-NEXT:    [[SWITCH_GEP:%.*]] = getelementptr inbounds{{( nuw)?}} [4 x i64], ptr @switch.table.branchy, i64 0, i64 [[_2]]
+    // CHECK-NEXT:    [[SWITCH_GEP:%.*]] = getelementptr inbounds{{( nuw)?}} {{\[4 x i64\]|i64}}, ptr @switch.table.branchy{{(, i64 0)?}}, i64 [[_2]]
     // CHECK-NEXT:    [[SWITCH_LOAD:%.*]] = load i64, ptr [[SWITCH_GEP]]
     // CHECK-NEXT:    ret i64 [[SWITCH_LOAD]]
     match input % 4 {
diff --git a/tests/codegen-llvm/issues/iter-max-no-unwrap-failed-129583.rs b/tests/codegen-llvm/issues/iter-max-no-unwrap-failed-129583.rs
new file mode 100644
index 00000000000..4d3fa4993ef
--- /dev/null
+++ b/tests/codegen-llvm/issues/iter-max-no-unwrap-failed-129583.rs
@@ -0,0 +1,31 @@
+// Tests that `unwrap` is optimized out when the slice has a known length.
+// The iterator may unroll for values smaller than a certain threshold so we
+// use a larger value to prevent unrolling.
+
+//@ compile-flags: -Copt-level=3
+//@ min-llvm-version: 20
+
+#![crate_type = "lib"]
+
+// CHECK-LABEL: @infallible_max_not_unrolled
+#[no_mangle]
+pub fn infallible_max_not_unrolled(x: &[u8; 1024]) -> u8 {
+    // CHECK-NOT: panic
+    // CHECK-NOT: unwrap_failed
+    *x.iter().max().unwrap()
+}
+
+// CHECK-LABEL: @infallible_max_unrolled
+#[no_mangle]
+pub fn infallible_max_unrolled(x: &[u8; 10]) -> u8 {
+    // CHECK-NOT: panic
+    // CHECK-NOT: unwrap_failed
+    *x.iter().max().unwrap()
+}
+
+// CHECK-LABEL: @may_panic_max
+#[no_mangle]
+pub fn may_panic_max(x: &[u8]) -> u8 {
+    // CHECK: unwrap_failed
+    *x.iter().max().unwrap()
+}
diff --git a/tests/codegen-llvm/issues/matches-logical-or-141497.rs b/tests/codegen-llvm/issues/matches-logical-or-141497.rs
new file mode 100644
index 00000000000..348f62096a5
--- /dev/null
+++ b/tests/codegen-llvm/issues/matches-logical-or-141497.rs
@@ -0,0 +1,25 @@
+// Tests that `matches!` optimizes the same as
+// `f == FrameType::Inter || f == FrameType::Switch`.
+
+//@ compile-flags: -Copt-level=3
+//@ min-llvm-version: 21
+
+#![crate_type = "lib"]
+
+#[derive(Clone, Copy, PartialEq, Eq)]
+pub enum FrameType {
+    Key = 0,
+    Inter = 1,
+    Intra = 2,
+    Switch = 3,
+}
+
+// CHECK-LABEL: @is_inter_or_switch
+#[no_mangle]
+pub fn is_inter_or_switch(f: FrameType) -> bool {
+    // CHECK-NEXT: start:
+    // CHECK-NEXT: and i8
+    // CHECK-NEXT: icmp
+    // CHECK-NEXT: ret
+    matches!(f, FrameType::Inter | FrameType::Switch)
+}
diff --git a/tests/codegen-llvm/issues/no-bounds-check-after-assert-110971.rs b/tests/codegen-llvm/issues/no-bounds-check-after-assert-110971.rs
new file mode 100644
index 00000000000..aa4002f176d
--- /dev/null
+++ b/tests/codegen-llvm/issues/no-bounds-check-after-assert-110971.rs
@@ -0,0 +1,14 @@
+// Tests that the slice access for `j` doesn't have a bounds check panic after
+// being asserted as less than half of the slice length.
+
+//@ compile-flags: -Copt-level=3
+
+#![crate_type = "lib"]
+
+// CHECK-LABEL: @check_only_assert_panic
+#[no_mangle]
+pub fn check_only_assert_panic(arr: &[u32], j: usize) -> u32 {
+    // CHECK-NOT: panic_bounds_check
+    assert!(j < arr.len() / 2);
+    arr[j]
+}
diff --git a/tests/codegen-llvm/issues/no-panic-for-pop-after-assert-71257.rs b/tests/codegen-llvm/issues/no-panic-for-pop-after-assert-71257.rs
new file mode 100644
index 00000000000..68877c28d6c
--- /dev/null
+++ b/tests/codegen-llvm/issues/no-panic-for-pop-after-assert-71257.rs
@@ -0,0 +1,19 @@
+// Tests that the `unwrap` branch is optimized out from the `pop` since the
+// length has already been validated.
+
+//@ compile-flags: -Copt-level=3
+
+#![crate_type = "lib"]
+
+pub enum Foo {
+    First(usize),
+    Second(usize),
+}
+
+// CHECK-LABEL: @check_only_one_panic
+#[no_mangle]
+pub fn check_only_one_panic(v: &mut Vec<Foo>) -> Foo {
+    // CHECK-COUNT-1: call{{.+}}panic
+    assert!(v.len() == 1);
+    v.pop().unwrap()
+}
diff --git a/tests/codegen-llvm/issues/num-is-digit-to-digit-59352.rs b/tests/codegen-llvm/issues/num-is-digit-to-digit-59352.rs
new file mode 100644
index 00000000000..1d23eb2cdf9
--- /dev/null
+++ b/tests/codegen-llvm/issues/num-is-digit-to-digit-59352.rs
@@ -0,0 +1,14 @@
+// Tests that there's no panic on unwrapping `to_digit` call after checking
+// with `is_digit`.
+
+//@ compile-flags: -Copt-level=3
+
+#![crate_type = "lib"]
+
+// CHECK-LABEL: @num_to_digit_slow
+#[no_mangle]
+pub fn num_to_digit_slow(num: char) -> u32 {
+    // CHECK-NOT: br
+    // CHECK-NOT: panic
+    if num.is_digit(8) { num.to_digit(8).unwrap() } else { 0 }
+}
diff --git a/tests/codegen-llvm/issues/slice-index-bounds-check-80075.rs b/tests/codegen-llvm/issues/slice-index-bounds-check-80075.rs
new file mode 100644
index 00000000000..ecb5eb787c7
--- /dev/null
+++ b/tests/codegen-llvm/issues/slice-index-bounds-check-80075.rs
@@ -0,0 +1,13 @@
+// Tests that no bounds check panic is generated for `j` since
+// `j <= i < data.len()`.
+
+//@ compile-flags: -Copt-level=3
+
+#![crate_type = "lib"]
+
+// CHECK-LABEL: @issue_80075
+#[no_mangle]
+pub fn issue_80075(data: &[u8], i: usize, j: usize) -> u8 {
+    // CHECK-NOT: panic_bounds_check
+    if i < data.len() && j <= i { data[j] } else { 0 }
+}
diff --git a/tests/codegen-llvm/iter-repeat-n-trivial-drop.rs b/tests/codegen-llvm/iter-repeat-n-trivial-drop.rs
index 28173530324..6f340978428 100644
--- a/tests/codegen-llvm/iter-repeat-n-trivial-drop.rs
+++ b/tests/codegen-llvm/iter-repeat-n-trivial-drop.rs
@@ -4,7 +4,6 @@
 
 #![crate_type = "lib"]
 #![feature(iter_repeat_n)]
-#![feature(array_repeat)]
 
 #[derive(Clone)]
 pub struct NotCopy(u16);
diff --git a/tests/codegen-llvm/loongarch-abi/loongarch64-lp64d-abi.rs b/tests/codegen-llvm/loongarch-abi/loongarch64-lp64d-abi.rs
index 4666342a16a..7ea08a1a8f7 100644
--- a/tests/codegen-llvm/loongarch-abi/loongarch64-lp64d-abi.rs
+++ b/tests/codegen-llvm/loongarch-abi/loongarch64-lp64d-abi.rs
@@ -256,11 +256,11 @@ pub struct IntDoubleInt {
     c: i32,
 }
 
-// CHECK: define void @f_int_double_int_s_arg(ptr{{( dead_on_return)?}} noalias{{( nocapture)?}} noundef align 8{{( captures\(none\))?}} dereferenceable(24) %a)
+// CHECK: define void @f_int_double_int_s_arg(ptr{{( dead_on_return)?}} noalias noundef align 8{{( captures\(address\))?}} dereferenceable(24) %a)
 #[no_mangle]
 pub extern "C" fn f_int_double_int_s_arg(a: IntDoubleInt) {}
 
-// CHECK: define void @f_ret_int_double_int_s(ptr{{( dead_on_unwind)?}} noalias{{( nocapture)?}} noundef{{( writable)?}} sret([24 x i8]) align 8{{( captures\(none\))?}} dereferenceable(24) %_0)
+// CHECK: define void @f_ret_int_double_int_s(ptr{{( dead_on_unwind)?}} noalias noundef{{( writable)?}} sret([24 x i8]) align 8{{( captures\(address\))?}} dereferenceable(24) %_0)
 #[no_mangle]
 pub extern "C" fn f_ret_int_double_int_s() -> IntDoubleInt {
     IntDoubleInt { a: 1, b: 2., c: 3 }