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/asm/powerpc-clobbers.rs8
-rw-r--r--tests/codegen-llvm/asm/readonly-not-pure.rs48
-rw-r--r--tests/codegen-llvm/asm/riscv-clobbers.rs2
-rw-r--r--tests/codegen-llvm/autodiff/abi_handling.rs210
-rw-r--r--tests/codegen-llvm/auxiliary/darwin_objc_aux.rs27
-rw-r--r--tests/codegen-llvm/c-variadic-lifetime.rs4
-rw-r--r--tests/codegen-llvm/cffi/c-variadic-inline.rs47
-rw-r--r--tests/codegen-llvm/comparison-operators-2-struct.rs1
-rw-r--r--tests/codegen-llvm/comparison-operators-2-tuple.rs1
-rw-r--r--tests/codegen-llvm/darwin-no-objc.rs52
-rw-r--r--tests/codegen-llvm/darwin-objc-abi-v1.rs100
-rw-r--r--tests/codegen-llvm/darwin-objc-abi-v2.rs185
-rw-r--r--tests/codegen-llvm/darwin-objc-cross-crate.rs58
-rw-r--r--tests/codegen-llvm/enum/enum-aggregate.rs1
-rw-r--r--tests/codegen-llvm/enum/enum-discriminant-eq.rs1
-rw-r--r--tests/codegen-llvm/integer-cmp.rs36
-rw-r--r--tests/codegen-llvm/intrinsics/three_way_compare.rs1
-rw-r--r--tests/codegen-llvm/issues/and-masked-comparison-131162.rs1
-rw-r--r--tests/codegen-llvm/issues/cows-dont-have-branches-117763.rs17
-rw-r--r--tests/codegen-llvm/issues/issue-101082.rs1
-rw-r--r--tests/codegen-llvm/issues/issue-129795.rs1
-rw-r--r--tests/codegen-llvm/issues/iter-max-no-unwrap-failed-129583.rs1
-rw-r--r--tests/codegen-llvm/issues/looping-over-ne-bytes-133528.rs1
-rw-r--r--tests/codegen-llvm/option-niche-eq.rs1
-rw-r--r--tests/codegen-llvm/rust-abi-arch-specific-adjustment.rs8
-rw-r--r--tests/codegen-llvm/slice-last-elements-optimization.rs1
-rw-r--r--tests/codegen-llvm/swap-small-types.rs1
-rw-r--r--tests/codegen-llvm/try_question_mark_nop.rs31
-rw-r--r--tests/codegen-llvm/union-aggregate.rs1
29 files changed, 773 insertions, 74 deletions
diff --git a/tests/codegen-llvm/asm/powerpc-clobbers.rs b/tests/codegen-llvm/asm/powerpc-clobbers.rs
index f7fc7eea5d5..10d7ae4dba4 100644
--- a/tests/codegen-llvm/asm/powerpc-clobbers.rs
+++ b/tests/codegen-llvm/asm/powerpc-clobbers.rs
@@ -58,10 +58,10 @@ pub unsafe fn v0_clobber() {
 
 // Output format depends on the availability of altivec.
 // CHECK-LABEL: @clobber_abi
-// powerpc: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{xer}"()
-// powerpc64: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{xer}"()
-// powerpc64le: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{xer}"()
-// aix64: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{xer}"()
+// powerpc: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"()
+// powerpc64: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"()
+// powerpc64le: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"()
+// aix64: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"()
 #[no_mangle]
 pub unsafe fn clobber_abi() {
     asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags));
diff --git a/tests/codegen-llvm/asm/readonly-not-pure.rs b/tests/codegen-llvm/asm/readonly-not-pure.rs
new file mode 100644
index 00000000000..a3c0e276c7f
--- /dev/null
+++ b/tests/codegen-llvm/asm/readonly-not-pure.rs
@@ -0,0 +1,48 @@
+//@ add-core-stubs
+//@ compile-flags: -Copt-level=3 --target x86_64-unknown-linux-gnu
+//@ needs-llvm-components: x86
+
+#![crate_type = "rlib"]
+#![feature(no_core)]
+#![no_core]
+
+// Test that when an inline assembly block specifies `readonly` but not `pure`, a detailed
+// `MemoryEffects` is provided to LLVM: this assembly block is not allowed to perform writes,
+// but it may have side-effects.
+
+extern crate minicore;
+use minicore::*;
+
+pub static mut VAR: i32 = 0;
+
+// CHECK-LABEL: @no_options
+// CHECK: call i32 asm
+#[no_mangle]
+pub unsafe fn no_options() -> i32 {
+    VAR = 1;
+    let _ignored: i32;
+    asm!("mov {0}, 1", out(reg) _ignored);
+    VAR
+}
+
+// CHECK-LABEL: @readonly_pure
+// CHECK-NOT: call i32 asm
+#[no_mangle]
+pub unsafe fn readonly_pure() -> i32 {
+    VAR = 1;
+    let _ignored: i32;
+    asm!("mov {0}, 1", out(reg) _ignored, options(pure, readonly));
+    VAR
+}
+
+// CHECK-LABEL: @readonly_not_pure
+// CHECK: call i32 asm {{.*}} #[[ATTR:[0-9]+]]
+#[no_mangle]
+pub unsafe fn readonly_not_pure() -> i32 {
+    VAR = 1;
+    let _ignored: i32;
+    asm!("mov {0}, 1", out(reg) _ignored, options(readonly));
+    VAR
+}
+
+// CHECK: attributes #[[ATTR]] = { nounwind memory(read, inaccessiblemem: readwrite) }
diff --git a/tests/codegen-llvm/asm/riscv-clobbers.rs b/tests/codegen-llvm/asm/riscv-clobbers.rs
index e55b6731098..0f235ddcdcc 100644
--- a/tests/codegen-llvm/asm/riscv-clobbers.rs
+++ b/tests/codegen-llvm/asm/riscv-clobbers.rs
@@ -17,7 +17,7 @@ extern crate minicore;
 use minicore::*;
 
 // CHECK-LABEL: @flags_clobber
-// CHECK: call void asm sideeffect "", "~{vtype},~{vl},~{vxsat},~{vxrm}"()
+// CHECK: call void asm sideeffect "", "~{fflags},~{vtype},~{vl},~{vxsat},~{vxrm}"()
 #[no_mangle]
 pub unsafe fn flags_clobber() {
     asm!("", options(nostack, nomem));
diff --git a/tests/codegen-llvm/autodiff/abi_handling.rs b/tests/codegen-llvm/autodiff/abi_handling.rs
new file mode 100644
index 00000000000..454ec698b91
--- /dev/null
+++ b/tests/codegen-llvm/autodiff/abi_handling.rs
@@ -0,0 +1,210 @@
+//@ revisions: debug release
+
+//@[debug] compile-flags: -Zautodiff=Enable -C opt-level=0 -Clto=fat
+//@[release] compile-flags: -Zautodiff=Enable -C opt-level=3 -Clto=fat
+//@ no-prefer-dynamic
+//@ needs-enzyme
+
+// This test checks that Rust types are lowered to LLVM-IR types in a way
+// we expect and Enzyme can handle. We explicitly check release mode to
+// ensure that LLVM's O3 pipeline doesn't rewrite function signatures
+// into forms that Enzyme can't process correctly.
+
+#![feature(autodiff)]
+
+use std::autodiff::{autodiff_forward, autodiff_reverse};
+
+#[derive(Copy, Clone)]
+struct Input {
+    x: f32,
+    y: f32,
+}
+
+#[derive(Copy, Clone)]
+struct Wrapper {
+    z: f32,
+}
+
+#[derive(Copy, Clone)]
+struct NestedInput {
+    x: f32,
+    y: Wrapper,
+}
+
+fn square(x: f32) -> f32 {
+    x * x
+}
+
+// CHECK-LABEL: ; abi_handling::df1
+// CHECK-NEXT: Function Attrs
+// debug-NEXT: define internal { float, float }
+// debug-SAME: (ptr align 4 %x, ptr align 4 %bx_0)
+// release-NEXT: define internal fastcc float
+// release-SAME: (float %x.0.val, float %x.4.val)
+
+// CHECK-LABEL: ; abi_handling::f1
+// CHECK-NEXT: Function Attrs
+// debug-NEXT: define internal float
+// debug-SAME: (ptr align 4 %x)
+// release-NEXT: define internal fastcc noundef float
+// release-SAME: (float %x.0.val, float %x.4.val)
+#[autodiff_forward(df1, Dual, Dual)]
+#[inline(never)]
+fn f1(x: &[f32; 2]) -> f32 {
+    x[0] + x[1]
+}
+
+// CHECK-LABEL: ; abi_handling::df2
+// CHECK-NEXT: Function Attrs
+// debug-NEXT: define internal { float, float }
+// debug-SAME: (ptr %f, float %x, float %dret)
+// release-NEXT: define internal fastcc float
+// release-SAME: (float noundef %x)
+
+// CHECK-LABEL: ; abi_handling::f2
+// CHECK-NEXT: Function Attrs
+// debug-NEXT: define internal float
+// debug-SAME: (ptr %f, float %x)
+// release-NEXT: define internal fastcc noundef float
+// release-SAME: (float noundef %x)
+#[autodiff_reverse(df2, Const, Active, Active)]
+#[inline(never)]
+fn f2(f: fn(f32) -> f32, x: f32) -> f32 {
+    f(x)
+}
+
+// CHECK-LABEL: ; abi_handling::df3
+// CHECK-NEXT: Function Attrs
+// debug-NEXT: define internal { float, float }
+// debug-SAME: (ptr align 4 %x, ptr align 4 %bx_0, ptr align 4 %y, ptr align 4 %by_0)
+// release-NEXT: define internal fastcc { float, float }
+// release-SAME: (float %x.0.val)
+
+// CHECK-LABEL: ; abi_handling::f3
+// CHECK-NEXT: Function Attrs
+// debug-NEXT: define internal float
+// debug-SAME: (ptr align 4 %x, ptr align 4 %y)
+// release-NEXT: define internal fastcc noundef float
+// release-SAME: (float %x.0.val)
+#[autodiff_forward(df3, Dual, Dual, Dual)]
+#[inline(never)]
+fn f3<'a>(x: &'a f32, y: &'a f32) -> f32 {
+    *x * *y
+}
+
+// CHECK-LABEL: ; abi_handling::df4
+// CHECK-NEXT: Function Attrs
+// debug-NEXT: define internal { float, float }
+// debug-SAME: (float %x.0, float %x.1, float %bx_0.0, float %bx_0.1)
+// release-NEXT: define internal fastcc { float, float }
+// release-SAME: (float noundef %x.0, float noundef %x.1)
+
+// CHECK-LABEL: ; abi_handling::f4
+// CHECK-NEXT: Function Attrs
+// debug-NEXT: define internal float
+// debug-SAME: (float %x.0, float %x.1)
+// release-NEXT: define internal fastcc noundef float
+// release-SAME: (float noundef %x.0, float noundef %x.1)
+#[autodiff_forward(df4, Dual, Dual)]
+#[inline(never)]
+fn f4(x: (f32, f32)) -> f32 {
+    x.0 * x.1
+}
+
+// CHECK-LABEL: ; abi_handling::df5
+// CHECK-NEXT: Function Attrs
+// debug-NEXT: define internal { float, float }
+// debug-SAME: (float %i.0, float %i.1, float %bi_0.0, float %bi_0.1)
+// release-NEXT: define internal fastcc { float, float }
+// release-SAME: (float noundef %i.0, float noundef %i.1)
+
+// CHECK-LABEL: ; abi_handling::f5
+// CHECK-NEXT: Function Attrs
+// debug-NEXT: define internal float
+// debug-SAME: (float %i.0, float %i.1)
+// release-NEXT: define internal fastcc noundef float
+// release-SAME: (float noundef %i.0, float noundef %i.1)
+#[autodiff_forward(df5, Dual, Dual)]
+#[inline(never)]
+fn f5(i: Input) -> f32 {
+    i.x + i.y
+}
+
+// CHECK-LABEL: ; abi_handling::df6
+// CHECK-NEXT: Function Attrs
+// debug-NEXT: define internal { float, float }
+// debug-SAME: (float %i.0, float %i.1, float %bi_0.0, float %bi_0.1)
+// release-NEXT: define internal fastcc { float, float }
+// release-SAME: float noundef %i.0, float noundef %i.1
+// release-SAME: float noundef %bi_0.0, float noundef %bi_0.1
+
+// CHECK-LABEL: ; abi_handling::f6
+// CHECK-NEXT: Function Attrs
+// debug-NEXT: define internal float
+// debug-SAME: (float %i.0, float %i.1)
+// release-NEXT: define internal fastcc noundef float
+// release-SAME: (float noundef %i.0, float noundef %i.1)
+#[autodiff_forward(df6, Dual, Dual)]
+#[inline(never)]
+fn f6(i: NestedInput) -> f32 {
+    i.x + i.y.z * i.y.z
+}
+
+// CHECK-LABEL: ; abi_handling::df7
+// CHECK-NEXT: Function Attrs
+// debug-NEXT: define internal { float, float }
+// debug-SAME: (ptr align 4 %x.0, ptr align 4 %x.1, ptr align 4 %bx_0.0, ptr align 4 %bx_0.1)
+// release-NEXT: define internal fastcc { float, float }
+// release-SAME: (float %x.0.0.val, float %x.1.0.val)
+
+// CHECK-LABEL: ; abi_handling::f7
+// CHECK-NEXT: Function Attrs
+// debug-NEXT: define internal float
+// debug-SAME: (ptr align 4 %x.0, ptr align 4 %x.1)
+// release-NEXT: define internal fastcc noundef float
+// release-SAME: (float %x.0.0.val, float %x.1.0.val)
+#[autodiff_forward(df7, Dual, Dual)]
+#[inline(never)]
+fn f7(x: (&f32, &f32)) -> f32 {
+    x.0 * x.1
+}
+
+fn main() {
+    let x = std::hint::black_box(2.0);
+    let y = std::hint::black_box(3.0);
+    let z = std::hint::black_box(4.0);
+    static Y: f32 = std::hint::black_box(3.2);
+
+    let in_f1 = [x, y];
+    dbg!(f1(&in_f1));
+    let res_f1 = df1(&in_f1, &[1.0, 0.0]);
+    dbg!(res_f1);
+
+    dbg!(f2(square, x));
+    let res_f2 = df2(square, x, 1.0);
+    dbg!(res_f2);
+
+    dbg!(f3(&x, &Y));
+    let res_f3 = df3(&x, &Y, &1.0, &0.0);
+    dbg!(res_f3);
+
+    let in_f4 = (x, y);
+    dbg!(f4(in_f4));
+    let res_f4 = df4(in_f4, (1.0, 0.0));
+    dbg!(res_f4);
+
+    let in_f5 = Input { x, y };
+    dbg!(f5(in_f5));
+    let res_f5 = df5(in_f5, Input { x: 1.0, y: 0.0 });
+    dbg!(res_f5);
+
+    let in_f6 = NestedInput { x, y: Wrapper { z: y } };
+    dbg!(f6(in_f6));
+    let res_f6 = df6(in_f6, NestedInput { x, y: Wrapper { z } });
+    dbg!(res_f6);
+
+    let in_f7 = (&x, &y);
+    dbg!(f7(in_f7));
+    let res_f7 = df7(in_f7, (&1.0, &0.0));
+    dbg!(res_f7);
+}
diff --git a/tests/codegen-llvm/auxiliary/darwin_objc_aux.rs b/tests/codegen-llvm/auxiliary/darwin_objc_aux.rs
new file mode 100644
index 00000000000..3c35d003c8a
--- /dev/null
+++ b/tests/codegen-llvm/auxiliary/darwin_objc_aux.rs
@@ -0,0 +1,27 @@
+#![crate_type = "lib"]
+#![feature(darwin_objc)]
+
+use std::os::darwin::objc;
+
+#[link(name = "Foundation", kind = "framework")]
+unsafe extern "C" {}
+
+#[inline(always)]
+pub fn inline_get_object_class() -> objc::Class {
+    objc::class!("NSObject")
+}
+
+#[inline(always)]
+pub fn inline_get_alloc_selector() -> objc::SEL {
+    objc::selector!("alloc")
+}
+
+#[inline(never)]
+pub fn never_inline_get_string_class() -> objc::Class {
+    objc::class!("NSString")
+}
+
+#[inline(never)]
+pub fn never_inline_get_init_selector() -> objc::SEL {
+    objc::selector!("init")
+}
diff --git a/tests/codegen-llvm/c-variadic-lifetime.rs b/tests/codegen-llvm/c-variadic-lifetime.rs
index 5b2f8af18c8..c6d3602ef51 100644
--- a/tests/codegen-llvm/c-variadic-lifetime.rs
+++ b/tests/codegen-llvm/c-variadic-lifetime.rs
@@ -8,7 +8,7 @@
 
 #[unsafe(no_mangle)]
 unsafe extern "C" fn variadic(a: f64, mut args: ...) -> f64 {
-    // CHECK: call void @llvm.lifetime.start.p0(i64 {{[0-9]+}}, ptr nonnull %args)
+    // CHECK: call void @llvm.lifetime.start.p0({{(i64 [0-9]+, )?}}ptr nonnull %args)
     // CHECK: call void @llvm.va_start.p0(ptr nonnull %args)
 
     let b = args.arg::<f64>();
@@ -17,5 +17,5 @@ unsafe extern "C" fn variadic(a: f64, mut args: ...) -> f64 {
     a + b + c
 
     // CHECK: call void @llvm.va_end.p0(ptr nonnull %args)
-    // CHECK: call void @llvm.lifetime.end.p0(i64 {{[0-9]+}}, ptr nonnull %args)
+    // CHECK: call void @llvm.lifetime.end.p0({{(i64 [0-9]+, )?}}ptr nonnull %args)
 }
diff --git a/tests/codegen-llvm/cffi/c-variadic-inline.rs b/tests/codegen-llvm/cffi/c-variadic-inline.rs
new file mode 100644
index 00000000000..369b7e571ca
--- /dev/null
+++ b/tests/codegen-llvm/cffi/c-variadic-inline.rs
@@ -0,0 +1,47 @@
+//@ compile-flags: -C opt-level=3
+#![feature(c_variadic)]
+
+// Test that the inline attributes are accepted on C-variadic functions.
+//
+// Currently LLVM is unable to inline C-variadic functions, but that is valid because despite
+// the name even `#[inline(always)]` is just a hint.
+
+#[inline(always)]
+unsafe extern "C" fn inline_always(mut ap: ...) -> u32 {
+    ap.arg::<u32>()
+}
+
+#[inline]
+unsafe extern "C" fn inline(mut ap: ...) -> u32 {
+    ap.arg::<u32>()
+}
+
+#[inline(never)]
+unsafe extern "C" fn inline_never(mut ap: ...) -> u32 {
+    ap.arg::<u32>()
+}
+
+#[cold]
+unsafe extern "C" fn cold(mut ap: ...) -> u32 {
+    ap.arg::<u32>()
+}
+
+#[unsafe(no_mangle)]
+#[inline(never)]
+fn helper() {
+    // CHECK-LABEL: helper
+    // CHECK-LABEL: call c_variadic_inline::inline_always
+    // CHECK-LABEL: call c_variadic_inline::inline
+    // CHECK-LABEL: call c_variadic_inline::inline_never
+    // CHECK-LABEL: call c_variadic_inline::cold
+    unsafe {
+        inline_always(1);
+        inline(2);
+        inline_never(3);
+        cold(4);
+    }
+}
+
+fn main() {
+    helper()
+}
diff --git a/tests/codegen-llvm/comparison-operators-2-struct.rs b/tests/codegen-llvm/comparison-operators-2-struct.rs
index e179066ebfd..d44f92f511b 100644
--- a/tests/codegen-llvm/comparison-operators-2-struct.rs
+++ b/tests/codegen-llvm/comparison-operators-2-struct.rs
@@ -1,5 +1,4 @@
 //@ compile-flags: -C opt-level=1
-//@ min-llvm-version: 20
 
 // The `derive(PartialOrd)` for a 2-field type doesn't override `lt`/`le`/`gt`/`ge`.
 // This double-checks that the `Option<Ordering>` intermediate values used
diff --git a/tests/codegen-llvm/comparison-operators-2-tuple.rs b/tests/codegen-llvm/comparison-operators-2-tuple.rs
index 6a7e489c82d..37a7c5dfdaf 100644
--- a/tests/codegen-llvm/comparison-operators-2-tuple.rs
+++ b/tests/codegen-llvm/comparison-operators-2-tuple.rs
@@ -1,5 +1,4 @@
 //@ compile-flags: -C opt-level=1 -Z merge-functions=disabled
-//@ min-llvm-version: 20
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen-llvm/darwin-no-objc.rs b/tests/codegen-llvm/darwin-no-objc.rs
new file mode 100644
index 00000000000..fda3671fb6d
--- /dev/null
+++ b/tests/codegen-llvm/darwin-no-objc.rs
@@ -0,0 +1,52 @@
+// Test that we don't generate Objective-C definitions or image info unnecessarily.
+
+//@ add-core-stubs
+//@ revisions: i686_apple_darwin
+//@ [i686_apple_darwin] compile-flags: --target i686-apple-darwin
+//@ [i686_apple_darwin] needs-llvm-components: x86
+//@ revisions: x86_64_macos
+//@ [x86_64_macos] compile-flags: --target x86_64-apple-darwin
+//@ [x86_64_macos] needs-llvm-components: x86
+//@ revisions: aarch64_macos
+//@ [aarch64_macos] compile-flags: --target aarch64-apple-darwin
+//@ [aarch64_macos] needs-llvm-components: aarch64
+//@ revisions: i386_ios
+//@ [i386_ios] compile-flags: --target i386-apple-ios
+//@ [i386_ios] needs-llvm-components: x86
+//@ revisions: x86_64_ios
+//@ [x86_64_ios] compile-flags: --target x86_64-apple-ios
+//@ [x86_64_ios] needs-llvm-components: x86
+//@ revisions: armv7s_ios
+//@ [armv7s_ios] compile-flags: --target armv7s-apple-ios
+//@ [armv7s_ios] needs-llvm-components: arm
+//@ revisions: aarch64_ios
+//@ [aarch64_ios] compile-flags: --target aarch64-apple-ios
+//@ [aarch64_ios] needs-llvm-components: aarch64
+//@ revisions: aarch64_ios_sim
+//@ [aarch64_ios_sim] compile-flags: --target aarch64-apple-ios-sim
+//@ [aarch64_ios_sim] needs-llvm-components: aarch64
+
+#![crate_type = "lib"]
+#![feature(no_core, lang_items)]
+#![no_core]
+
+extern crate minicore;
+use minicore::*;
+
+#[no_mangle]
+pub fn foo() {}
+
+// CHECK-NOT: %struct._class_t
+// CHECK-NOT: %struct._objc_module
+// CHECK-NOT: @OBJC_CLASS_NAME_
+// CHECK-NOT: @"OBJC_CLASS_$_{{[0-9A-Z_a-z]+}}"
+// CHECK-NOT: @"OBJC_CLASSLIST_REFERENCES_$_.{{[0-9]+}}"
+// CHECK-NOT: @OBJC_METH_VAR_NAME_
+// CHECK-NOT: @OBJC_SELECTOR_REFERENCES_
+// CHECK-NOT: @OBJC_MODULES
+
+// CHECK-NOT: !"Objective-C Version"
+// CHECK-NOT: !"Objective-C Image Info Version"
+// CHECK-NOT: !"Objective-C Image Info Section"
+// CHECK-NOT: !"Objective-C Is Simulated"
+// CHECK-NOT: !"Objective-C Class Properties"
diff --git a/tests/codegen-llvm/darwin-objc-abi-v1.rs b/tests/codegen-llvm/darwin-objc-abi-v1.rs
new file mode 100644
index 00000000000..0fc1de9332a
--- /dev/null
+++ b/tests/codegen-llvm/darwin-objc-abi-v1.rs
@@ -0,0 +1,100 @@
+// ignore-tidy-linelength
+//@ add-core-stubs
+//@ revisions: i686_apple_darwin
+//@ [i686_apple_darwin] compile-flags: --target i686-apple-darwin
+//@ [i686_apple_darwin] needs-llvm-components: x86
+
+#![crate_type = "lib"]
+#![feature(no_core, lang_items, rustc_attrs)]
+#![no_core]
+
+extern crate minicore;
+use minicore::*;
+
+#[no_mangle]
+pub fn get_class() -> *mut () {
+    unsafe extern "C" {
+        #[rustc_objc_class = "MyClass"]
+        safe static VAL: *mut ();
+    }
+    VAL
+}
+
+#[no_mangle]
+pub fn get_class_again() -> *mut () {
+    // Codegen should de-duplicate this class with the one from get_class above.
+    unsafe extern "C" {
+        #[rustc_objc_class = "MyClass"]
+        safe static VAL: *mut ();
+    }
+    VAL
+}
+
+#[no_mangle]
+pub fn get_selector() -> *mut () {
+    unsafe extern "C" {
+        #[rustc_objc_selector = "myMethod"]
+        safe static VAL: *mut ();
+    }
+    VAL
+}
+
+#[no_mangle]
+pub fn get_selector_again() -> *mut () {
+    // Codegen should de-duplicate this selector with the one from get_selector above.
+    unsafe extern "C" {
+        #[rustc_objc_selector = "myMethod"]
+        safe static VAL: *mut ();
+    }
+    VAL
+}
+
+#[no_mangle]
+pub fn get_other_class() -> *mut () {
+    unsafe extern "C" {
+        #[rustc_objc_class = "OtherClass"]
+        safe static VAL: *mut ();
+    }
+    VAL
+}
+
+#[no_mangle]
+pub fn get_other_selector() -> *mut () {
+    unsafe extern "C" {
+        #[rustc_objc_selector = "otherMethod"]
+        safe static VAL: *mut ();
+    }
+    VAL
+}
+
+// CHECK: %struct._objc_module = type { i32, i32, ptr, ptr }
+
+// CHECK: @OBJC_CLASS_NAME_.{{[0-9]+}} = private unnamed_addr constant [8 x i8] c"MyClass\00", section "__TEXT,__cstring,cstring_literals", align 1
+// CHECK: @OBJC_CLASS_REFERENCES_.{{[0-9]+}} = private global ptr @OBJC_CLASS_NAME_.{{[0-9]+}}, section "__OBJC,__cls_refs,literal_pointers,no_dead_strip", align 4
+// CHECK-NOT: @OBJC_CLASS_NAME_
+// CHECK-NOT: @OBJC_CLASS_REFERENCES_
+
+// CHECK: @OBJC_METH_VAR_NAME_.{{[0-9]+}} = private unnamed_addr constant [9 x i8] c"myMethod\00", section "__TEXT,__cstring,cstring_literals", align 1
+// CHECK: @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}} = private externally_initialized global ptr @OBJC_METH_VAR_NAME_.{{[0-9]+}}, section "__OBJC,__message_refs,literal_pointers,no_dead_strip", align 4
+// CHECK-NOT: @OBJC_METH_VAR_NAME_
+// CHECK-NOT: @OBJC_SELECTOR_REFERENCES_
+
+// CHECK: @OBJC_CLASS_NAME_.{{[0-9]+}} = private unnamed_addr constant [11 x i8] c"OtherClass\00", section "__TEXT,__cstring,cstring_literals", align 1
+// CHECK: @OBJC_CLASS_REFERENCES_.{{[0-9]+}} = private global ptr @OBJC_CLASS_NAME_.{{[0-9]+}}, section "__OBJC,__cls_refs,literal_pointers,no_dead_strip", align 4
+
+// CHECK: @OBJC_METH_VAR_NAME_.{{[0-9]+}} = private unnamed_addr constant [12 x i8] c"otherMethod\00", section "__TEXT,__cstring,cstring_literals", align 1
+// CHECK: @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}} = private externally_initialized global ptr @OBJC_METH_VAR_NAME_.{{[0-9]+}}, section "__OBJC,__message_refs,literal_pointers,no_dead_strip", align 4
+
+// CHECK: @OBJC_CLASS_NAME_.{{[0-9]+}} = private unnamed_addr constant [1 x i8] zeroinitializer, section "__TEXT,__cstring,cstring_literals", align 1
+// CHECK: @OBJC_MODULES = private global %struct._objc_module { i32 7, i32 16, ptr @OBJC_CLASS_NAME_.{{[0-9]+}}, ptr null }, section "__OBJC,__module_info,regular,no_dead_strip", align 4
+
+// CHECK: load ptr, ptr @OBJC_CLASS_REFERENCES_.{{[0-9]+}}, align 4
+// CHECK: load ptr, ptr @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}}, align 4
+// CHECK: load ptr, ptr @OBJC_CLASS_REFERENCES_.{{[0-9]+}}, align 4
+// CHECK: load ptr, ptr @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}}, align 4
+
+// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Version", i32 1}
+// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Image Info Version", i32 0}
+// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Image Info Section", !"__OBJC,__image_info,regular"}
+// CHECK-NOT: !{{[0-9]+}} = !{i32 1, !"Objective-C Is Simulated", i32 32}
+// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Class Properties", i32 64}
diff --git a/tests/codegen-llvm/darwin-objc-abi-v2.rs b/tests/codegen-llvm/darwin-objc-abi-v2.rs
new file mode 100644
index 00000000000..f142371d582
--- /dev/null
+++ b/tests/codegen-llvm/darwin-objc-abi-v2.rs
@@ -0,0 +1,185 @@
+// ignore-tidy-linelength
+//@ add-core-stubs
+//@ revisions: x86_64_macos
+//@ [x86_64_macos] compile-flags: --target x86_64-apple-darwin
+//@ [x86_64_macos] needs-llvm-components: x86
+//@ revisions: aarch64_macos
+//@ [aarch64_macos] compile-flags: --target aarch64-apple-darwin
+//@ [aarch64_macos] needs-llvm-components: aarch64
+//@ revisions: i386_ios
+//@ [i386_ios] compile-flags: --target i386-apple-ios
+//@ [i386_ios] needs-llvm-components: x86
+//@ revisions: x86_64_ios
+//@ [x86_64_ios] compile-flags: --target x86_64-apple-ios
+//@ [x86_64_ios] needs-llvm-components: x86
+//@ revisions: armv7s_ios
+//@ [armv7s_ios] compile-flags: --target armv7s-apple-ios
+//@ [armv7s_ios] needs-llvm-components: arm
+//@ revisions: aarch64_ios
+//@ [aarch64_ios] compile-flags: --target aarch64-apple-ios
+//@ [aarch64_ios] needs-llvm-components: aarch64
+//@ revisions: aarch64_ios_sim
+//@ [aarch64_ios_sim] compile-flags: --target aarch64-apple-ios-sim
+//@ [aarch64_ios_sim] needs-llvm-components: aarch64
+
+#![crate_type = "lib"]
+#![feature(no_core, lang_items, rustc_attrs)]
+#![no_core]
+
+extern crate minicore;
+use minicore::*;
+
+#[no_mangle]
+pub fn get_class() -> *mut () {
+    unsafe extern "C" {
+        #[rustc_objc_class = "MyClass"]
+        safe static VAL: *mut ();
+    }
+    VAL
+}
+
+#[no_mangle]
+pub fn get_class_again() -> *mut () {
+    // Codegen should de-duplicate this class with the one from get_class above.
+    unsafe extern "C" {
+        #[rustc_objc_class = "MyClass"]
+        safe static VAL: *mut ();
+    }
+    VAL
+}
+
+#[no_mangle]
+pub fn get_selector() -> *mut () {
+    unsafe extern "C" {
+        #[rustc_objc_selector = "myMethod"]
+        safe static VAL: *mut ();
+    }
+    VAL
+}
+
+#[no_mangle]
+pub fn get_selector_again() -> *mut () {
+    // Codegen should de-duplicate this selector with the one from get_selector above.
+    unsafe extern "C" {
+        #[rustc_objc_selector = "myMethod"]
+        safe static VAL: *mut ();
+    }
+    VAL
+}
+
+#[no_mangle]
+pub fn get_other_class() -> *mut () {
+    unsafe extern "C" {
+        #[rustc_objc_class = "OtherClass"]
+        safe static VAL: *mut ();
+    }
+    VAL
+}
+
+#[no_mangle]
+pub fn get_other_selector() -> *mut () {
+    unsafe extern "C" {
+        #[rustc_objc_selector = "otherMethod"]
+        safe static VAL: *mut ();
+    }
+    VAL
+}
+
+// CHECK: %struct._class_t = type { ptr, ptr, ptr, ptr, ptr }
+
+// CHECK: @"OBJC_CLASS_$_MyClass" = external global %struct._class_t
+// CHECK: @"OBJC_CLASSLIST_REFERENCES_$_.{{[0-9]+}}" = internal global ptr @"OBJC_CLASS_$_MyClass", section "__DATA,__objc_classrefs,regular,no_dead_strip",
+// x86_64_macos-SAME: align 8
+// aarch64_macos-SAME: align 8
+// i386_ios-SAME: align 4
+// x86_64_ios-SAME: align 8
+// armv7s_ios-SAME: align 4
+// aarch64_ios-SAME: align 8
+// aarch64_ios_sim-SAME: align 8
+// CHECK-NOT: @"OBJC_CLASS_$_MyClass"
+// CHECK-NOT: @"OBJC_CLASSLIST_REFERENCES_$_
+
+// CHECK: @OBJC_METH_VAR_NAME_.{{[0-9]+}} = private unnamed_addr constant [9 x i8] c"myMethod\00", section "__TEXT,__objc_methname,cstring_literals", align 1
+// CHECK: @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}} = internal externally_initialized global ptr @OBJC_METH_VAR_NAME_.{{[0-9]+}}, section "__DATA,__objc_selrefs,literal_pointers,no_dead_strip",
+// x86_64_macos-SAME: align 8
+// aarch64_macos-SAME: align 8
+// i386_ios-SAME: align 4
+// x86_64_ios-SAME: align 8
+// armv7s_ios-SAME: align 4
+// aarch64_ios-SAME: align 8
+// aarch64_ios_sim-SAME: align 8
+// CHECK-NOT: @OBJC_METH_VAR_NAME_
+// CHECK-NOT: @OBJC_SELECTOR_REFERENCES_
+
+// CHECK: @"OBJC_CLASS_$_OtherClass" = external global %struct._class_t
+// CHECK: @"OBJC_CLASSLIST_REFERENCES_$_.{{[0-9]+}}" = internal global ptr @"OBJC_CLASS_$_OtherClass", section "__DATA,__objc_classrefs,regular,no_dead_strip",
+// x86_64_macos-SAME: align 8
+// aarch64_macos-SAME: align 8
+// i386_ios-SAME: align 4
+// x86_64_ios-SAME: align 8
+// armv7s_ios-SAME: align 4
+// aarch64_ios-SAME: align 8
+// aarch64_ios_sim-SAME: align 8
+
+// CHECK: @OBJC_METH_VAR_NAME_.{{[0-9]+}} = private unnamed_addr constant [12 x i8] c"otherMethod\00", section "__TEXT,__objc_methname,cstring_literals", align 1
+// CHECK: @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}} = internal externally_initialized global ptr @OBJC_METH_VAR_NAME_.{{[0-9]+}}, section "__DATA,__objc_selrefs,literal_pointers,no_dead_strip",
+// x86_64_macos-SAME: align 8
+// aarch64_macos-SAME: align 8
+// i386_ios-SAME: align 4
+// x86_64_ios-SAME: align 8
+// armv7s_ios-SAME: align 4
+// aarch64_ios-SAME: align 8
+// aarch64_ios_sim-SAME: align 8
+
+// CHECK-NOT: @OBJC_CLASS_NAME_
+// CHECK-NOT: @OBJC_MODULES
+
+// CHECK: load ptr, ptr @"OBJC_CLASSLIST_REFERENCES_$_.{{[0-9]+}}",
+// x86_64_macos-SAME: align 8
+// aarch64_macos-SAME: align 8
+// i386_ios-SAME: align 4
+// x86_64_ios-SAME: align 8
+// armv7s_ios-SAME: align 4
+// aarch64_ios-SAME: align 8
+// aarch64_ios_sim-SAME: align 8
+
+// CHECK: load ptr, ptr @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}},
+// x86_64_macos-SAME: align 8
+// aarch64_macos-SAME: align 8
+// i386_ios-SAME: align 4
+// x86_64_ios-SAME: align 8
+// armv7s_ios-SAME: align 4
+// aarch64_ios-SAME: align 8
+// aarch64_ios_sim-SAME: align 8
+
+// CHECK: load ptr, ptr @"OBJC_CLASSLIST_REFERENCES_$_.{{[0-9]+}}",
+// x86_64_macos-SAME: align 8
+// aarch64_macos-SAME: align 8
+// i386_ios-SAME: align 4
+// x86_64_ios-SAME: align 8
+// armv7s_ios-SAME: align 4
+// aarch64_ios-SAME: align 8
+// aarch64_ios_sim-SAME: align 8
+
+// CHECK: load ptr, ptr @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}},
+// x86_64_macos-SAME: align 8
+// aarch64_macos-SAME: align 8
+// i386_ios-SAME: align 4
+// x86_64_ios-SAME: align 8
+// armv7s_ios-SAME: align 4
+// aarch64_ios-SAME: align 8
+// aarch64_ios_sim-SAME: align 8
+
+// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Version", i32 2}
+// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Image Info Version", i32 0}
+// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Image Info Section", !"__DATA,__objc_imageinfo,regular,no_dead_strip"}
+
+// x86_64_macos-NOT: !{{[0-9]+}} = !{i32 1, !"Objective-C Is Simulated", i32 32}
+// aarch64_macos-NOT: !{{[0-9]+}} = !{i32 1, !"Objective-C Is Simulated", i32 32}
+// i386_ios: !{{[0-9]+}} = !{i32 1, !"Objective-C Is Simulated", i32 32}
+// x86_64_ios: !{{[0-9]+}} = !{i32 1, !"Objective-C Is Simulated", i32 32}
+// armv7s_ios-NOT: !{{[0-9]+}} = !{i32 1, !"Objective-C Is Simulated", i32 32}
+// aarch64_ios-NOT: !{{[0-9]+}} = !{i32 1, !"Objective-C Is Simulated", i32 32}
+// aarch64_ios_sim: !{{[0-9]+}} = !{i32 1, !"Objective-C Is Simulated", i32 32}
+
+// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Class Properties", i32 64}
diff --git a/tests/codegen-llvm/darwin-objc-cross-crate.rs b/tests/codegen-llvm/darwin-objc-cross-crate.rs
new file mode 100644
index 00000000000..74ad9a27346
--- /dev/null
+++ b/tests/codegen-llvm/darwin-objc-cross-crate.rs
@@ -0,0 +1,58 @@
+// Test that Objective-C class and selector references inlined across crates
+// get defined in this CGU but non-inline references don't.
+
+// ignore-tidy-linelength
+//@ aux-build: darwin_objc_aux.rs
+//@ revisions: x86_64_macos aarch64_macos
+//@ [x86_64_macos] only-x86_64-apple-darwin
+//@ [aarch64_macos] only-aarch64-apple-darwin
+
+#![crate_type = "lib"]
+#![feature(darwin_objc)]
+
+use std::os::darwin::objc;
+
+extern crate darwin_objc_aux as aux;
+
+#[no_mangle]
+pub fn get_object_class() -> objc::Class {
+    aux::inline_get_object_class()
+}
+
+#[no_mangle]
+pub fn get_alloc_selector() -> objc::SEL {
+    aux::inline_get_alloc_selector()
+}
+
+#[no_mangle]
+pub fn get_string_class() -> objc::Class {
+    aux::never_inline_get_string_class()
+}
+
+#[no_mangle]
+pub fn get_init_selector() -> objc::SEL {
+    aux::never_inline_get_init_selector()
+}
+
+// CHECK: %struct._class_t = type { ptr, ptr, ptr, ptr, ptr }
+
+// CHECK: @"OBJC_CLASS_$_NSObject" = external global %struct._class_t
+// CHECK: @"OBJC_CLASSLIST_REFERENCES_$_.{{[0-9]+}}" = internal global ptr @"OBJC_CLASS_$_NSObject", section "__DATA,__objc_classrefs,regular,no_dead_strip", align 8
+
+// CHECK: @OBJC_METH_VAR_NAME_.{{[0-9]+}} = private unnamed_addr constant [6 x i8] c"alloc\00", section "__TEXT,__objc_methname,cstring_literals", align 1
+// CHECK: @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}} = internal externally_initialized global ptr @OBJC_METH_VAR_NAME_.{{[0-9]+}}, section "__DATA,__objc_selrefs,literal_pointers,no_dead_strip", align 8
+
+// CHECK-NOT: @"OBJC_CLASS_$_NSString" = external global %struct._class_t
+// CHECK-NOT: @"OBJC_CLASSLIST_REFERENCES_$_.{{[0-9]+}}" = internal global ptr @"OBJC_CLASS_$_NSString"
+
+// CHECK-NOT: @OBJC_METH_VAR_NAME_.{{[0-9]+}} = private unnamed_addr constant [5 x i8] c"init\00"
+// CHECK-NOT: @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}} = internal externally_initialized global ptr @OBJC_METH_VAR_NAME_.{{[0-9]+}}
+
+// CHECK: load ptr, ptr @"OBJC_CLASSLIST_REFERENCES_$_.{{[0-9]+}}", align 8
+// CHECK: load ptr, ptr @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}}, align 8
+
+// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Version", i32 2}
+// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Image Info Version", i32 0}
+// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Image Info Section", !"__DATA,__objc_imageinfo,regular,no_dead_strip"}
+// CHECK-NOT: !{{[0-9]+}} = !{i32 1, !"Objective-C Is Simulated", i32 32}
+// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Class Properties", i32 64}
diff --git a/tests/codegen-llvm/enum/enum-aggregate.rs b/tests/codegen-llvm/enum/enum-aggregate.rs
index f58d7ef12b6..7d450a89e2e 100644
--- a/tests/codegen-llvm/enum/enum-aggregate.rs
+++ b/tests/codegen-llvm/enum/enum-aggregate.rs
@@ -1,5 +1,4 @@
 //@ compile-flags: -Copt-level=0 -Cno-prepopulate-passes
-//@ min-llvm-version: 19
 //@ only-64bit
 
 #![crate_type = "lib"]
diff --git a/tests/codegen-llvm/enum/enum-discriminant-eq.rs b/tests/codegen-llvm/enum/enum-discriminant-eq.rs
index a1ab5e5c6e2..68cd58643e8 100644
--- a/tests/codegen-llvm/enum/enum-discriminant-eq.rs
+++ b/tests/codegen-llvm/enum/enum-discriminant-eq.rs
@@ -1,5 +1,4 @@
 //@ compile-flags: -Copt-level=3 -Zmerge-functions=disabled
-//@ min-llvm-version: 20
 //@ only-64bit
 //@ revisions: LLVM20 LLVM21
 //@ [LLVM21] min-llvm-version: 21
diff --git a/tests/codegen-llvm/integer-cmp.rs b/tests/codegen-llvm/integer-cmp.rs
index 812fa8e4a42..2233a575f8e 100644
--- a/tests/codegen-llvm/integer-cmp.rs
+++ b/tests/codegen-llvm/integer-cmp.rs
@@ -1,9 +1,6 @@
 // This is test for more optimal Ord implementation for integers.
 // See <https://github.com/rust-lang/rust/issues/63758> for more info.
 
-//@ revisions: llvm-pre-20 llvm-20
-//@ [llvm-20] min-llvm-version: 20
-//@ [llvm-pre-20] max-llvm-major-version: 19
 //@ compile-flags: -C opt-level=3 -Zmerge-functions=disabled
 
 #![crate_type = "lib"]
@@ -13,50 +10,29 @@ use std::cmp::Ordering;
 // CHECK-LABEL: @cmp_signed
 #[no_mangle]
 pub fn cmp_signed(a: i64, b: i64) -> Ordering {
-    // llvm-20: call{{.*}} i8 @llvm.scmp.i8.i64
-    // llvm-pre-20: icmp slt
-    // llvm-pre-20: icmp ne
-    // llvm-pre-20: zext i1
-    // llvm-pre-20: select i1
+    // CHECK: call{{.*}} i8 @llvm.scmp.i8.i64
     a.cmp(&b)
 }
 
 // CHECK-LABEL: @cmp_unsigned
 #[no_mangle]
 pub fn cmp_unsigned(a: u32, b: u32) -> Ordering {
-    // llvm-20: call{{.*}} i8 @llvm.ucmp.i8.i32
-    // llvm-pre-20: icmp ult
-    // llvm-pre-20: icmp ne
-    // llvm-pre-20: zext i1
-    // llvm-pre-20: select i1
+    // CHECK: call{{.*}} i8 @llvm.ucmp.i8.i32
     a.cmp(&b)
 }
 
 // CHECK-LABEL: @cmp_char
 #[no_mangle]
 pub fn cmp_char(a: char, b: char) -> Ordering {
-    // llvm-20: call{{.*}} i8 @llvm.ucmp.i8.i32
-    // llvm-pre-20: icmp ult
-    // llvm-pre-20: icmp ne
-    // llvm-pre-20: zext i1
-    // llvm-pre-20: select i1
+    // CHECK: call{{.*}} i8 @llvm.ucmp.i8.i32
     a.cmp(&b)
 }
 
 // CHECK-LABEL: @cmp_tuple
 #[no_mangle]
 pub fn cmp_tuple(a: (i16, u16), b: (i16, u16)) -> Ordering {
-    // llvm-20-DAG: call{{.*}} i8 @llvm.ucmp.i8.i16
-    // llvm-20-DAG: call{{.*}} i8 @llvm.scmp.i8.i16
-    // llvm-20: ret i8
-    // llvm-pre-20: icmp slt
-    // llvm-pre-20: icmp ne
-    // llvm-pre-20: zext i1
-    // llvm-pre-20: select i1
-    // llvm-pre-20: icmp ult
-    // llvm-pre-20: icmp ne
-    // llvm-pre-20: zext i1
-    // llvm-pre-20: select i1
-    // llvm-pre-20: select i1
+    // CHECK-DAG: call{{.*}} i8 @llvm.ucmp.i8.i16
+    // CHECK-DAG: call{{.*}} i8 @llvm.scmp.i8.i16
+    // CHECK: ret i8
     a.cmp(&b)
 }
diff --git a/tests/codegen-llvm/intrinsics/three_way_compare.rs b/tests/codegen-llvm/intrinsics/three_way_compare.rs
index 95fcb636f7c..89bf69561e9 100644
--- a/tests/codegen-llvm/intrinsics/three_way_compare.rs
+++ b/tests/codegen-llvm/intrinsics/three_way_compare.rs
@@ -2,7 +2,6 @@
 //@ [DEBUG] compile-flags: -C opt-level=0
 //@ [OPTIM] compile-flags: -C opt-level=3
 //@ compile-flags: -C no-prepopulate-passes
-//@ min-llvm-version: 20
 
 #![crate_type = "lib"]
 #![feature(core_intrinsics)]
diff --git a/tests/codegen-llvm/issues/and-masked-comparison-131162.rs b/tests/codegen-llvm/issues/and-masked-comparison-131162.rs
index bdf021092fd..fc4b0341a31 100644
--- a/tests/codegen-llvm/issues/and-masked-comparison-131162.rs
+++ b/tests/codegen-llvm/issues/and-masked-comparison-131162.rs
@@ -1,5 +1,4 @@
 //@ compile-flags: -Copt-level=3
-//@ min-llvm-version: 20
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen-llvm/issues/cows-dont-have-branches-117763.rs b/tests/codegen-llvm/issues/cows-dont-have-branches-117763.rs
new file mode 100644
index 00000000000..b97729fa146
--- /dev/null
+++ b/tests/codegen-llvm/issues/cows-dont-have-branches-117763.rs
@@ -0,0 +1,17 @@
+//@ compile-flags: -Copt-level=3
+//@ needs-deterministic-layouts
+
+// Currently Vec<T> and &[T] have layouts that start with (pointer, len)
+// which makes the conversion branchless.
+// A nice-to-have property, not guaranteed.
+#![crate_type = "cdylib"]
+
+// CHECK-LABEL: @branchless_cow_slices
+#[no_mangle]
+pub fn branchless_cow_slices<'a>(cow: &'a std::borrow::Cow<'a, [u8]>) -> &'a [u8] {
+    // CHECK-NOT: br
+    // CHECK-NOT: select
+    // CHECK-NOT: icmp
+    // CHECK: ret { ptr, {{i32|i64}} }
+    &*cow
+}
diff --git a/tests/codegen-llvm/issues/issue-101082.rs b/tests/codegen-llvm/issues/issue-101082.rs
index 8d15921ddb4..0c1f90f951a 100644
--- a/tests/codegen-llvm/issues/issue-101082.rs
+++ b/tests/codegen-llvm/issues/issue-101082.rs
@@ -1,6 +1,5 @@
 //@ compile-flags: -Copt-level=3
 //@ revisions: host x86-64 x86-64-v3
-//@ min-llvm-version: 20
 
 //@[host] ignore-x86_64
 
diff --git a/tests/codegen-llvm/issues/issue-129795.rs b/tests/codegen-llvm/issues/issue-129795.rs
index dc64ee35c97..7a928389fab 100644
--- a/tests/codegen-llvm/issues/issue-129795.rs
+++ b/tests/codegen-llvm/issues/issue-129795.rs
@@ -1,5 +1,4 @@
 //@ compile-flags: -Copt-level=3
-//@ min-llvm-version: 20
 #![crate_type = "lib"]
 
 // Ensure that a modulo operation with an operand that is known to be
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
index 4d3fa4993ef..4c4eebeabb5 100644
--- a/tests/codegen-llvm/issues/iter-max-no-unwrap-failed-129583.rs
+++ b/tests/codegen-llvm/issues/iter-max-no-unwrap-failed-129583.rs
@@ -3,7 +3,6 @@
 // use a larger value to prevent unrolling.
 
 //@ compile-flags: -Copt-level=3
-//@ min-llvm-version: 20
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen-llvm/issues/looping-over-ne-bytes-133528.rs b/tests/codegen-llvm/issues/looping-over-ne-bytes-133528.rs
index 35acf765d69..b686f8c4b3a 100644
--- a/tests/codegen-llvm/issues/looping-over-ne-bytes-133528.rs
+++ b/tests/codegen-llvm/issues/looping-over-ne-bytes-133528.rs
@@ -1,5 +1,4 @@
 //@ compile-flags: -Copt-level=3
-//@ min-llvm-version: 20
 #![crate_type = "lib"]
 
 /// Ensure the function is properly optimized
diff --git a/tests/codegen-llvm/option-niche-eq.rs b/tests/codegen-llvm/option-niche-eq.rs
index 3900cb79aa2..e9c3fa2407e 100644
--- a/tests/codegen-llvm/option-niche-eq.rs
+++ b/tests/codegen-llvm/option-niche-eq.rs
@@ -1,5 +1,4 @@
 //@ revisions: REGULAR LLVM21
-//@ min-llvm-version: 20
 //@ compile-flags: -Copt-level=3 -Zmerge-functions=disabled
 //@ [LLVM21] min-llvm-version: 21
 #![crate_type = "lib"]
diff --git a/tests/codegen-llvm/rust-abi-arch-specific-adjustment.rs b/tests/codegen-llvm/rust-abi-arch-specific-adjustment.rs
index 561f081c700..ffff4b35994 100644
--- a/tests/codegen-llvm/rust-abi-arch-specific-adjustment.rs
+++ b/tests/codegen-llvm/rust-abi-arch-specific-adjustment.rs
@@ -1,15 +1,19 @@
+//@ add-core-stubs
 //@ compile-flags: -Copt-level=3 -C no-prepopulate-passes
 //@ revisions: riscv64 loongarch64
 
-//@[riscv64] only-riscv64
 //@[riscv64] compile-flags: --target riscv64gc-unknown-linux-gnu
 //@[riscv64] needs-llvm-components: riscv
 
-//@[loongarch64] only-loongarch64
 //@[loongarch64] compile-flags: --target loongarch64-unknown-linux-gnu
 //@[loongarch64] needs-llvm-components: loongarch
 
 #![crate_type = "lib"]
+#![feature(no_core)]
+#![no_core]
+
+extern crate minicore;
+use minicore::*;
 
 #[no_mangle]
 // riscv64:     define noundef i8 @arg_attr_u8(i8 noundef zeroext %x)
diff --git a/tests/codegen-llvm/slice-last-elements-optimization.rs b/tests/codegen-llvm/slice-last-elements-optimization.rs
index d982cda709d..77fc1d21cd9 100644
--- a/tests/codegen-llvm/slice-last-elements-optimization.rs
+++ b/tests/codegen-llvm/slice-last-elements-optimization.rs
@@ -1,5 +1,4 @@
 //@ compile-flags: -Copt-level=3
-//@ min-llvm-version: 20
 #![crate_type = "lib"]
 
 // This test verifies that LLVM 20 properly optimizes the bounds check
diff --git a/tests/codegen-llvm/swap-small-types.rs b/tests/codegen-llvm/swap-small-types.rs
index 7aa613ae9c2..0799ff76331 100644
--- a/tests/codegen-llvm/swap-small-types.rs
+++ b/tests/codegen-llvm/swap-small-types.rs
@@ -1,6 +1,5 @@
 //@ compile-flags: -Copt-level=3 -Z merge-functions=disabled
 //@ only-x86_64
-//@ min-llvm-version: 20
 //@ ignore-std-debug-assertions (`ptr::swap_nonoverlapping` has one which blocks some optimizations)
 
 #![crate_type = "lib"]
diff --git a/tests/codegen-llvm/try_question_mark_nop.rs b/tests/codegen-llvm/try_question_mark_nop.rs
index 398c9a580bc..a09fa0a4901 100644
--- a/tests/codegen-llvm/try_question_mark_nop.rs
+++ b/tests/codegen-llvm/try_question_mark_nop.rs
@@ -1,9 +1,6 @@
 //@ compile-flags: -Copt-level=3 -Z merge-functions=disabled
 //@ edition: 2021
 //@ only-x86_64
-//@ revisions: NINETEEN TWENTY
-//@[NINETEEN] exact-llvm-major-version: 19
-//@[TWENTY] min-llvm-version: 20
 
 #![crate_type = "lib"]
 #![feature(try_blocks)]
@@ -17,13 +14,9 @@ pub fn option_nop_match_32(x: Option<u32>) -> Option<u32> {
     // CHECK: start:
     // CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw i32 %0 to i1
 
-    // NINETEEN-NEXT: [[SELECT:%.*]] = select i1 [[TRUNC]], i32 %0, i32 0
-    // NINETEEN-NEXT: [[REG2:%.*]] = insertvalue { i32, i32 } poison, i32 [[SELECT]], 0
-    // NINETEEN-NEXT: [[REG3:%.*]] = insertvalue { i32, i32 } [[REG2]], i32 %1, 1
-
-    // TWENTY-NEXT: [[SELECT:%.*]] = select i1 [[TRUNC]], i32 %1, i32 undef
-    // TWENTY-NEXT: [[REG2:%.*]] = insertvalue { i32, i32 } poison, i32 %0, 0
-    // TWENTY-NEXT: [[REG3:%.*]] = insertvalue { i32, i32 } [[REG2]], i32 [[SELECT]], 1
+    // CHECK-NEXT: [[SELECT:%.*]] = select i1 [[TRUNC]], i32 %1, i32 undef
+    // CHECK-NEXT: [[REG2:%.*]] = insertvalue { i32, i32 } poison, i32 %0, 0
+    // CHECK-NEXT: [[REG3:%.*]] = insertvalue { i32, i32 } [[REG2]], i32 [[SELECT]], 1
 
     // CHECK-NEXT: ret { i32, i32 } [[REG3]]
     match x {
@@ -36,8 +29,8 @@ pub fn option_nop_match_32(x: Option<u32>) -> Option<u32> {
 #[no_mangle]
 pub fn option_nop_traits_32(x: Option<u32>) -> Option<u32> {
     // CHECK: start:
-    // TWENTY-NEXT: %[[IS_SOME:.+]] = trunc nuw i32 %0 to i1
-    // TWENTY-NEXT: select i1 %[[IS_SOME]], i32 %1, i32 undef
+    // CHECK-NEXT: %[[IS_SOME:.+]] = trunc nuw i32 %0 to i1
+    // CHECK-NEXT: select i1 %[[IS_SOME]], i32 %1, i32 undef
     // CHECK-NEXT: insertvalue { i32, i32 }
     // CHECK-NEXT: insertvalue { i32, i32 }
     // CHECK-NEXT: ret { i32, i32 }
@@ -96,13 +89,9 @@ pub fn option_nop_match_64(x: Option<u64>) -> Option<u64> {
     // CHECK: start:
     // CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw i64 %0 to i1
 
-    // NINETEEN-NEXT: [[SELECT:%.*]] = select i1 [[TRUNC]], i64 %0, i64 0
-    // NINETEEN-NEXT: [[REG2:%.*]] = insertvalue { i64, i64 } poison, i64 [[SELECT]], 0
-    // NINETEEN-NEXT: [[REG3:%.*]] = insertvalue { i64, i64 } [[REG2]], i64 %1, 1
-
-    // TWENTY-NEXT: [[SELECT:%.*]] = select i1 [[TRUNC]], i64 %1, i64 undef
-    // TWENTY-NEXT: [[REG2:%.*]] = insertvalue { i64, i64 } poison, i64 %0, 0
-    // TWENTY-NEXT: [[REG3:%.*]] = insertvalue { i64, i64 } [[REG2]], i64 [[SELECT]], 1
+    // CHECK-NEXT: [[SELECT:%.*]] = select i1 [[TRUNC]], i64 %1, i64 undef
+    // CHECK-NEXT: [[REG2:%.*]] = insertvalue { i64, i64 } poison, i64 %0, 0
+    // CHECK-NEXT: [[REG3:%.*]] = insertvalue { i64, i64 } [[REG2]], i64 [[SELECT]], 1
 
     // CHECK-NEXT: ret { i64, i64 } [[REG3]]
     match x {
@@ -115,8 +104,8 @@ pub fn option_nop_match_64(x: Option<u64>) -> Option<u64> {
 #[no_mangle]
 pub fn option_nop_traits_64(x: Option<u64>) -> Option<u64> {
     // CHECK: start:
-    // TWENTY-NEXT: %[[TRUNC:[0-9]+]] = trunc nuw i64 %0 to i1
-    // TWENTY-NEXT: %[[SEL:\.[0-9]+]] = select i1 %[[TRUNC]], i64 %1, i64 undef
+    // CHECK-NEXT: %[[TRUNC:[0-9]+]] = trunc nuw i64 %0 to i1
+    // CHECK-NEXT: %[[SEL:\.[0-9]+]] = select i1 %[[TRUNC]], i64 %1, i64 undef
     // CHECK-NEXT: insertvalue { i64, i64 }
     // CHECK-NEXT: insertvalue { i64, i64 }
     // CHECK-NEXT: ret { i64, i64 }
diff --git a/tests/codegen-llvm/union-aggregate.rs b/tests/codegen-llvm/union-aggregate.rs
index aac66c5dcdd..7faa66804fe 100644
--- a/tests/codegen-llvm/union-aggregate.rs
+++ b/tests/codegen-llvm/union-aggregate.rs
@@ -1,5 +1,4 @@
 //@ compile-flags: -Copt-level=0 -Cno-prepopulate-passes
-//@ min-llvm-version: 19
 //@ only-64bit
 
 #![crate_type = "lib"]