about summary refs log tree commit diff
path: root/tests/codegen/issues
diff options
context:
space:
mode:
authorScott McMurray <scottmcm@users.noreply.github.com>2023-03-15 09:09:10 -0700
committerMaybe Waffle <waffle.lapkin@gmail.com>2023-03-20 10:25:29 +0000
commit5dfe37a5044376834825e55dcc3a4bb4b52bb237 (patch)
treefbb27ac3b643cf31c8f42e31711c1375ec2ac65f /tests/codegen/issues
parente91364bcf5100017a8bd5b18cdebefdd3e5f0bb1 (diff)
downloadrust-5dfe37a5044376834825e55dcc3a4bb4b52bb237.tar.gz
rust-5dfe37a5044376834825e55dcc3a4bb4b52bb237.zip
mv tests/codegen/issue-* tests/codegen/issues/
Diffstat (limited to 'tests/codegen/issues')
-rw-r--r--tests/codegen/issues/issue-103285-ptr-addr-overflow-check.rs16
-rw-r--r--tests/codegen/issues/issue-103840.rs9
-rw-r--r--tests/codegen/issues/issue-105386-ub-in-debuginfo.rs22
-rw-r--r--tests/codegen/issues/issue-13018.rs11
-rw-r--r--tests/codegen/issues/issue-15953.rs29
-rw-r--r--tests/codegen/issues/issue-27130.rs21
-rw-r--r--tests/codegen/issues/issue-32031.rs23
-rw-r--r--tests/codegen/issues/issue-32364.rs18
-rw-r--r--tests/codegen/issues/issue-34634.rs16
-rw-r--r--tests/codegen/issues/issue-34947-pow-i32.rs13
-rw-r--r--tests/codegen/issues/issue-37945.rs38
-rw-r--r--tests/codegen/issues/issue-44056-macos-tls-align.rs28
-rw-r--r--tests/codegen/issues/issue-45222.rs63
-rw-r--r--tests/codegen/issues/issue-45466.rs15
-rw-r--r--tests/codegen/issues/issue-45964-bounds-check-slice-pos.rs39
-rw-r--r--tests/codegen/issues/issue-47278.rs9
-rw-r--r--tests/codegen/issues/issue-47442.rs22
-rw-r--r--tests/codegen/issues/issue-56267-2.rs18
-rw-r--r--tests/codegen/issues/issue-56267.rs18
-rw-r--r--tests/codegen/issues/issue-56927.rs43
-rw-r--r--tests/codegen/issues/issue-58881.rs21
-rw-r--r--tests/codegen/issues/issue-59352.rs18
-rw-r--r--tests/codegen/issues/issue-69101-bounds-check.rs44
-rw-r--r--tests/codegen/issues/issue-73031.rs26
-rw-r--r--tests/codegen/issues/issue-73338-effecient-cmp.rs39
-rw-r--r--tests/codegen/issues/issue-73396-bounds-check-after-position.rs77
-rw-r--r--tests/codegen/issues/issue-73827-bounds-check-index-in-subexpr.rs17
-rw-r--r--tests/codegen/issues/issue-75525-bounds-checks.rs26
-rw-r--r--tests/codegen/issues/issue-75546.rs15
-rw-r--r--tests/codegen/issues/issue-75659.rs63
-rw-r--r--tests/codegen/issues/issue-77812.rs32
-rw-r--r--tests/codegen/issues/issue-81408-dllimport-thinlto-windows.rs15
-rw-r--r--tests/codegen/issues/issue-84268.rs23
-rw-r--r--tests/codegen/issues/issue-85872-multiple-reverse.rs20
-rw-r--r--tests/codegen/issues/issue-86106.rs62
-rw-r--r--tests/codegen/issues/issue-96274.rs17
-rw-r--r--tests/codegen/issues/issue-96497-slice-size-nowrap.rs29
-rw-r--r--tests/codegen/issues/issue-98156-const-arg-temp-lifetime.rs27
-rw-r--r--tests/codegen/issues/issue-98294-get-mut-copy-from-slice-opt.rs19
39 files changed, 1061 insertions, 0 deletions
diff --git a/tests/codegen/issues/issue-103285-ptr-addr-overflow-check.rs b/tests/codegen/issues/issue-103285-ptr-addr-overflow-check.rs
new file mode 100644
index 00000000000..a3499babea2
--- /dev/null
+++ b/tests/codegen/issues/issue-103285-ptr-addr-overflow-check.rs
@@ -0,0 +1,16 @@
+// compile-flags: -O -C debug-assertions=yes
+
+#![crate_type = "lib"]
+#![feature(strict_provenance)]
+
+#[no_mangle]
+pub fn test(src: *const u8, dst: *const u8) -> usize {
+    // CHECK-LABEL: @test(
+    // CHECK-NOT: panic
+    let src_usize = src.addr();
+    let dst_usize = dst.addr();
+    if src_usize > dst_usize {
+        return src_usize - dst_usize;
+    }
+    return 0;
+}
diff --git a/tests/codegen/issues/issue-103840.rs b/tests/codegen/issues/issue-103840.rs
new file mode 100644
index 00000000000..f19d7031bb3
--- /dev/null
+++ b/tests/codegen/issues/issue-103840.rs
@@ -0,0 +1,9 @@
+// compile-flags: -O
+#![crate_type = "lib"]
+
+pub fn foo(t: &mut Vec<usize>) {
+    // CHECK-NOT: __rust_dealloc
+    let mut taken = std::mem::take(t);
+    taken.pop();
+    *t = taken;
+}
diff --git a/tests/codegen/issues/issue-105386-ub-in-debuginfo.rs b/tests/codegen/issues/issue-105386-ub-in-debuginfo.rs
new file mode 100644
index 00000000000..d54ac9e33bc
--- /dev/null
+++ b/tests/codegen/issues/issue-105386-ub-in-debuginfo.rs
@@ -0,0 +1,22 @@
+// compile-flags: --crate-type=lib -O -Cdebuginfo=2 -Cno-prepopulate-passes
+// min-llvm-version: 15.0 # this test uses opaque pointer notation
+#![feature(stmt_expr_attributes)]
+
+pub struct S([usize; 8]);
+
+#[no_mangle]
+pub fn outer_function(x: S, y: S) -> usize {
+    (#[inline(always)]|| {
+        let _z = x;
+        y.0[0]
+    })()
+}
+
+// Check that we do not attempt to load from the spilled arg before it is assigned to
+// when generating debuginfo.
+// CHECK-LABEL: @outer_function
+// CHECK: [[spill:%.*]] = alloca %"[closure@{{.*.rs}}:9:23: 9:25]"
+// CHECK-NOT: [[ptr_tmp:%.*]] = getelementptr inbounds %"[closure@{{.*.rs}}:9:23: 9:25]", ptr [[spill]]
+// CHECK-NOT: [[load:%.*]] = load ptr, ptr
+// CHECK: call void @llvm.lifetime.start{{.*}}({{.*}}, ptr [[spill]])
+// CHECK: call void @llvm.memcpy{{.*}}(ptr {{align .*}} [[spill]], ptr {{align .*}} %x
diff --git a/tests/codegen/issues/issue-13018.rs b/tests/codegen/issues/issue-13018.rs
new file mode 100644
index 00000000000..b70ea1f48c8
--- /dev/null
+++ b/tests/codegen/issues/issue-13018.rs
@@ -0,0 +1,11 @@
+// compile-flags: -O
+
+// A drop([...].clone()) sequence on an Rc should be a no-op
+// In particular, no call to __rust_dealloc should be emitted
+#![crate_type = "lib"]
+use std::rc::Rc;
+
+pub fn foo(t: &Rc<Vec<usize>>) {
+// CHECK-NOT: __rust_dealloc
+    drop(t.clone());
+}
diff --git a/tests/codegen/issues/issue-15953.rs b/tests/codegen/issues/issue-15953.rs
new file mode 100644
index 00000000000..28d28428904
--- /dev/null
+++ b/tests/codegen/issues/issue-15953.rs
@@ -0,0 +1,29 @@
+// Test that llvm generates `memcpy` for moving a value
+// inside a function and moving an argument.
+
+struct Foo {
+    x: Vec<i32>,
+}
+
+#[inline(never)]
+#[no_mangle]
+// CHECK: memcpy
+fn interior(x: Vec<i32>) -> Vec<i32> {
+    let Foo { x } = Foo { x: x };
+    x
+}
+
+#[inline(never)]
+#[no_mangle]
+// CHECK: memcpy
+fn exterior(x: Vec<i32>) -> Vec<i32> {
+    x
+}
+
+fn main() {
+    let x = interior(Vec::new());
+    println!("{:?}", x);
+
+    let x = exterior(Vec::new());
+    println!("{:?}", x);
+}
diff --git a/tests/codegen/issues/issue-27130.rs b/tests/codegen/issues/issue-27130.rs
new file mode 100644
index 00000000000..e5ee94e1f45
--- /dev/null
+++ b/tests/codegen/issues/issue-27130.rs
@@ -0,0 +1,21 @@
+// compile-flags: -O
+
+#![crate_type = "lib"]
+
+// CHECK-LABEL: @trim_in_place
+#[no_mangle]
+pub fn trim_in_place(a: &mut &[u8]) {
+    while a.first() == Some(&42) {
+        // CHECK-NOT: slice_index_order_fail
+        *a = &a[1..];
+    }
+}
+
+// CHECK-LABEL: @trim_in_place2
+#[no_mangle]
+pub fn trim_in_place2(a: &mut &[u8]) {
+    while let Some(&42) = a.first() {
+        // CHECK-NOT: slice_index_order_fail
+        *a = &a[2..];
+    }
+}
diff --git a/tests/codegen/issues/issue-32031.rs b/tests/codegen/issues/issue-32031.rs
new file mode 100644
index 00000000000..abef92c19b6
--- /dev/null
+++ b/tests/codegen/issues/issue-32031.rs
@@ -0,0 +1,23 @@
+// compile-flags: -C no-prepopulate-passes -Copt-level=0
+
+#![crate_type = "lib"]
+
+#[no_mangle]
+pub struct F32(f32);
+
+// CHECK: define{{.*}}float @add_newtype_f32(float %a, float %b)
+#[inline(never)]
+#[no_mangle]
+pub fn add_newtype_f32(a: F32, b: F32) -> F32 {
+    F32(a.0 + b.0)
+}
+
+#[no_mangle]
+pub struct F64(f64);
+
+// CHECK: define{{.*}}double @add_newtype_f64(double %a, double %b)
+#[inline(never)]
+#[no_mangle]
+pub fn add_newtype_f64(a: F64, b: F64) -> F64 {
+    F64(a.0 + b.0)
+}
diff --git a/tests/codegen/issues/issue-32364.rs b/tests/codegen/issues/issue-32364.rs
new file mode 100644
index 00000000000..85493a4bb73
--- /dev/null
+++ b/tests/codegen/issues/issue-32364.rs
@@ -0,0 +1,18 @@
+// Test that `extern "stdcall"` is properly translated.
+
+// only-x86
+
+// compile-flags: -C no-prepopulate-passes
+
+struct Foo;
+
+impl Foo {
+// CHECK: define internal x86_stdcallcc void @{{.*}}foo{{.*}}()
+    #[inline(never)]
+    pub extern "stdcall" fn foo<T>() {
+    }
+}
+
+fn main() {
+    Foo::foo::<Foo>();
+}
diff --git a/tests/codegen/issues/issue-34634.rs b/tests/codegen/issues/issue-34634.rs
new file mode 100644
index 00000000000..f53fa240cd1
--- /dev/null
+++ b/tests/codegen/issues/issue-34634.rs
@@ -0,0 +1,16 @@
+// Test that `wrapping_div` only checks divisor once.
+// This test checks that there is only a single compare against -1 and -1 is not present as a
+// switch case (the second check present until rustc 1.12).
+// This test also verifies that a single panic call is generated (for the division by zero case).
+
+// compile-flags: -O
+#![crate_type = "lib"]
+
+// CHECK-LABEL: @f
+#[no_mangle]
+pub fn f(x: i32, y: i32) -> i32 {
+    // CHECK-COUNT-1: icmp eq i32 %y, -1
+    // CHECK-COUNT-1: panic
+    // CHECK-NOT: i32 -1, label
+    x.wrapping_div(y)
+}
diff --git a/tests/codegen/issues/issue-34947-pow-i32.rs b/tests/codegen/issues/issue-34947-pow-i32.rs
new file mode 100644
index 00000000000..653da8e8b5f
--- /dev/null
+++ b/tests/codegen/issues/issue-34947-pow-i32.rs
@@ -0,0 +1,13 @@
+// compile-flags: -O
+
+#![crate_type = "lib"]
+
+// CHECK-LABEL: @issue_34947
+#[no_mangle]
+pub fn issue_34947(x: i32) -> i32 {
+    // CHECK: mul
+    // CHECK-NEXT: mul
+    // CHECK-NEXT: mul
+    // CHECK-NEXT: ret
+    x.pow(5)
+}
diff --git a/tests/codegen/issues/issue-37945.rs b/tests/codegen/issues/issue-37945.rs
new file mode 100644
index 00000000000..fe54375bbf6
--- /dev/null
+++ b/tests/codegen/issues/issue-37945.rs
@@ -0,0 +1,38 @@
+// compile-flags: -O -Zmerge-functions=disabled
+// ignore-x86
+// ignore-arm
+// ignore-emscripten
+// ignore-gnux32
+// ignore 32-bit platforms (LLVM has a bug with them)
+
+// Check that LLVM understands that `Iter` pointer is not null. Issue #37945.
+
+#![crate_type = "lib"]
+
+use std::slice::Iter;
+
+#[no_mangle]
+pub fn is_empty_1(xs: Iter<f32>) -> bool {
+// CHECK-LABEL: @is_empty_1(
+// CHECK-NEXT:  start:
+// CHECK-NEXT:    [[A:%.*]] = icmp ne {{i32\*|ptr}} {{%xs.0|%xs.1}}, null
+// CHECK-NEXT:    tail call void @llvm.assume(i1 [[A]])
+// The order between %xs.0 and %xs.1 on the next line doesn't matter
+// and different LLVM versions produce different order.
+// CHECK-NEXT:    [[B:%.*]] = icmp eq {{i32\*|ptr}} {{%xs.0, %xs.1|%xs.1, %xs.0}}
+// CHECK-NEXT:    ret i1 [[B:%.*]]
+    {xs}.next().is_none()
+}
+
+#[no_mangle]
+pub fn is_empty_2(xs: Iter<f32>) -> bool {
+// CHECK-LABEL: @is_empty_2
+// CHECK-NEXT:  start:
+// CHECK-NEXT:    [[C:%.*]] = icmp ne {{i32\*|ptr}} {{%xs.0|%xs.1}}, null
+// CHECK-NEXT:    tail call void @llvm.assume(i1 [[C]])
+// The order between %xs.0 and %xs.1 on the next line doesn't matter
+// and different LLVM versions produce different order.
+// CHECK-NEXT:    [[D:%.*]] = icmp eq {{i32\*|ptr}} {{%xs.0, %xs.1|%xs.1, %xs.0}}
+// CHECK-NEXT:    ret i1 [[D:%.*]]
+    xs.map(|&x| x).next().is_none()
+}
diff --git a/tests/codegen/issues/issue-44056-macos-tls-align.rs b/tests/codegen/issues/issue-44056-macos-tls-align.rs
new file mode 100644
index 00000000000..1a3923f1bb1
--- /dev/null
+++ b/tests/codegen/issues/issue-44056-macos-tls-align.rs
@@ -0,0 +1,28 @@
+//
+// only-macos
+// no-system-llvm
+// compile-flags: -O
+
+#![crate_type = "rlib"]
+#![feature(thread_local)]
+
+// local_unnamed_addr does not appear when std is built with debug assertions.
+// CHECK: @STATIC_VAR_1 = thread_local {{(local_unnamed_addr )?}}global <{ [32 x i8] }> zeroinitializer, section "__DATA,__thread_bss", align 4
+#[no_mangle]
+#[thread_local]
+static mut STATIC_VAR_1: [u32; 8] = [0; 8];
+
+// CHECK: @STATIC_VAR_2 = thread_local {{(local_unnamed_addr )?}}global <{ [32 x i8] }> <{{[^>]*}}>, section "__DATA,__thread_data", align 4
+#[no_mangle]
+#[thread_local]
+static mut STATIC_VAR_2: [u32; 8] = [4; 8];
+
+#[no_mangle]
+pub unsafe fn f(x: &mut [u32; 8]) {
+    std::mem::swap(x, &mut STATIC_VAR_1)
+}
+
+#[no_mangle]
+pub unsafe fn g(x: &mut [u32; 8]) {
+    std::mem::swap(x, &mut STATIC_VAR_2)
+}
diff --git a/tests/codegen/issues/issue-45222.rs b/tests/codegen/issues/issue-45222.rs
new file mode 100644
index 00000000000..e9b05e648b4
--- /dev/null
+++ b/tests/codegen/issues/issue-45222.rs
@@ -0,0 +1,63 @@
+// compile-flags: -O
+// ignore-debug: the debug assertions get in the way
+
+#![crate_type = "lib"]
+
+// verify that LLVM recognizes a loop involving 0..=n and will const-fold it.
+
+// Example from original issue #45222
+
+fn foo2(n: u64) -> u64 {
+    let mut count = 0;
+    for _ in 0..n {
+        for j in (0..=n).rev() {
+            count += j;
+        }
+    }
+    count
+}
+
+// CHECK-LABEL: @check_foo2
+#[no_mangle]
+pub fn check_foo2() -> u64 {
+    // CHECK: ret i64 500005000000000
+    foo2(100000)
+}
+
+// Simplified example of #45222
+//
+// Temporarily disabled in #68835 to fix a soundness hole.
+//
+// fn triangle_inc(n: u64) -> u64 {
+//     let mut count = 0;
+//     for j in 0 ..= n {
+//         count += j;
+//     }
+//     count
+// }
+//
+// // COMMENTEDCHECK-LABEL: @check_triangle_inc
+// #[no_mangle]
+// pub fn check_triangle_inc() -> u64 {
+//     // COMMENTEDCHECK: ret i64 5000050000
+//     triangle_inc(100000)
+// }
+
+// Demo in #48012
+
+fn foo3r(n: u64) -> u64 {
+    let mut count = 0;
+    (0..n).for_each(|_| {
+        (0..=n).rev().for_each(|j| {
+            count += j;
+        })
+    });
+    count
+}
+
+// CHECK-LABEL: @check_foo3r
+#[no_mangle]
+pub fn check_foo3r() -> u64 {
+    // CHECK: ret i64 500050000000
+    foo3r(10000)
+}
diff --git a/tests/codegen/issues/issue-45466.rs b/tests/codegen/issues/issue-45466.rs
new file mode 100644
index 00000000000..c7954276777
--- /dev/null
+++ b/tests/codegen/issues/issue-45466.rs
@@ -0,0 +1,15 @@
+// compile-flags: -O
+// ignore-debug: the debug assertions get in the way
+
+#![crate_type="rlib"]
+
+// CHECK-LABEL: @memzero
+// CHECK-NOT: store
+// CHECK: call void @llvm.memset
+// CHECK-NOT: store
+#[no_mangle]
+pub fn memzero(data: &mut [u8]) {
+    for i in 0..data.len() {
+        data[i] = 0;
+    }
+}
diff --git a/tests/codegen/issues/issue-45964-bounds-check-slice-pos.rs b/tests/codegen/issues/issue-45964-bounds-check-slice-pos.rs
new file mode 100644
index 00000000000..1daa213fc82
--- /dev/null
+++ b/tests/codegen/issues/issue-45964-bounds-check-slice-pos.rs
@@ -0,0 +1,39 @@
+// This test case checks that slice::{r}position functions do not
+// prevent optimizing away bounds checks
+
+// compile-flags: -O
+// ignore-debug: the debug assertions get in the way
+
+#![crate_type="rlib"]
+
+// CHECK-LABEL: @test
+#[no_mangle]
+pub fn test(y: &[u32], x: &u32, z: &u32) -> bool {
+    let result = match y.iter().position(|a| a == x) {
+        Some(p) => Ok(p),
+        None => Err(()),
+    };
+
+    if let Ok(p) = result {
+        // CHECK-NOT: panic
+        y[p] == *z
+    } else {
+        false
+    }
+}
+
+// CHECK-LABEL: @rtest
+#[no_mangle]
+pub fn rtest(y: &[u32], x: &u32, z: &u32) -> bool {
+    let result = match y.iter().rposition(|a| a == x) {
+        Some(p) => Ok(p),
+        None => Err(()),
+    };
+
+    if let Ok(p) = result {
+        // CHECK-NOT: panic
+        y[p] == *z
+    } else {
+        false
+    }
+}
diff --git a/tests/codegen/issues/issue-47278.rs b/tests/codegen/issues/issue-47278.rs
new file mode 100644
index 00000000000..9076274f45e
--- /dev/null
+++ b/tests/codegen/issues/issue-47278.rs
@@ -0,0 +1,9 @@
+// -C no-prepopulate-passes
+#![crate_type="staticlib"]
+
+#[repr(C)]
+pub struct Foo(u64);
+
+// CHECK: define {{.*}} @foo(
+#[no_mangle]
+pub extern "C" fn foo(_: Foo) -> Foo { loop {} }
diff --git a/tests/codegen/issues/issue-47442.rs b/tests/codegen/issues/issue-47442.rs
new file mode 100644
index 00000000000..6944336d335
--- /dev/null
+++ b/tests/codegen/issues/issue-47442.rs
@@ -0,0 +1,22 @@
+// check that we don't emit unneeded `resume` cleanup blocks for every
+// destructor.
+
+// CHECK-NOT: Unwind
+
+#![feature(test)]
+#![crate_type="rlib"]
+
+extern crate test;
+
+struct Foo {}
+
+impl Drop for Foo {
+    fn drop(&mut self) {
+        test::black_box(());
+    }
+}
+
+#[no_mangle]
+pub fn foo() {
+    let _foo = Foo {};
+}
diff --git a/tests/codegen/issues/issue-56267-2.rs b/tests/codegen/issues/issue-56267-2.rs
new file mode 100644
index 00000000000..4dc9ebfebbc
--- /dev/null
+++ b/tests/codegen/issues/issue-56267-2.rs
@@ -0,0 +1,18 @@
+// compile-flags: -C no-prepopulate-passes
+
+#![crate_type="rlib"]
+
+#[allow(dead_code)]
+pub struct Foo<T> {
+    foo: u64,
+    bar: T,
+}
+
+// The load from bar.1 should have alignment 4. Not checking
+// other loads here, as the alignment will be platform-dependent.
+
+// CHECK: %{{.+}} = load i32, {{i32\*|ptr}} %{{.+}}, align 4
+#[no_mangle]
+pub fn test(x: Foo<(i32, i32)>) -> (i32, i32) {
+    x.bar
+}
diff --git a/tests/codegen/issues/issue-56267.rs b/tests/codegen/issues/issue-56267.rs
new file mode 100644
index 00000000000..7bdd2577998
--- /dev/null
+++ b/tests/codegen/issues/issue-56267.rs
@@ -0,0 +1,18 @@
+// compile-flags: -C no-prepopulate-passes
+
+#![crate_type="rlib"]
+
+#[allow(dead_code)]
+pub struct Foo<T> {
+    foo: u64,
+    bar: T,
+}
+
+// The store writing to bar.1 should have alignment 4. Not checking
+// other stores here, as the alignment will be platform-dependent.
+
+// CHECK: store i32 [[TMP1:%.+]], {{i32\*|ptr}} [[TMP2:%.+]], align 4
+#[no_mangle]
+pub fn test(x: (i32, i32)) -> Foo<(i32, i32)> {
+    Foo { foo: 0, bar: x }
+}
diff --git a/tests/codegen/issues/issue-56927.rs b/tests/codegen/issues/issue-56927.rs
new file mode 100644
index 00000000000..044d721814b
--- /dev/null
+++ b/tests/codegen/issues/issue-56927.rs
@@ -0,0 +1,43 @@
+// compile-flags: -C no-prepopulate-passes
+
+#![crate_type="rlib"]
+
+#[repr(align(16))]
+pub struct S {
+    arr: [u32; 4],
+}
+
+// CHECK-LABEL: @test1
+// CHECK: store i32 0, {{i32\*|ptr}} %{{.+}}, align 16
+// CHECK: store i32 1, {{i32\*|ptr}} %{{.+}}, align 4
+// CHECK: store i32 2, {{i32\*|ptr}} %{{.+}}, align 8
+// CHECK: store i32 3, {{i32\*|ptr}} %{{.+}}, align 4
+#[no_mangle]
+pub fn test1(s: &mut S) {
+    s.arr[0] = 0;
+    s.arr[1] = 1;
+    s.arr[2] = 2;
+    s.arr[3] = 3;
+}
+
+// CHECK-LABEL: @test2
+// CHECK: store i32 4, {{i32\*|ptr}} %{{.+}}, align 4
+#[allow(unconditional_panic)]
+#[no_mangle]
+pub fn test2(s: &mut S) {
+    s.arr[usize::MAX / 4 + 1] = 4;
+}
+
+// CHECK-LABEL: @test3
+// CHECK: store i32 5, {{i32\*|ptr}} %{{.+}}, align 4
+#[no_mangle]
+pub fn test3(s: &mut S, i: usize) {
+    s.arr[i] = 5;
+}
+
+// CHECK-LABEL: @test4
+// CHECK: store i32 6, {{i32\*|ptr}} %{{.+}}, align 4
+#[no_mangle]
+pub fn test4(s: &mut S) {
+    s.arr = [6; 4];
+}
diff --git a/tests/codegen/issues/issue-58881.rs b/tests/codegen/issues/issue-58881.rs
new file mode 100644
index 00000000000..00f8953d949
--- /dev/null
+++ b/tests/codegen/issues/issue-58881.rs
@@ -0,0 +1,21 @@
+// compile-flags: -C no-prepopulate-passes -Copt-level=0
+//
+// only-x86_64
+// ignore-windows
+
+#![crate_type = "lib"]
+
+extern "C" {
+    fn variadic_fn(_: i32, ...);
+}
+
+#[repr(C)]
+struct Foo(u8);
+#[repr(C)]
+struct Bar(u64, u64, u64);
+
+// Ensure that emit arguments of the correct type.
+pub unsafe fn test_call_variadic() {
+    // CHECK: call void (i32, ...) @variadic_fn(i32 0, i8 {{.*}}, {{%Bar\*|ptr}} {{.*}})
+    variadic_fn(0, Foo(0), Bar(0, 0, 0))
+}
diff --git a/tests/codegen/issues/issue-59352.rs b/tests/codegen/issues/issue-59352.rs
new file mode 100644
index 00000000000..d271fe027e3
--- /dev/null
+++ b/tests/codegen/issues/issue-59352.rs
@@ -0,0 +1,18 @@
+// This test is a mirror of mir-opt/issues/issue-59352.rs. The LLVM inliner doesn't inline
+// `char::method::is_digit()` and `char::method::to_digit()`, probably because of their size.
+//
+// Currently, the MIR optimizer isn't capable of removing the unreachable panic in this test case.
+// Once the optimizer can do that, mir-opt/issues/issue-59352.rs will need to be updated and this
+// test case should be removed as it will become redundant.
+
+// mir-opt-level=3 enables inlining and enables LLVM to optimize away the unreachable panic call.
+// compile-flags: -O -Z mir-opt-level=3
+
+#![crate_type = "rlib"]
+
+// CHECK-LABEL: @num_to_digit
+#[no_mangle]
+pub fn num_to_digit(num: char) -> u32 {
+    // CHECK-NOT: panic
+    if num.is_digit(8) { num.to_digit(8).unwrap() } else { 0 }
+}
diff --git a/tests/codegen/issues/issue-69101-bounds-check.rs b/tests/codegen/issues/issue-69101-bounds-check.rs
new file mode 100644
index 00000000000..a3aca3a2912
--- /dev/null
+++ b/tests/codegen/issues/issue-69101-bounds-check.rs
@@ -0,0 +1,44 @@
+// no-system-llvm
+// compile-flags: -O
+// ignore-debug: the debug assertions get in the way
+#![crate_type = "lib"]
+
+// Make sure no bounds checks are emitted in the loop when upfront slicing
+// ensures that the slices are big enough.
+// In particular, bounds checks were not always optimized out if the upfront
+// check was for a greater len than the loop requires.
+// (i.e. `already_sliced_no_bounds_check` was not always optimized even when
+// `already_sliced_no_bounds_check_exact` was)
+// CHECK-LABEL: @already_sliced_no_bounds_check
+#[no_mangle]
+pub fn already_sliced_no_bounds_check(a: &[u8], b: &[u8], c: &mut [u8]) {
+    // CHECK: slice_end_index_len_fail
+    // CHECK-NOT: panic_bounds_check
+    let _ = (&a[..2048], &b[..2048], &mut c[..2048]);
+    for i in 0..1024 {
+        c[i] = a[i] ^ b[i];
+    }
+}
+
+// CHECK-LABEL: @already_sliced_no_bounds_check_exact
+#[no_mangle]
+pub fn already_sliced_no_bounds_check_exact(a: &[u8], b: &[u8], c: &mut [u8]) {
+    // CHECK: slice_end_index_len_fail
+    // CHECK-NOT: panic_bounds_check
+    let _ = (&a[..1024], &b[..1024], &mut c[..1024]);
+    for i in 0..1024 {
+        c[i] = a[i] ^ b[i];
+    }
+}
+
+// Make sure we're checking for the right thing: there can be a panic if the slice is too small.
+// CHECK-LABEL: @already_sliced_bounds_check
+#[no_mangle]
+pub fn already_sliced_bounds_check(a: &[u8], b: &[u8], c: &mut [u8]) {
+    // CHECK: slice_end_index_len_fail
+    // CHECK: panic_bounds_check
+    let _ = (&a[..1023], &b[..2048], &mut c[..2048]);
+    for i in 0..1024 {
+        c[i] = a[i] ^ b[i];
+    }
+}
diff --git a/tests/codegen/issues/issue-73031.rs b/tests/codegen/issues/issue-73031.rs
new file mode 100644
index 00000000000..a09c4bcfbea
--- /dev/null
+++ b/tests/codegen/issues/issue-73031.rs
@@ -0,0 +1,26 @@
+// compile-flags: -O
+#![crate_type = "lib"]
+
+// Test that LLVM can eliminate the unreachable `All::None` branch.
+
+pub enum All {
+    None,
+    Foo,
+    Bar,
+}
+
+// CHECK-LABEL: @issue_73031
+#[no_mangle]
+pub fn issue_73031(a: &mut All, q: i32) -> i32 {
+    *a = if q == 5 {
+        All::Foo
+    } else {
+        All::Bar
+    };
+    match *a {
+        // CHECK-NOT: panic
+        All::None => panic!(),
+        All::Foo => 1,
+        All::Bar => 2,
+    }
+}
diff --git a/tests/codegen/issues/issue-73338-effecient-cmp.rs b/tests/codegen/issues/issue-73338-effecient-cmp.rs
new file mode 100644
index 00000000000..85c2bbfd040
--- /dev/null
+++ b/tests/codegen/issues/issue-73338-effecient-cmp.rs
@@ -0,0 +1,39 @@
+// This test checks that comparison operation
+// generated by #[derive(PartialOrd)]
+// doesn't contain jumps for C enums
+
+// compile-flags: -Copt-level=3
+
+#![crate_type="lib"]
+
+#[repr(u32)]
+#[derive(Copy, Clone, Eq, PartialEq, PartialOrd)]
+pub enum Foo {
+    Zero,
+    One,
+    Two,
+}
+
+#[no_mangle]
+pub fn compare_less(a: Foo, b: Foo)->bool{
+    // CHECK-NOT: br {{.*}}
+    a < b
+}
+
+#[no_mangle]
+pub fn compare_le(a: Foo, b: Foo)->bool{
+    // CHECK-NOT: br {{.*}}
+    a <= b
+}
+
+#[no_mangle]
+pub fn compare_ge(a: Foo, b: Foo)->bool{
+    // CHECK-NOT: br {{.*}}
+    a >= b
+}
+
+#[no_mangle]
+pub fn compare_greater(a: Foo, b: Foo)->bool{
+    // CHECK-NOT: br {{.*}}
+    a > b
+}
diff --git a/tests/codegen/issues/issue-73396-bounds-check-after-position.rs b/tests/codegen/issues/issue-73396-bounds-check-after-position.rs
new file mode 100644
index 00000000000..8d07a67a1b4
--- /dev/null
+++ b/tests/codegen/issues/issue-73396-bounds-check-after-position.rs
@@ -0,0 +1,77 @@
+// compile-flags: -O
+// ignore-debug: the debug assertions get in the way
+#![crate_type = "lib"]
+
+// Make sure no bounds checks are emitted when slicing or indexing
+// with an index from `position()` or `rposition()`.
+
+// CHECK-LABEL: @position_slice_to_no_bounds_check
+#[no_mangle]
+pub fn position_slice_to_no_bounds_check(s: &[u8]) -> &[u8] {
+    // CHECK-NOT: panic
+    // CHECK-NOT: slice_index_len_fail
+    if let Some(idx) = s.iter().position(|b| *b == b'\\') {
+        &s[..idx]
+    } else {
+        s
+    }
+}
+
+// CHECK-LABEL: @position_slice_from_no_bounds_check
+#[no_mangle]
+pub fn position_slice_from_no_bounds_check(s: &[u8]) -> &[u8] {
+    // CHECK-NOT: panic
+    // CHECK-NOT: slice_index_len_fail
+    if let Some(idx) = s.iter().position(|b| *b == b'\\') {
+        &s[idx..]
+    } else {
+        s
+    }
+}
+
+// CHECK-LABEL: @position_index_no_bounds_check
+#[no_mangle]
+pub fn position_index_no_bounds_check(s: &[u8]) -> u8 {
+    // CHECK-NOT: panic
+    // CHECK-NOT: slice_index_len_fail
+    if let Some(idx) = s.iter().position(|b| *b == b'\\') {
+        s[idx]
+    } else {
+        42
+    }
+}
+// CHECK-LABEL: @rposition_slice_to_no_bounds_check
+#[no_mangle]
+pub fn rposition_slice_to_no_bounds_check(s: &[u8]) -> &[u8] {
+    // CHECK-NOT: panic
+    // CHECK-NOT: slice_index_len_fail
+    if let Some(idx) = s.iter().rposition(|b| *b == b'\\') {
+        &s[..idx]
+    } else {
+        s
+    }
+}
+
+// CHECK-LABEL: @rposition_slice_from_no_bounds_check
+#[no_mangle]
+pub fn rposition_slice_from_no_bounds_check(s: &[u8]) -> &[u8] {
+    // CHECK-NOT: panic
+    // CHECK-NOT: slice_index_len_fail
+    if let Some(idx) = s.iter().rposition(|b| *b == b'\\') {
+        &s[idx..]
+    } else {
+        s
+    }
+}
+
+// CHECK-LABEL: @rposition_index_no_bounds_check
+#[no_mangle]
+pub fn rposition_index_no_bounds_check(s: &[u8]) -> u8 {
+    // CHECK-NOT: panic
+    // CHECK-NOT: slice_index_len_fail
+    if let Some(idx) = s.iter().rposition(|b| *b == b'\\') {
+        s[idx]
+    } else {
+        42
+    }
+}
diff --git a/tests/codegen/issues/issue-73827-bounds-check-index-in-subexpr.rs b/tests/codegen/issues/issue-73827-bounds-check-index-in-subexpr.rs
new file mode 100644
index 00000000000..1ad05906e21
--- /dev/null
+++ b/tests/codegen/issues/issue-73827-bounds-check-index-in-subexpr.rs
@@ -0,0 +1,17 @@
+// This test checks that bounds checks are elided when
+// index is part of a (x | y) < C style condition
+
+// compile-flags: -O
+
+#![crate_type = "lib"]
+
+// CHECK-LABEL: @get
+#[no_mangle]
+pub fn get(array: &[u8; 8], x: usize, y: usize) -> u8 {
+    if x > 7 || y > 7 {
+        0
+    } else {
+        // CHECK-NOT: panic_bounds_check
+        array[y]
+    }
+}
diff --git a/tests/codegen/issues/issue-75525-bounds-checks.rs b/tests/codegen/issues/issue-75525-bounds-checks.rs
new file mode 100644
index 00000000000..2d363d8f73b
--- /dev/null
+++ b/tests/codegen/issues/issue-75525-bounds-checks.rs
@@ -0,0 +1,26 @@
+// Regression test for #75525, verifies that no bounds checks are generated.
+
+// compile-flags: -O
+
+#![crate_type = "lib"]
+
+// CHECK-LABEL: @f0
+// CHECK-NOT: panic
+#[no_mangle]
+pub fn f0(idx: usize, buf: &[u8; 10]) -> u8 {
+    if idx < 8 { buf[idx + 1] } else { 0 }
+}
+
+// CHECK-LABEL: @f1
+// CHECK-NOT: panic
+#[no_mangle]
+pub fn f1(idx: usize, buf: &[u8; 10]) -> u8 {
+    if idx > 5 && idx < 8 { buf[idx - 1] } else { 0 }
+}
+
+// CHECK-LABEL: @f2
+// CHECK-NOT: panic
+#[no_mangle]
+pub fn f2(idx: usize, buf: &[u8; 10]) -> u8 {
+    if idx > 5 && idx < 8 { buf[idx] } else { 0 }
+}
diff --git a/tests/codegen/issues/issue-75546.rs b/tests/codegen/issues/issue-75546.rs
new file mode 100644
index 00000000000..470a9e04096
--- /dev/null
+++ b/tests/codegen/issues/issue-75546.rs
@@ -0,0 +1,15 @@
+// compile-flags: -O
+#![crate_type = "lib"]
+
+// Test that LLVM can eliminate the impossible `i == 0` check.
+
+// CHECK-LABEL: @issue_75546
+#[no_mangle]
+pub fn issue_75546() {
+    let mut i = 1u32;
+    while i < u32::MAX {
+        // CHECK-NOT: panic
+        if i == 0 { panic!(); }
+        i += 1;
+    }
+}
diff --git a/tests/codegen/issues/issue-75659.rs b/tests/codegen/issues/issue-75659.rs
new file mode 100644
index 00000000000..9394868c08d
--- /dev/null
+++ b/tests/codegen/issues/issue-75659.rs
@@ -0,0 +1,63 @@
+// This test checks that the call to memchr/slice_contains is optimized away
+// when searching in small slices.
+
+// compile-flags: -O -Zinline-mir=false
+// only-x86_64
+
+#![crate_type = "lib"]
+
+// CHECK-LABEL: @foo1
+#[no_mangle]
+pub fn foo1(x: u8, data: &[u8; 1]) -> bool {
+    // CHECK-NOT: memchr
+    // CHECK-NOT: slice_contains
+    data.contains(&x)
+}
+
+// CHECK-LABEL: @foo2
+#[no_mangle]
+pub fn foo2(x: u8, data: &[u8; 2]) -> bool {
+    // CHECK-NOT: memchr
+    // CHECK-NOT: slice_contains
+    data.contains(&x)
+}
+
+// CHECK-LABEL: @foo3
+#[no_mangle]
+pub fn foo3(x: u8, data: &[u8; 3]) -> bool {
+    // CHECK-NOT: memchr
+    // CHECK-NOT: slice_contains
+    data.contains(&x)
+}
+
+// CHECK-LABEL: @foo4
+#[no_mangle]
+pub fn foo4(x: u8, data: &[u8; 4]) -> bool {
+    // CHECK-NOT: memchr
+    // CHECK-NOT: slice_contains
+    data.contains(&x)
+}
+
+// CHECK-LABEL: @foo8
+#[no_mangle]
+pub fn foo8(x: u8, data: &[u8; 8]) -> bool {
+    // CHECK-NOT: memchr
+    // CHECK-NOT: slice_contains
+    data.contains(&x)
+}
+
+// CHECK-LABEL: @foo8_i8
+#[no_mangle]
+pub fn foo8_i8(x: i8, data: &[i8; 8]) -> bool {
+    // CHECK-NOT: memchr
+    // CHECK-NOT: slice_contains
+    !data.contains(&x)
+}
+
+// Check that the general case isn't inlined
+// CHECK-LABEL: @foo80
+#[no_mangle]
+pub fn foo80(x: u8, data: &[u8; 80]) -> bool {
+    // CHECK: call core::slice::memchr
+    data.contains(&x)
+}
diff --git a/tests/codegen/issues/issue-77812.rs b/tests/codegen/issues/issue-77812.rs
new file mode 100644
index 00000000000..4cc82414546
--- /dev/null
+++ b/tests/codegen/issues/issue-77812.rs
@@ -0,0 +1,32 @@
+// compile-flags: -O
+#![crate_type = "lib"]
+
+// Test that LLVM can eliminate the unreachable `Variant::Zero` branch.
+
+#[derive(Copy, Clone, Eq, PartialEq)]
+pub enum Variant {
+    Zero,
+    One,
+    Two,
+}
+
+extern {
+    fn exf1();
+    fn exf2();
+}
+
+pub static mut GLOBAL: Variant = Variant::Zero;
+
+// CHECK-LABEL: @issue_77812
+#[no_mangle]
+pub unsafe fn issue_77812() {
+    let g = GLOBAL;
+    if g != Variant::Zero {
+        match g {
+            Variant::One => exf1(),
+            Variant::Two => exf2(),
+            // CHECK-NOT: panic
+            Variant::Zero => panic!(),
+        }
+    }
+}
diff --git a/tests/codegen/issues/issue-81408-dllimport-thinlto-windows.rs b/tests/codegen/issues/issue-81408-dllimport-thinlto-windows.rs
new file mode 100644
index 00000000000..0b6ab4f7ecb
--- /dev/null
+++ b/tests/codegen/issues/issue-81408-dllimport-thinlto-windows.rs
@@ -0,0 +1,15 @@
+// compile-flags: -O -C lto=thin -C prefer-dynamic=no
+// only-windows
+// aux-build:static_dllimport_aux.rs
+
+// Test that on Windows, when performing ThinLTO, we do not mark cross-crate static items with
+// dllimport because lld does not fix the symbol names for us.
+
+extern crate static_dllimport_aux;
+
+// CHECK-LABEL: @{{.+}}CROSS_CRATE_STATIC_ITEM{{.+}} =
+// CHECK-SAME: external local_unnamed_addr global %"{{.+}}AtomicPtr
+
+pub fn main() {
+    static_dllimport_aux::memrchr();
+}
diff --git a/tests/codegen/issues/issue-84268.rs b/tests/codegen/issues/issue-84268.rs
new file mode 100644
index 00000000000..7ca19544700
--- /dev/null
+++ b/tests/codegen/issues/issue-84268.rs
@@ -0,0 +1,23 @@
+// compile-flags: -O --crate-type=rlib
+#![feature(platform_intrinsics, repr_simd)]
+
+extern "platform-intrinsic" {
+    fn simd_fabs<T>(x: T) -> T;
+    fn simd_eq<T, U>(x: T, y: T) -> U;
+}
+
+#[repr(simd)]
+pub struct V([f32; 4]);
+
+#[repr(simd)]
+pub struct M([i32; 4]);
+
+#[no_mangle]
+// CHECK-LABEL: @is_infinite
+pub fn is_infinite(v: V) -> M {
+    // CHECK: fabs
+    // CHECK: cmp oeq
+    unsafe {
+        simd_eq(simd_fabs(v), V([f32::INFINITY; 4]))
+    }
+}
diff --git a/tests/codegen/issues/issue-85872-multiple-reverse.rs b/tests/codegen/issues/issue-85872-multiple-reverse.rs
new file mode 100644
index 00000000000..591a1aca747
--- /dev/null
+++ b/tests/codegen/issues/issue-85872-multiple-reverse.rs
@@ -0,0 +1,20 @@
+// min-llvm-version: 15.0.0
+// compile-flags: -O
+
+#![crate_type = "lib"]
+
+#[no_mangle]
+pub fn u16_be_to_arch(mut data: [u8; 2]) -> [u8; 2] {
+    // CHECK-LABEL: @u16_be_to_arch
+    // CHECK: @llvm.bswap.i16
+    data.reverse();
+    data
+}
+
+#[no_mangle]
+pub fn u32_be_to_arch(mut data: [u8; 4]) -> [u8; 4] {
+    // CHECK-LABEL: @u32_be_to_arch
+    // CHECK: @llvm.bswap.i32
+    data.reverse();
+    data
+}
diff --git a/tests/codegen/issues/issue-86106.rs b/tests/codegen/issues/issue-86106.rs
new file mode 100644
index 00000000000..9ccbcb24f56
--- /dev/null
+++ b/tests/codegen/issues/issue-86106.rs
@@ -0,0 +1,62 @@
+// min-llvm-version: 15.0
+// compile-flags: -C opt-level=3 -Z merge-functions=disabled
+
+// The below two functions ensure that both `String::new()` and `"".to_string()`
+// produce the identical code.
+
+#![crate_type = "lib"]
+
+// CHECK-LABEL: define void @string_new
+#[no_mangle]
+pub fn string_new() -> String {
+    // CHECK-NOT: load i8
+    // CHECK: store i{{32|64}}
+    // CHECK-NEXT: getelementptr
+    // CHECK-NEXT: store ptr
+    // CHECK-NEXT: getelementptr
+    // CHECK-NEXT: store i{{32|64}}
+    // CHECK-NEXT: ret void
+    String::new()
+}
+
+// CHECK-LABEL: define void @empty_to_string
+#[no_mangle]
+pub fn empty_to_string() -> String {
+    // CHECK-NOT: load i8
+    // CHECK: store i{{32|64}}
+    // CHECK-NEXT: getelementptr
+    // CHECK-NEXT: store ptr
+    // CHECK-NEXT: getelementptr
+    // CHECK-NEXT: store i{{32|64}}
+    // CHECK-NEXT: ret void
+    "".to_string()
+}
+
+// The below two functions ensure that both `vec![]` and `vec![].clone()`
+// produce the identical code.
+
+// CHECK-LABEL: @empty_vec
+#[no_mangle]
+pub fn empty_vec() -> Vec<u8> {
+    // CHECK: store i{{32|64}}
+    // CHECK-NOT: load i8
+    // CHECK-NEXT: getelementptr
+    // CHECK-NEXT: store ptr
+    // CHECK-NEXT: getelementptr
+    // CHECK-NEXT: store i{{32|64}}
+    // CHECK-NEXT: ret void
+    vec![]
+}
+
+// CHECK-LABEL: @empty_vec_clone
+#[no_mangle]
+pub fn empty_vec_clone() -> Vec<u8> {
+    // CHECK: store i{{32|64}}
+    // CHECK-NOT: load i8
+    // CHECK-NEXT: getelementptr
+    // CHECK-NEXT: store ptr
+    // CHECK-NEXT: getelementptr
+    // CHECK-NEXT: store i{{32|64}}
+    // CHECK-NEXT: ret void
+    vec![].clone()
+}
diff --git a/tests/codegen/issues/issue-96274.rs b/tests/codegen/issues/issue-96274.rs
new file mode 100644
index 00000000000..28bfcce0d7b
--- /dev/null
+++ b/tests/codegen/issues/issue-96274.rs
@@ -0,0 +1,17 @@
+// min-llvm-version: 15.0
+// compile-flags: -O
+
+#![crate_type = "lib"]
+#![feature(inline_const)]
+
+use std::mem::MaybeUninit;
+
+pub fn maybe_uninit() -> [MaybeUninit<u8>; 3000] {
+    // CHECK-NOT: memset
+    [MaybeUninit::uninit(); 3000]
+}
+
+pub fn maybe_uninit_const<T>() -> [MaybeUninit<T>; 8192] {
+    // CHECK-NOT: memset
+    [const { MaybeUninit::uninit() }; 8192]
+}
diff --git a/tests/codegen/issues/issue-96497-slice-size-nowrap.rs b/tests/codegen/issues/issue-96497-slice-size-nowrap.rs
new file mode 100644
index 00000000000..0413ed6b26f
--- /dev/null
+++ b/tests/codegen/issues/issue-96497-slice-size-nowrap.rs
@@ -0,0 +1,29 @@
+// This test case checks that LLVM is aware that computing the size of a slice cannot wrap.
+// The possibility of wrapping results in an additional branch when dropping boxed slices
+// in some situations, see https://github.com/rust-lang/rust/issues/96497#issuecomment-1112865218
+
+// compile-flags: -O
+// min-llvm-version: 15.0
+
+#![crate_type="lib"]
+
+// CHECK-LABEL: @simple_size_of_nowrap
+#[no_mangle]
+pub fn simple_size_of_nowrap(x: &[u32]) -> usize {
+    // Make sure the shift used to compute the size has a nowrap flag.
+
+    // CHECK: [[A:%.*]] = shl nsw {{.*}}, 2
+    // CHECK-NEXT: ret {{.*}} [[A]]
+    core::mem::size_of_val(x)
+}
+
+// CHECK-LABEL: @drop_write
+#[no_mangle]
+pub fn drop_write(mut x: Box<[u32]>) {
+    // Check that this write is optimized out.
+    // This depends on the size calculation not wrapping,
+    // since otherwise LLVM can't tell that the memory is always deallocated if the slice len > 0.
+
+    // CHECK-NOT: store i32 42
+    x[1] = 42;
+}
diff --git a/tests/codegen/issues/issue-98156-const-arg-temp-lifetime.rs b/tests/codegen/issues/issue-98156-const-arg-temp-lifetime.rs
new file mode 100644
index 00000000000..12ace5fff6b
--- /dev/null
+++ b/tests/codegen/issues/issue-98156-const-arg-temp-lifetime.rs
@@ -0,0 +1,27 @@
+// This test checks that temporaries for indirectly-passed arguments get lifetime markers.
+
+// compile-flags: -O -C no-prepopulate-passes -Zmir-opt-level=0
+
+#![crate_type = "lib"]
+
+extern "Rust" {
+    fn f(x: [u8; 1024]);
+}
+
+const A: [u8; 1024] = [0; 1024];
+
+// CHECK-LABEL: @const_arg_indirect
+#[no_mangle]
+pub unsafe fn const_arg_indirect() {
+    // Ensure that the live ranges for the two argument temporaries don't overlap.
+
+    // CHECK: call void @llvm.lifetime.start
+    // CHECK: call void @f
+    // CHECK: call void @llvm.lifetime.end
+    // CHECK: call void @llvm.lifetime.start
+    // CHECK: call void @f
+    // CHECK: call void @llvm.lifetime.end
+
+    f(A);
+    f(A);
+}
diff --git a/tests/codegen/issues/issue-98294-get-mut-copy-from-slice-opt.rs b/tests/codegen/issues/issue-98294-get-mut-copy-from-slice-opt.rs
new file mode 100644
index 00000000000..7da29cd7952
--- /dev/null
+++ b/tests/codegen/issues/issue-98294-get-mut-copy-from-slice-opt.rs
@@ -0,0 +1,19 @@
+// min-llvm-version: 15.0.0
+// ignore-debug: The debug assertions get in the way
+// compile-flags: -O
+
+#![crate_type = "lib"]
+
+// There should be no calls to panic / len_mismatch_fail.
+
+#[no_mangle]
+pub fn test(a: &mut [u8], offset: usize, bytes: &[u8]) {
+    // CHECK-LABEL: @test(
+    // CHECK-NOT: call
+    // CHECK: call void @llvm.memcpy
+    // CHECK-NOT: call
+    // CHECK: }
+    if let Some(dst) = a.get_mut(offset..offset + bytes.len()) {
+        dst.copy_from_slice(bytes);
+    }
+}