about summary refs log tree commit diff
path: root/tests/codegen
diff options
context:
space:
mode:
Diffstat (limited to 'tests/codegen')
-rw-r--r--tests/codegen/autodiff.rs4
-rw-r--r--tests/codegen/autodiffv.rs116
-rw-r--r--tests/codegen/branch-protection-old-llvm.rs46
-rw-r--r--tests/codegen/branch-protection.rs1
-rw-r--r--tests/codegen/call-metadata.rs18
-rw-r--r--tests/codegen/cast-target-abi.rs1
-rw-r--r--tests/codegen/cffi/ffi-const.rs3
-rw-r--r--tests/codegen/cffi/ffi-out-of-bounds-loads.rs1
-rw-r--r--tests/codegen/cffi/ffi-pure.rs3
-rw-r--r--tests/codegen/char-escape-debug-no-bounds-check.rs14
-rw-r--r--tests/codegen/debuginfo-proc-macro/mir_inlined_twice_var_locs.rs1
-rw-r--r--tests/codegen/dont-shuffle-bswaps.rs1
-rw-r--r--tests/codegen/enum/enum-two-variants-match.rs1
-rw-r--r--tests/codegen/float/algebraic.rs149
-rw-r--r--tests/codegen/float_math.rs71
-rw-r--r--tests/codegen/intrinsics/carrying_mul_add.rs1
-rw-r--r--tests/codegen/intrinsics/transmute.rs11
-rw-r--r--tests/codegen/issues/issue-107681-unwrap_unchecked.rs1
-rw-r--r--tests/codegen/issues/issue-118306.rs1
-rw-r--r--tests/codegen/issues/issue-122600-ptr-discriminant-update.rs3
-rw-r--r--tests/codegen/issues/issue-126585.rs1
-rw-r--r--tests/codegen/range-attribute.rs1
-rw-r--r--tests/codegen/sanitizer/kcfi/add-kcfi-arity-flag.rs19
-rw-r--r--tests/codegen/tied-features-strength.rs12
-rw-r--r--tests/codegen/try_question_mark_nop.rs2
-rw-r--r--tests/codegen/unchecked_shifts.rs15
-rw-r--r--tests/codegen/vec_pop_push_noop.rs3
27 files changed, 374 insertions, 126 deletions
diff --git a/tests/codegen/autodiff.rs b/tests/codegen/autodiff.rs
index cace0edb2b5..85358f5fcb6 100644
--- a/tests/codegen/autodiff.rs
+++ b/tests/codegen/autodiff.rs
@@ -11,7 +11,7 @@ fn square(x: &f64) -> f64 {
     x * x
 }
 
-// CHECK:define internal fastcc double @diffesquare(double %x.0.val, ptr nocapture align 8 %"x'"
+// CHECK:define internal fastcc double @diffesquare(double %x.0.val, ptr nocapture nonnull align 8 %"x'"
 // CHECK-NEXT:invertstart:
 // CHECK-NEXT:  %_0 = fmul double %x.0.val, %x.0.val
 // CHECK-NEXT:  %0 = fadd fast double %x.0.val, %x.0.val
@@ -22,7 +22,7 @@ fn square(x: &f64) -> f64 {
 // CHECK-NEXT:}
 
 fn main() {
-    let x = 3.0;
+    let x = std::hint::black_box(3.0);
     let output = square(&x);
     assert_eq!(9.0, output);
 
diff --git a/tests/codegen/autodiffv.rs b/tests/codegen/autodiffv.rs
new file mode 100644
index 00000000000..e0047116405
--- /dev/null
+++ b/tests/codegen/autodiffv.rs
@@ -0,0 +1,116 @@
+//@ compile-flags: -Zautodiff=Enable -C opt-level=3  -Clto=fat
+//@ no-prefer-dynamic
+//@ needs-enzyme
+//
+// In Enzyme, we test against a large range of LLVM versions (5+) and don't have overly many
+// breakages. One benefit is that we match the IR generated by Enzyme only after running it
+// through LLVM's O3 pipeline, which will remove most of the noise.
+// However, our integration test could also be affected by changes in how rustc lowers MIR into
+// LLVM-IR, which could cause additional noise and thus breakages. If that's the case, we should
+// reduce this test to only match the first lines and the ret instructions.
+
+#![feature(autodiff)]
+
+use std::autodiff::autodiff;
+
+#[autodiff(d_square3, Forward, Dual, DualOnly)]
+#[autodiff(d_square2, Forward, 4, Dual, DualOnly)]
+#[autodiff(d_square1, Forward, 4, Dual, Dual)]
+#[no_mangle]
+fn square(x: &f32) -> f32 {
+    x * x
+}
+
+// d_sqaure2
+// CHECK: define internal fastcc [4 x float] @fwddiffe4square(float %x.0.val, [4 x ptr] %"x'")
+// CHECK-NEXT: start:
+// CHECK-NEXT:   %0 = extractvalue [4 x ptr] %"x'", 0
+// CHECK-NEXT:   %"_2'ipl" = load float, ptr %0, align 4
+// CHECK-NEXT:   %1 = extractvalue [4 x ptr] %"x'", 1
+// CHECK-NEXT:   %"_2'ipl1" = load float, ptr %1, align 4
+// CHECK-NEXT:   %2 = extractvalue [4 x ptr] %"x'", 2
+// CHECK-NEXT:   %"_2'ipl2" = load float, ptr %2, align 4
+// CHECK-NEXT:   %3 = extractvalue [4 x ptr] %"x'", 3
+// CHECK-NEXT:   %"_2'ipl3" = load float, ptr %3, align 4
+// CHECK-NEXT:   %4 = insertelement <4 x float> poison, float %"_2'ipl", i64 0
+// CHECK-NEXT:   %5 = insertelement <4 x float> %4, float %"_2'ipl1", i64 1
+// CHECK-NEXT:   %6 = insertelement <4 x float> %5, float %"_2'ipl2", i64 2
+// CHECK-NEXT:   %7 = insertelement <4 x float> %6, float %"_2'ipl3", i64 3
+// CHECK-NEXT:   %8 = fadd fast <4 x float> %7, %7
+// CHECK-NEXT:   %9 = insertelement <4 x float> poison, float %x.0.val, i64 0
+// CHECK-NEXT:   %10 = shufflevector <4 x float> %9, <4 x float> poison, <4 x i32> zeroinitializer
+// CHECK-NEXT:   %11 = fmul fast <4 x float> %8, %10
+// CHECK-NEXT:   %12 = extractelement <4 x float> %11, i64 0
+// CHECK-NEXT:   %13 = insertvalue [4 x float] undef, float %12, 0
+// CHECK-NEXT:   %14 = extractelement <4 x float> %11, i64 1
+// CHECK-NEXT:   %15 = insertvalue [4 x float] %13, float %14, 1
+// CHECK-NEXT:   %16 = extractelement <4 x float> %11, i64 2
+// CHECK-NEXT:   %17 = insertvalue [4 x float] %15, float %16, 2
+// CHECK-NEXT:   %18 = extractelement <4 x float> %11, i64 3
+// CHECK-NEXT:   %19 = insertvalue [4 x float] %17, float %18, 3
+// CHECK-NEXT:   ret [4 x float] %19
+// CHECK-NEXT: }
+
+// d_square3, the extra float is the original return value (x * x)
+// CHECK: define internal fastcc { float, [4 x float] } @fwddiffe4square.1(float %x.0.val, [4 x ptr] %"x'")
+// CHECK-NEXT: start:
+// CHECK-NEXT:   %0 = extractvalue [4 x ptr] %"x'", 0
+// CHECK-NEXT:   %"_2'ipl" = load float, ptr %0, align 4
+// CHECK-NEXT:   %1 = extractvalue [4 x ptr] %"x'", 1
+// CHECK-NEXT:   %"_2'ipl1" = load float, ptr %1, align 4
+// CHECK-NEXT:   %2 = extractvalue [4 x ptr] %"x'", 2
+// CHECK-NEXT:   %"_2'ipl2" = load float, ptr %2, align 4
+// CHECK-NEXT:   %3 = extractvalue [4 x ptr] %"x'", 3
+// CHECK-NEXT:   %"_2'ipl3" = load float, ptr %3, align 4
+// CHECK-NEXT:   %_0 = fmul float %x.0.val, %x.0.val
+// CHECK-NEXT:   %4 = insertelement <4 x float> poison, float %"_2'ipl", i64 0
+// CHECK-NEXT:   %5 = insertelement <4 x float> %4, float %"_2'ipl1", i64 1
+// CHECK-NEXT:   %6 = insertelement <4 x float> %5, float %"_2'ipl2", i64 2
+// CHECK-NEXT:   %7 = insertelement <4 x float> %6, float %"_2'ipl3", i64 3
+// CHECK-NEXT:   %8 = fadd fast <4 x float> %7, %7
+// CHECK-NEXT:   %9 = insertelement <4 x float> poison, float %x.0.val, i64 0
+// CHECK-NEXT:   %10 = shufflevector <4 x float> %9, <4 x float> poison, <4 x i32> zeroinitializer
+// CHECK-NEXT:   %11 = fmul fast <4 x float> %8, %10
+// CHECK-NEXT:   %12 = extractelement <4 x float> %11, i64 0
+// CHECK-NEXT:   %13 = insertvalue [4 x float] undef, float %12, 0
+// CHECK-NEXT:   %14 = extractelement <4 x float> %11, i64 1
+// CHECK-NEXT:   %15 = insertvalue [4 x float] %13, float %14, 1
+// CHECK-NEXT:   %16 = extractelement <4 x float> %11, i64 2
+// CHECK-NEXT:   %17 = insertvalue [4 x float] %15, float %16, 2
+// CHECK-NEXT:   %18 = extractelement <4 x float> %11, i64 3
+// CHECK-NEXT:   %19 = insertvalue [4 x float] %17, float %18, 3
+// CHECK-NEXT:   %20 = insertvalue { float, [4 x float] } undef, float %_0, 0
+// CHECK-NEXT:   %21 = insertvalue { float, [4 x float] } %20, [4 x float] %19, 1
+// CHECK-NEXT:   ret { float, [4 x float] } %21
+// CHECK-NEXT: }
+
+fn main() {
+    let x = std::hint::black_box(3.0);
+    let output = square(&x);
+    dbg!(&output);
+    assert_eq!(9.0, output);
+    dbg!(square(&x));
+
+    let mut df_dx1 = 1.0;
+    let mut df_dx2 = 2.0;
+    let mut df_dx3 = 3.0;
+    let mut df_dx4 = 0.0;
+    let [o1, o2, o3, o4] = d_square2(&x, &mut df_dx1, &mut df_dx2, &mut df_dx3, &mut df_dx4);
+    dbg!(o1, o2, o3, o4);
+    let [output2, o1, o2, o3, o4] =
+        d_square1(&x, &mut df_dx1, &mut df_dx2, &mut df_dx3, &mut df_dx4);
+    dbg!(o1, o2, o3, o4);
+    assert_eq!(output, output2);
+    assert!((6.0 - o1).abs() < 1e-10);
+    assert!((12.0 - o2).abs() < 1e-10);
+    assert!((18.0 - o3).abs() < 1e-10);
+    assert!((0.0 - o4).abs() < 1e-10);
+    assert_eq!(1.0, df_dx1);
+    assert_eq!(2.0, df_dx2);
+    assert_eq!(3.0, df_dx3);
+    assert_eq!(0.0, df_dx4);
+    assert_eq!(d_square3(&x, &mut df_dx1), 2.0 * o1);
+    assert_eq!(d_square3(&x, &mut df_dx2), 2.0 * o2);
+    assert_eq!(d_square3(&x, &mut df_dx3), 2.0 * o3);
+    assert_eq!(d_square3(&x, &mut df_dx4), 2.0 * o4);
+}
diff --git a/tests/codegen/branch-protection-old-llvm.rs b/tests/codegen/branch-protection-old-llvm.rs
deleted file mode 100644
index 14b34ac5018..00000000000
--- a/tests/codegen/branch-protection-old-llvm.rs
+++ /dev/null
@@ -1,46 +0,0 @@
-// Test that the correct module flags are emitted with different branch protection flags.
-
-//@ add-core-stubs
-//@ revisions: BTI PACRET LEAF BKEY NONE
-//@ needs-llvm-components: aarch64
-//@ [BTI] compile-flags: -Z branch-protection=bti
-//@ [PACRET] compile-flags: -Z branch-protection=pac-ret
-//@ [LEAF] compile-flags: -Z branch-protection=pac-ret,leaf
-//@ [BKEY] compile-flags: -Z branch-protection=pac-ret,b-key
-//@ compile-flags: --target aarch64-unknown-linux-gnu
-//@ max-llvm-major-version: 18
-
-#![crate_type = "lib"]
-#![feature(no_core, lang_items)]
-#![no_core]
-
-extern crate minicore;
-use minicore::*;
-
-// A basic test function.
-pub fn test() {}
-
-// BTI: !"branch-target-enforcement", i32 1
-// BTI: !"sign-return-address", i32 0
-// BTI: !"sign-return-address-all", i32 0
-// BTI: !"sign-return-address-with-bkey", i32 0
-
-// PACRET: !"branch-target-enforcement", i32 0
-// PACRET: !"sign-return-address", i32 1
-// PACRET: !"sign-return-address-all", i32 0
-// PACRET: !"sign-return-address-with-bkey", i32 0
-
-// LEAF: !"branch-target-enforcement", i32 0
-// LEAF: !"sign-return-address", i32 1
-// LEAF: !"sign-return-address-all", i32 1
-// LEAF: !"sign-return-address-with-bkey", i32 0
-
-// BKEY: !"branch-target-enforcement", i32 0
-// BKEY: !"sign-return-address", i32 1
-// BKEY: !"sign-return-address-all", i32 0
-// BKEY: !"sign-return-address-with-bkey", i32 1
-
-// NONE-NOT: branch-target-enforcement
-// NONE-NOT: sign-return-address
-// NONE-NOT: sign-return-address-all
-// NONE-NOT: sign-return-address-with-bkey
diff --git a/tests/codegen/branch-protection.rs b/tests/codegen/branch-protection.rs
index ae14eae9ae0..d67e494cc0d 100644
--- a/tests/codegen/branch-protection.rs
+++ b/tests/codegen/branch-protection.rs
@@ -12,7 +12,6 @@
 //@ [PAUTHLR_LEAF] compile-flags: -Z branch-protection=pac-ret,pc,leaf
 //@ [PAUTHLR_BTI] compile-flags: -Z branch-protection=bti,pac-ret,pc
 //@ compile-flags: --target aarch64-unknown-linux-gnu
-//@ min-llvm-version: 19
 
 #![crate_type = "lib"]
 #![feature(no_core, lang_items)]
diff --git a/tests/codegen/call-metadata.rs b/tests/codegen/call-metadata.rs
deleted file mode 100644
index 7ad3ded2f09..00000000000
--- a/tests/codegen/call-metadata.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-// Checks that range metadata gets emitted on calls to functions returning a
-// scalar value.
-
-//@ compile-flags: -Copt-level=3 -C no-prepopulate-passes
-//@ max-llvm-major-version: 18
-
-#![crate_type = "lib"]
-
-pub fn test() {
-    // CHECK: call noundef i8 @some_true(){{( #[0-9]+)?}}, !range [[R0:![0-9]+]]
-    // CHECK: [[R0]] = !{i8 0, i8 3}
-    some_true();
-}
-
-#[no_mangle]
-fn some_true() -> Option<bool> {
-    Some(true)
-}
diff --git a/tests/codegen/cast-target-abi.rs b/tests/codegen/cast-target-abi.rs
index e1a7ad718a0..cbd49e2f022 100644
--- a/tests/codegen/cast-target-abi.rs
+++ b/tests/codegen/cast-target-abi.rs
@@ -1,7 +1,6 @@
 // ignore-tidy-linelength
 //@ add-core-stubs
 //@ revisions:aarch64 loongarch64 powerpc64 sparc64 x86_64
-//@ min-llvm-version: 19
 //@ compile-flags: -Copt-level=3 -Cno-prepopulate-passes -Zlint-llvm-ir
 
 //@[aarch64] compile-flags: --target aarch64-unknown-linux-gnu
diff --git a/tests/codegen/cffi/ffi-const.rs b/tests/codegen/cffi/ffi-const.rs
index 564b8f7f8d8..6c90902e89f 100644
--- a/tests/codegen/cffi/ffi-const.rs
+++ b/tests/codegen/cffi/ffi-const.rs
@@ -9,8 +9,7 @@ pub fn bar() {
 extern "C" {
     // CHECK-LABEL: declare{{.*}}void @foo()
     // CHECK-SAME: [[ATTRS:#[0-9]+]]
-    // The attribute changed from `readnone` to `memory(none)` with LLVM 16.0.
-    // CHECK-DAG: attributes [[ATTRS]] = { {{.*}}{{readnone|memory\(none\)}}{{.*}} }
+    // CHECK-DAG: attributes [[ATTRS]] = { {{.*}}memory(none){{.*}} }
     #[ffi_const]
     pub fn foo();
 }
diff --git a/tests/codegen/cffi/ffi-out-of-bounds-loads.rs b/tests/codegen/cffi/ffi-out-of-bounds-loads.rs
index 73bc7ef6b77..859386d2df8 100644
--- a/tests/codegen/cffi/ffi-out-of-bounds-loads.rs
+++ b/tests/codegen/cffi/ffi-out-of-bounds-loads.rs
@@ -1,6 +1,5 @@
 //@ add-core-stubs
 //@ revisions: linux apple
-//@ min-llvm-version: 19
 //@ compile-flags: -Copt-level=0 -Cno-prepopulate-passes -Zlint-llvm-ir
 
 //@[linux] compile-flags: --target x86_64-unknown-linux-gnu
diff --git a/tests/codegen/cffi/ffi-pure.rs b/tests/codegen/cffi/ffi-pure.rs
index 601509d5c90..2c5d5f5b4b1 100644
--- a/tests/codegen/cffi/ffi-pure.rs
+++ b/tests/codegen/cffi/ffi-pure.rs
@@ -9,8 +9,7 @@ pub fn bar() {
 extern "C" {
     // CHECK-LABEL: declare{{.*}}void @foo()
     // CHECK-SAME: [[ATTRS:#[0-9]+]]
-    // The attribute changed from `readonly` to `memory(read)` with LLVM 16.0.
-    // CHECK-DAG: attributes [[ATTRS]] = { {{.*}}{{readonly|memory\(read\)}}{{.*}} }
+    // CHECK-DAG: attributes [[ATTRS]] = { {{.*}}memory(read){{.*}} }
     #[ffi_pure]
     pub fn foo();
 }
diff --git a/tests/codegen/char-escape-debug-no-bounds-check.rs b/tests/codegen/char-escape-debug-no-bounds-check.rs
new file mode 100644
index 00000000000..cfde46045e5
--- /dev/null
+++ b/tests/codegen/char-escape-debug-no-bounds-check.rs
@@ -0,0 +1,14 @@
+//@ compile-flags: -Copt-level=3
+#![crate_type = "lib"]
+
+use std::char::EscapeDebug;
+
+// Make sure no bounds checks are emitted when escaping a character.
+
+// CHECK-LABEL: @char_escape_debug_no_bounds_check
+#[no_mangle]
+pub fn char_escape_debug_no_bounds_check(c: char) -> EscapeDebug {
+    // CHECK-NOT: panic
+    // CHECK-NOT: panic_bounds_check
+    c.escape_debug()
+}
diff --git a/tests/codegen/debuginfo-proc-macro/mir_inlined_twice_var_locs.rs b/tests/codegen/debuginfo-proc-macro/mir_inlined_twice_var_locs.rs
index 0f6e99f9b1e..7530689d574 100644
--- a/tests/codegen/debuginfo-proc-macro/mir_inlined_twice_var_locs.rs
+++ b/tests/codegen/debuginfo-proc-macro/mir_inlined_twice_var_locs.rs
@@ -1,4 +1,3 @@
-//@ min-llvm-version: 19
 //@ compile-flags: -Cdebuginfo=2 -Copt-level=0 -Zmir-enable-passes=+Inline
 // MSVC is different because of the individual allocas.
 //@ ignore-msvc
diff --git a/tests/codegen/dont-shuffle-bswaps.rs b/tests/codegen/dont-shuffle-bswaps.rs
index 0e712bc3a4e..e100474f606 100644
--- a/tests/codegen/dont-shuffle-bswaps.rs
+++ b/tests/codegen/dont-shuffle-bswaps.rs
@@ -3,7 +3,6 @@
 //@[OPT3] compile-flags: -C opt-level=3
 // some targets don't do the opt we are looking for
 //@[OPT3] only-64bit
-//@ min-llvm-version: 18.1.3
 
 #![crate_type = "lib"]
 #![no_std]
diff --git a/tests/codegen/enum/enum-two-variants-match.rs b/tests/codegen/enum/enum-two-variants-match.rs
index c1f208d7909..21ae1f96bca 100644
--- a/tests/codegen/enum/enum-two-variants-match.rs
+++ b/tests/codegen/enum/enum-two-variants-match.rs
@@ -1,5 +1,4 @@
 //@ compile-flags: -Copt-level=3 -C no-prepopulate-passes
-//@ min-llvm-version: 19 (for trunc nuw)
 //@ only-x86_64 (because these discriminants are isize)
 
 #![crate_type = "lib"]
diff --git a/tests/codegen/float/algebraic.rs b/tests/codegen/float/algebraic.rs
new file mode 100644
index 00000000000..818a4bcdfe3
--- /dev/null
+++ b/tests/codegen/float/algebraic.rs
@@ -0,0 +1,149 @@
+// Verify that algebraic intrinsics generate the correct LLVM calls
+
+// Ensure operations get inlined
+//@ compile-flags: -Copt-level=1
+
+#![crate_type = "lib"]
+#![feature(f16)]
+#![feature(f128)]
+#![feature(float_algebraic)]
+
+// CHECK-LABEL: @f16_algebraic_add
+#[no_mangle]
+pub fn f16_algebraic_add(a: f16, b: f16) -> f16 {
+    // CHECK: fadd reassoc nsz arcp contract half %{{.+}}, %{{.+}}
+    a.algebraic_add(b)
+}
+
+// CHECK-LABEL: @f16_algebraic_sub
+#[no_mangle]
+pub fn f16_algebraic_sub(a: f16, b: f16) -> f16 {
+    // CHECK: fsub reassoc nsz arcp contract half %{{.+}}, %{{.+}}
+    a.algebraic_sub(b)
+}
+
+// CHECK-LABEL: @f16_algebraic_mul
+#[no_mangle]
+pub fn f16_algebraic_mul(a: f16, b: f16) -> f16 {
+    // CHECK: fmul reassoc nsz arcp contract half %{{.+}}, %{{.+}}
+    a.algebraic_mul(b)
+}
+
+// CHECK-LABEL: @f16_algebraic_div
+#[no_mangle]
+pub fn f16_algebraic_div(a: f16, b: f16) -> f16 {
+    // CHECK: fdiv reassoc nsz arcp contract half %{{.+}}, %{{.+}}
+    a.algebraic_div(b)
+}
+
+// CHECK-LABEL: @f16_algebraic_rem
+#[no_mangle]
+pub fn f16_algebraic_rem(a: f16, b: f16) -> f16 {
+    // CHECK: frem reassoc nsz arcp contract half %{{.+}}, %{{.+}}
+    a.algebraic_rem(b)
+}
+
+// CHECK-LABEL: @f32_algebraic_add
+#[no_mangle]
+pub fn f32_algebraic_add(a: f32, b: f32) -> f32 {
+    // CHECK: fadd reassoc nsz arcp contract float %{{.+}}, %{{.+}}
+    a.algebraic_add(b)
+}
+
+// CHECK-LABEL: @f32_algebraic_sub
+#[no_mangle]
+pub fn f32_algebraic_sub(a: f32, b: f32) -> f32 {
+    // CHECK: fsub reassoc nsz arcp contract float %{{.+}}, %{{.+}}
+    a.algebraic_sub(b)
+}
+
+// CHECK-LABEL: @f32_algebraic_mul
+#[no_mangle]
+pub fn f32_algebraic_mul(a: f32, b: f32) -> f32 {
+    // CHECK: fmul reassoc nsz arcp contract float %{{.+}}, %{{.+}}
+    a.algebraic_mul(b)
+}
+
+// CHECK-LABEL: @f32_algebraic_div
+#[no_mangle]
+pub fn f32_algebraic_div(a: f32, b: f32) -> f32 {
+    // CHECK: fdiv reassoc nsz arcp contract float %{{.+}}, %{{.+}}
+    a.algebraic_div(b)
+}
+
+// CHECK-LABEL: @f32_algebraic_rem
+#[no_mangle]
+pub fn f32_algebraic_rem(a: f32, b: f32) -> f32 {
+    // CHECK: frem reassoc nsz arcp contract float %{{.+}}, %{{.+}}
+    a.algebraic_rem(b)
+}
+
+// CHECK-LABEL: @f64_algebraic_add
+#[no_mangle]
+pub fn f64_algebraic_add(a: f64, b: f64) -> f64 {
+    // CHECK: fadd reassoc nsz arcp contract double %{{.+}}, %{{.+}}
+    a.algebraic_add(b)
+}
+
+// CHECK-LABEL: @f64_algebraic_sub
+#[no_mangle]
+pub fn f64_algebraic_sub(a: f64, b: f64) -> f64 {
+    // CHECK: fsub reassoc nsz arcp contract double %{{.+}}, %{{.+}}
+    a.algebraic_sub(b)
+}
+
+// CHECK-LABEL: @f64_algebraic_mul
+#[no_mangle]
+pub fn f64_algebraic_mul(a: f64, b: f64) -> f64 {
+    // CHECK: fmul reassoc nsz arcp contract double %{{.+}}, %{{.+}}
+    a.algebraic_mul(b)
+}
+
+// CHECK-LABEL: @f64_algebraic_div
+#[no_mangle]
+pub fn f64_algebraic_div(a: f64, b: f64) -> f64 {
+    // CHECK: fdiv reassoc nsz arcp contract double %{{.+}}, %{{.+}}
+    a.algebraic_div(b)
+}
+
+// CHECK-LABEL: @f64_algebraic_rem
+#[no_mangle]
+pub fn f64_algebraic_rem(a: f64, b: f64) -> f64 {
+    // CHECK: frem reassoc nsz arcp contract double %{{.+}}, %{{.+}}
+    a.algebraic_rem(b)
+}
+
+// CHECK-LABEL: @f128_algebraic_add
+#[no_mangle]
+pub fn f128_algebraic_add(a: f128, b: f128) -> f128 {
+    // CHECK: fadd reassoc nsz arcp contract fp128 %{{.+}}, %{{.+}}
+    a.algebraic_add(b)
+}
+
+// CHECK-LABEL: @f128_algebraic_sub
+#[no_mangle]
+pub fn f128_algebraic_sub(a: f128, b: f128) -> f128 {
+    // CHECK: fsub reassoc nsz arcp contract fp128 %{{.+}}, %{{.+}}
+    a.algebraic_sub(b)
+}
+
+// CHECK-LABEL: @f128_algebraic_mul
+#[no_mangle]
+pub fn f128_algebraic_mul(a: f128, b: f128) -> f128 {
+    // CHECK: fmul reassoc nsz arcp contract fp128 %{{.+}}, %{{.+}}
+    a.algebraic_mul(b)
+}
+
+// CHECK-LABEL: @f128_algebraic_div
+#[no_mangle]
+pub fn f128_algebraic_div(a: f128, b: f128) -> f128 {
+    // CHECK: fdiv reassoc nsz arcp contract fp128 %{{.+}}, %{{.+}}
+    a.algebraic_div(b)
+}
+
+// CHECK-LABEL: @f128_algebraic_rem
+#[no_mangle]
+pub fn f128_algebraic_rem(a: f128, b: f128) -> f128 {
+    // CHECK: frem reassoc nsz arcp contract fp128 %{{.+}}, %{{.+}}
+    a.algebraic_rem(b)
+}
diff --git a/tests/codegen/float_math.rs b/tests/codegen/float_math.rs
index 31387ec82b9..9a1e0b4d2d0 100644
--- a/tests/codegen/float_math.rs
+++ b/tests/codegen/float_math.rs
@@ -3,7 +3,10 @@
 #![crate_type = "lib"]
 #![feature(core_intrinsics)]
 
-use std::intrinsics::{fadd_fast, fdiv_fast, fmul_fast, frem_fast, fsub_fast};
+use std::intrinsics::{
+    fadd_algebraic, fadd_fast, fdiv_algebraic, fdiv_fast, fmul_algebraic, fmul_fast,
+    frem_algebraic, frem_fast, fsub_algebraic, fsub_fast,
+};
 
 // CHECK-LABEL: @add
 #[no_mangle]
@@ -13,30 +16,72 @@ pub fn add(x: f32, y: f32) -> f32 {
     x + y
 }
 
-// CHECK-LABEL: @addition
+// CHECK-LABEL: @test_fadd_algebraic
 #[no_mangle]
-pub fn addition(x: f32, y: f32) -> f32 {
-    // CHECK: fadd fast float
+pub fn test_fadd_algebraic(x: f32, y: f32) -> f32 {
+    // CHECK: fadd reassoc nsz arcp contract float %x, %y
+    fadd_algebraic(x, y)
+}
+
+// CHECK-LABEL: @test_fsub_algebraic
+#[no_mangle]
+pub fn test_fsub_algebraic(x: f32, y: f32) -> f32 {
+    // CHECK: fsub reassoc nsz arcp contract float %x, %y
+    fsub_algebraic(x, y)
+}
+
+// CHECK-LABEL: @test_fmul_algebraic
+#[no_mangle]
+pub fn test_fmul_algebraic(x: f32, y: f32) -> f32 {
+    // CHECK: fmul reassoc nsz arcp contract float %x, %y
+    fmul_algebraic(x, y)
+}
+
+// CHECK-LABEL: @test_fdiv_algebraic
+#[no_mangle]
+pub fn test_fdiv_algebraic(x: f32, y: f32) -> f32 {
+    // CHECK: fdiv reassoc nsz arcp contract float %x, %y
+    fdiv_algebraic(x, y)
+}
+
+// CHECK-LABEL: @test_frem_algebraic
+#[no_mangle]
+pub fn test_frem_algebraic(x: f32, y: f32) -> f32 {
+    // CHECK: frem reassoc nsz arcp contract float %x, %y
+    frem_algebraic(x, y)
+}
+
+// CHECK-LABEL: @test_fadd_fast
+#[no_mangle]
+pub fn test_fadd_fast(x: f32, y: f32) -> f32 {
+    // CHECK: fadd fast float %x, %y
     unsafe { fadd_fast(x, y) }
 }
 
-// CHECK-LABEL: @subtraction
+// CHECK-LABEL: @test_fsub_fast
 #[no_mangle]
-pub fn subtraction(x: f32, y: f32) -> f32 {
-    // CHECK: fsub fast float
+pub fn test_fsub_fast(x: f32, y: f32) -> f32 {
+    // CHECK: fsub fast float %x, %y
     unsafe { fsub_fast(x, y) }
 }
 
-// CHECK-LABEL: @multiplication
+// CHECK-LABEL: @test_fmul_fast
 #[no_mangle]
-pub fn multiplication(x: f32, y: f32) -> f32 {
-    // CHECK: fmul fast float
+pub fn test_fmul_fast(x: f32, y: f32) -> f32 {
+    // CHECK: fmul fast float %x, %y
     unsafe { fmul_fast(x, y) }
 }
 
-// CHECK-LABEL: @division
+// CHECK-LABEL: @test_fdiv_fast
 #[no_mangle]
-pub fn division(x: f32, y: f32) -> f32 {
-    // CHECK: fdiv fast float
+pub fn test_fdiv_fast(x: f32, y: f32) -> f32 {
+    // CHECK: fdiv fast float %x, %y
     unsafe { fdiv_fast(x, y) }
 }
+
+// CHECK-LABEL: @test_frem_fast
+#[no_mangle]
+pub fn test_frem_fast(x: f32, y: f32) -> f32 {
+    // CHECK: frem fast float %x, %y
+    unsafe { frem_fast(x, y) }
+}
diff --git a/tests/codegen/intrinsics/carrying_mul_add.rs b/tests/codegen/intrinsics/carrying_mul_add.rs
index b53585a8a6e..21fb49a3786 100644
--- a/tests/codegen/intrinsics/carrying_mul_add.rs
+++ b/tests/codegen/intrinsics/carrying_mul_add.rs
@@ -1,7 +1,6 @@
 //@ revisions: RAW OPT
 //@ compile-flags: -C opt-level=1
 //@[RAW] compile-flags: -C no-prepopulate-passes
-//@[OPT] min-llvm-version: 19
 
 #![crate_type = "lib"]
 #![feature(core_intrinsics)]
diff --git a/tests/codegen/intrinsics/transmute.rs b/tests/codegen/intrinsics/transmute.rs
index 4849b88c09c..560ebcccdd0 100644
--- a/tests/codegen/intrinsics/transmute.rs
+++ b/tests/codegen/intrinsics/transmute.rs
@@ -12,9 +12,6 @@ use std::intrinsics::{transmute, transmute_unchecked};
 use std::mem::MaybeUninit;
 use std::num::NonZero;
 
-// FIXME(LLVM18REMOVED): `trunc nuw` doesn't exist in LLVM 18, so once we no
-// longer support it the optional flag checks can be changed to required.
-
 pub enum ZstNever {}
 
 #[repr(align(2))]
@@ -157,7 +154,7 @@ pub unsafe fn check_from_newtype(x: Scalar64) -> u64 {
 pub unsafe fn check_aggregate_to_bool(x: Aggregate8) -> bool {
     // CHECK: %x = alloca [1 x i8], align 1
     // CHECK: %[[BYTE:.+]] = load i8, ptr %x, align 1
-    // CHECK: %[[BOOL:.+]] = trunc{{( nuw)?}} i8 %[[BYTE]] to i1
+    // CHECK: %[[BOOL:.+]] = trunc nuw i8 %[[BYTE]] to i1
     // CHECK: ret i1 %[[BOOL]]
     transmute(x)
 }
@@ -175,7 +172,7 @@ pub unsafe fn check_aggregate_from_bool(x: bool) -> Aggregate8 {
 #[no_mangle]
 pub unsafe fn check_byte_to_bool(x: u8) -> bool {
     // CHECK-NOT: alloca
-    // CHECK: %[[R:.+]] = trunc{{( nuw)?}} i8 %x to i1
+    // CHECK: %[[R:.+]] = trunc nuw i8 %x to i1
     // CHECK: ret i1 %[[R]]
     transmute(x)
 }
@@ -288,7 +285,7 @@ pub unsafe fn check_long_array_more_aligned(x: [u8; 100]) -> [u32; 25] {
 #[no_mangle]
 pub unsafe fn check_pair_with_bool(x: (u8, bool)) -> (bool, i8) {
     // CHECK-NOT: alloca
-    // CHECK: trunc{{( nuw)?}} i8 %x.0 to i1
+    // CHECK: trunc nuw i8 %x.0 to i1
     // CHECK: zext i1 %x.1 to i8
     transmute(x)
 }
@@ -342,7 +339,7 @@ pub unsafe fn check_heterogeneous_integer_pair(x: (i32, bool)) -> (bool, u32) {
     // CHECK: store i8 %[[WIDER]]
 
     // CHECK: %[[BYTE:.+]] = load i8
-    // CHECK: trunc{{( nuw)?}} i8 %[[BYTE:.+]] to i1
+    // CHECK: trunc nuw i8 %[[BYTE:.+]] to i1
     // CHECK: load i32
     transmute(x)
 }
diff --git a/tests/codegen/issues/issue-107681-unwrap_unchecked.rs b/tests/codegen/issues/issue-107681-unwrap_unchecked.rs
index fd7296de4c8..69aefc6b1fb 100644
--- a/tests/codegen/issues/issue-107681-unwrap_unchecked.rs
+++ b/tests/codegen/issues/issue-107681-unwrap_unchecked.rs
@@ -1,5 +1,4 @@
 //@ compile-flags: -Copt-level=3
-//@ min-llvm-version: 19
 
 // Test for #107681.
 // Make sure we don't create `br` or `select` instructions.
diff --git a/tests/codegen/issues/issue-118306.rs b/tests/codegen/issues/issue-118306.rs
index f9f3e0c0529..f12dc7cdfe2 100644
--- a/tests/codegen/issues/issue-118306.rs
+++ b/tests/codegen/issues/issue-118306.rs
@@ -1,5 +1,4 @@
 //@ compile-flags: -Copt-level=3
-//@ min-llvm-version: 19
 //@ only-x86_64
 
 // Test for #118306.
diff --git a/tests/codegen/issues/issue-122600-ptr-discriminant-update.rs b/tests/codegen/issues/issue-122600-ptr-discriminant-update.rs
index fbea4ee8979..853a1ff36b1 100644
--- a/tests/codegen/issues/issue-122600-ptr-discriminant-update.rs
+++ b/tests/codegen/issues/issue-122600-ptr-discriminant-update.rs
@@ -1,5 +1,4 @@
 //@ compile-flags: -Copt-level=3
-//@ min-llvm-version: 19
 
 #![crate_type = "lib"]
 
@@ -37,6 +36,8 @@ pub unsafe fn update(s: *mut State) {
     // CHECK-NOT: store
     // CHECK-NOT: memcpy
     // CHECK-NOT: 75{{3|4}}
+
+    // CHECK: ret
     let State::A(v) = s.read() else { std::hint::unreachable_unchecked() };
     s.write(State::B(v));
 }
diff --git a/tests/codegen/issues/issue-126585.rs b/tests/codegen/issues/issue-126585.rs
index a468efd728d..466dab64cdc 100644
--- a/tests/codegen/issues/issue-126585.rs
+++ b/tests/codegen/issues/issue-126585.rs
@@ -1,5 +1,4 @@
 //@ compile-flags: -Copt-level=s
-//@ min-llvm-version: 19
 //@ only-x86_64
 
 // Test for #126585.
diff --git a/tests/codegen/range-attribute.rs b/tests/codegen/range-attribute.rs
index e23f5e6bb74..b81ff9ab3e2 100644
--- a/tests/codegen/range-attribute.rs
+++ b/tests/codegen/range-attribute.rs
@@ -6,7 +6,6 @@
 //@[bit32] only-32bit
 //@[bit64] only-64bit
 //@ compile-flags: -Copt-level=3 -C no-prepopulate-passes
-//@ min-llvm-version: 19
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/sanitizer/kcfi/add-kcfi-arity-flag.rs b/tests/codegen/sanitizer/kcfi/add-kcfi-arity-flag.rs
new file mode 100644
index 00000000000..9a2290901d6
--- /dev/null
+++ b/tests/codegen/sanitizer/kcfi/add-kcfi-arity-flag.rs
@@ -0,0 +1,19 @@
+// Verifies that "kcfi-arity" module flag is added.
+//
+//@ add-core-stubs
+//@ revisions: x86_64
+//@ [x86_64] compile-flags: --target x86_64-unknown-none
+//@ [x86_64] needs-llvm-components: x86
+//@ compile-flags: -Ctarget-feature=-crt-static -Cpanic=abort -Zsanitizer=kcfi -Zsanitizer-kcfi-arity
+//@ min-llvm-version: 21.0.0
+
+#![feature(no_core, lang_items)]
+#![crate_type = "lib"]
+#![no_core]
+
+extern crate minicore;
+use minicore::*;
+
+pub fn foo() {}
+
+// CHECK: !{{[0-9]+}} = !{i32 4, !"kcfi-arity", i32 1}
diff --git a/tests/codegen/tied-features-strength.rs b/tests/codegen/tied-features-strength.rs
index 8b1f3b14fc3..6be0e21e0ef 100644
--- a/tests/codegen/tied-features-strength.rs
+++ b/tests/codegen/tied-features-strength.rs
@@ -4,21 +4,17 @@
 //@ compile-flags: --crate-type=rlib --target=aarch64-unknown-linux-gnu
 //@ needs-llvm-components: aarch64
 
-// The "+fpmr" feature is matched as optional as it is only an explicit
-// feature in LLVM 18. Once the min supported version is LLVM-19 the optional
-// regex matching for this feature can be removed.
-
 //@ [ENABLE_SVE] compile-flags: -C target-feature=+sve -Copt-level=0
-// ENABLE_SVE: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)|(\+fpmr,?)?|(\+sve,?)|(\+neon,?)|(\+fp-armv8,?))*}}" }
+// ENABLE_SVE: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)|(\+sve,?)|(\+neon,?)|(\+fp-armv8,?))*}}" }
 
 //@ [DISABLE_SVE] compile-flags: -C target-feature=-sve -Copt-level=0
-// DISABLE_SVE: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)|(\+fpmr,?)?|(-sve,?)|(\+neon,?))*}}" }
+// DISABLE_SVE: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)|(-sve,?)|(\+neon,?))*}}" }
 
 //@ [DISABLE_NEON] compile-flags: -C target-feature=-neon -Copt-level=0
-// DISABLE_NEON: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)|(\+fpmr,?)?|(-fp-armv8,?)|(-neon,?))*}}" }
+// DISABLE_NEON: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)|(-fp-armv8,?)|(-neon,?))*}}" }
 
 //@ [ENABLE_NEON] compile-flags: -C target-feature=+neon -Copt-level=0
-// ENABLE_NEON: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)|(\+fpmr,?)?|(\+fp-armv8,?)|(\+neon,?))*}}" }
+// ENABLE_NEON: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)|(\+fp-armv8,?)|(\+neon,?))*}}" }
 
 #![feature(no_core, lang_items)]
 #![no_core]
diff --git a/tests/codegen/try_question_mark_nop.rs b/tests/codegen/try_question_mark_nop.rs
index 9430465a286..9f68d742a75 100644
--- a/tests/codegen/try_question_mark_nop.rs
+++ b/tests/codegen/try_question_mark_nop.rs
@@ -1,10 +1,8 @@
 //@ compile-flags: -Copt-level=3 -Z merge-functions=disabled --edition=2021
 //@ only-x86_64
-// FIXME: Remove the `min-llvm-version`.
 //@ revisions: NINETEEN TWENTY
 //@[NINETEEN] exact-llvm-major-version: 19
 //@[TWENTY] min-llvm-version: 20
-//@ min-llvm-version: 19
 
 #![crate_type = "lib"]
 #![feature(try_blocks)]
diff --git a/tests/codegen/unchecked_shifts.rs b/tests/codegen/unchecked_shifts.rs
index 9fccaf2252e..3f533718a2d 100644
--- a/tests/codegen/unchecked_shifts.rs
+++ b/tests/codegen/unchecked_shifts.rs
@@ -1,7 +1,4 @@
-//@ revisions: LLVM18 LLVM19PLUS
 //@ compile-flags: -Copt-level=3 -C no-prepopulate-passes
-//@[LLVM18] exact-llvm-major-version: 18
-//@[LLVM19PLUS] min-llvm-version: 19
 
 // This runs mir-opts to inline the standard library call, but doesn't run LLVM
 // optimizations so it doesn't need to worry about them adding more flags.
@@ -24,8 +21,7 @@ pub unsafe fn unchecked_shl_unsigned_same(a: u32, b: u32) -> u32 {
 #[no_mangle]
 pub unsafe fn unchecked_shl_unsigned_smaller(a: u16, b: u32) -> u16 {
     // CHECK-NOT: assume
-    // LLVM18: %[[TRUNC:.+]] = trunc i32 %b to i16
-    // LLVM19PLUS: %[[TRUNC:.+]] = trunc nuw i32 %b to i16
+    // CHECK: %[[TRUNC:.+]] = trunc nuw i32 %b to i16
     // CHECK: shl i16 %a, %[[TRUNC]]
     a.unchecked_shl(b)
 }
@@ -53,8 +49,7 @@ pub unsafe fn unchecked_shr_signed_same(a: i32, b: u32) -> i32 {
 #[no_mangle]
 pub unsafe fn unchecked_shr_signed_smaller(a: i16, b: u32) -> i16 {
     // CHECK-NOT: assume
-    // LLVM18: %[[TRUNC:.+]] = trunc i32 %b to i16
-    // LLVM19PLUS: %[[TRUNC:.+]] = trunc nuw i32 %b to i16
+    // CHECK: %[[TRUNC:.+]] = trunc nuw i32 %b to i16
     // CHECK: ashr i16 %a, %[[TRUNC]]
     a.unchecked_shr(b)
 }
@@ -90,8 +85,7 @@ pub unsafe fn unchecked_shl_i128_u8(a: i128, b: u8) -> i128 {
 #[no_mangle]
 pub unsafe fn unchecked_shl_u8_i128(a: u8, b: i128) -> u8 {
     // CHECK-NOT: assume
-    // LLVM18: %[[TRUNC:.+]] = trunc i128 %b to i8
-    // LLVM19PLUS: %[[TRUNC:.+]] = trunc nuw i128 %b to i8
+    // CHECK: %[[TRUNC:.+]] = trunc nuw i128 %b to i8
     // CHECK: shl i8 %a, %[[TRUNC]]
     std::intrinsics::unchecked_shl(a, b)
 }
@@ -100,8 +94,7 @@ pub unsafe fn unchecked_shl_u8_i128(a: u8, b: i128) -> u8 {
 #[no_mangle]
 pub unsafe fn unchecked_shr_i8_u128(a: i8, b: u128) -> i8 {
     // CHECK-NOT: assume
-    // LLVM18: %[[TRUNC:.+]] = trunc i128 %b to i8
-    // LLVM19PLUS: %[[TRUNC:.+]] = trunc nuw i128 %b to i8
+    // CHECK: %[[TRUNC:.+]] = trunc nuw i128 %b to i8
     // CHECK: ashr i8 %a, %[[TRUNC]]
     std::intrinsics::unchecked_shr(a, b)
 }
diff --git a/tests/codegen/vec_pop_push_noop.rs b/tests/codegen/vec_pop_push_noop.rs
index 2635660596a..3e375219fe0 100644
--- a/tests/codegen/vec_pop_push_noop.rs
+++ b/tests/codegen/vec_pop_push_noop.rs
@@ -1,6 +1,3 @@
-//@ revisions: llvm-pre-19 llvm-19
-//@ [llvm-19] min-llvm-version: 19
-//@ [llvm-pre-19] max-llvm-major-version: 18
 //@ compile-flags: -Copt-level=3
 
 #![crate_type = "lib"]