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/aarch64-softfloat.rs48
-rw-r--r--tests/codegen/asm/arm64ec-clobbers.rs2
-rw-r--r--tests/codegen/asm/s390x-clobbers.rs2
-rw-r--r--tests/codegen/branch-protection-old-llvm.rs2
-rw-r--r--tests/codegen/call-metadata.rs2
-rw-r--r--tests/codegen/checked_math.rs2
-rw-r--r--tests/codegen/debuginfo-proc-macro/auxiliary/macro_def.rs11
-rw-r--r--tests/codegen/debuginfo-proc-macro/mir_inlined_twice_var_locs.rs53
-rw-r--r--tests/codegen/float/f16-f128-inline.rs29
-rw-r--r--tests/codegen/function-arguments.rs24
-rw-r--r--tests/codegen/integer-cmp.rs2
-rw-r--r--tests/codegen/intrinsics/cold_path.rs13
-rw-r--r--tests/codegen/intrinsics/likely.rs37
-rw-r--r--tests/codegen/intrinsics/likely_assert.rs17
-rw-r--r--tests/codegen/intrinsics/unlikely.rs35
-rw-r--r--tests/codegen/sanitizer/cfi/dbg-location-on-cfi-blocks.rs19
-rw-r--r--tests/codegen/sanitizer/no-sanitize.rs10
-rw-r--r--tests/codegen/try_question_mark_nop.rs10
18 files changed, 295 insertions, 23 deletions
diff --git a/tests/codegen/aarch64-softfloat.rs b/tests/codegen/aarch64-softfloat.rs
new file mode 100644
index 00000000000..14d0054f80c
--- /dev/null
+++ b/tests/codegen/aarch64-softfloat.rs
@@ -0,0 +1,48 @@
+//@ compile-flags: --target aarch64-unknown-none-softfloat -Zmerge-functions=disabled
+//@ needs-llvm-components: aarch64
+#![crate_type = "lib"]
+#![feature(no_core, lang_items)]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+#[lang = "copy"]
+trait Copy {}
+impl Copy for f32 {}
+impl Copy for f64 {}
+
+// CHECK: i64 @pass_f64_C(i64 {{[^,]*}})
+#[no_mangle]
+extern "C" fn pass_f64_C(x: f64) -> f64 {
+    x
+}
+
+// CHECK: i64 @pass_f32_pair_C(i64 {{[^,]*}})
+#[no_mangle]
+extern "C" fn pass_f32_pair_C(x: (f32, f32)) -> (f32, f32) {
+    x
+}
+
+// CHECK: [2 x i64] @pass_f64_pair_C([2 x i64] {{[^,]*}})
+#[no_mangle]
+extern "C" fn pass_f64_pair_C(x: (f64, f64)) -> (f64, f64) {
+    x
+}
+
+// CHECK: i64 @pass_f64_Rust(i64 {{[^,]*}})
+#[no_mangle]
+fn pass_f64_Rust(x: f64) -> f64 {
+    x
+}
+
+// CHECK: i64 @pass_f32_pair_Rust(i64 {{[^,]*}})
+#[no_mangle]
+fn pass_f32_pair_Rust(x: (f32, f32)) -> (f32, f32) {
+    x
+}
+
+// CHECK: void @pass_f64_pair_Rust(ptr {{[^,]*}}, ptr {{[^,]*}})
+#[no_mangle]
+fn pass_f64_pair_Rust(x: (f64, f64)) -> (f64, f64) {
+    x
+}
diff --git a/tests/codegen/asm/arm64ec-clobbers.rs b/tests/codegen/asm/arm64ec-clobbers.rs
index 2ec61907947..80059331642 100644
--- a/tests/codegen/asm/arm64ec-clobbers.rs
+++ b/tests/codegen/asm/arm64ec-clobbers.rs
@@ -3,7 +3,7 @@
 //@ needs-llvm-components: aarch64
 
 #![crate_type = "rlib"]
-#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)]
+#![feature(no_core, rustc_attrs, lang_items)]
 #![no_core]
 
 #[lang = "sized"]
diff --git a/tests/codegen/asm/s390x-clobbers.rs b/tests/codegen/asm/s390x-clobbers.rs
index 45f72206bdf..56d82b4b044 100644
--- a/tests/codegen/asm/s390x-clobbers.rs
+++ b/tests/codegen/asm/s390x-clobbers.rs
@@ -3,7 +3,7 @@
 //@[s390x] needs-llvm-components: systemz
 
 #![crate_type = "rlib"]
-#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)]
+#![feature(no_core, rustc_attrs, lang_items)]
 #![no_core]
 
 #[lang = "sized"]
diff --git a/tests/codegen/branch-protection-old-llvm.rs b/tests/codegen/branch-protection-old-llvm.rs
index bb3c7a4b70c..1846f35479d 100644
--- a/tests/codegen/branch-protection-old-llvm.rs
+++ b/tests/codegen/branch-protection-old-llvm.rs
@@ -7,7 +7,7 @@
 //@ [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
-//@ ignore-llvm-version: 19 - 99
+//@ max-llvm-major-version: 18
 
 #![crate_type = "lib"]
 #![feature(no_core, lang_items)]
diff --git a/tests/codegen/call-metadata.rs b/tests/codegen/call-metadata.rs
index 73c4b33e2cf..b986b4467fa 100644
--- a/tests/codegen/call-metadata.rs
+++ b/tests/codegen/call-metadata.rs
@@ -2,7 +2,7 @@
 // scalar value.
 
 //@ compile-flags: -O -C no-prepopulate-passes
-//@ ignore-llvm-version: 19 - 99
+//@ max-llvm-major-version: 18
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/checked_math.rs b/tests/codegen/checked_math.rs
index 63f5c3d34f7..c612ddccdaa 100644
--- a/tests/codegen/checked_math.rs
+++ b/tests/codegen/checked_math.rs
@@ -90,7 +90,7 @@ pub fn checked_shr_signed(a: i32, b: u32) -> Option<i32> {
 #[no_mangle]
 pub fn checked_add_one_unwrap_unsigned(x: u32) -> u32 {
     // CHECK: %[[IS_MAX:.+]] = icmp eq i32 %x, -1
-    // CHECK: br i1 %[[IS_MAX]], label %[[NONE_BB:.+]], label %[[SOME_BB:.+]]
+    // CHECK: br i1 %[[IS_MAX]], label %[[NONE_BB:.+]], label %[[SOME_BB:.+]],
     // CHECK: [[SOME_BB]]:
     // CHECK: %[[R:.+]] = add nuw i32 %x, 1
     // CHECK: ret i32 %[[R]]
diff --git a/tests/codegen/debuginfo-proc-macro/auxiliary/macro_def.rs b/tests/codegen/debuginfo-proc-macro/auxiliary/macro_def.rs
new file mode 100644
index 00000000000..159ecfd0974
--- /dev/null
+++ b/tests/codegen/debuginfo-proc-macro/auxiliary/macro_def.rs
@@ -0,0 +1,11 @@
+//@ force-host
+//@ no-prefer-dynamic
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+use proc_macro::*;
+
+#[proc_macro]
+pub fn square_twice(_item: TokenStream) -> TokenStream {
+    "(square(env::vars().count() as i32), square(env::vars().count() as i32))".parse().unwrap()
+}
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
new file mode 100644
index 00000000000..c3858044c0c
--- /dev/null
+++ b/tests/codegen/debuginfo-proc-macro/mir_inlined_twice_var_locs.rs
@@ -0,0 +1,53 @@
+//@ 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
+
+//@ aux-build:macro_def.rs
+
+// Find the variable.
+// CHECK-DAG: ![[#var_dbg:]] = !DILocalVariable(name: "n",{{( arg: 1,)?}} scope: ![[#var_scope:]]
+
+// Find both dbg_declares. These will proceed the variable metadata, of course, so we're looking
+// backwards.
+// CHECK-DAG: dbg_declare(ptr %n.dbg.spill{{[0-9]}}, ![[#var_dbg]], !DIExpression(), ![[#var_loc2:]])
+// CHECK-DAG: dbg_declare(ptr %n.dbg.spill, ![[#var_dbg]], !DIExpression(), ![[#var_loc1:]])
+
+// Find the first location definition, looking forwards again.
+// CHECK: ![[#var_loc1]] = !DILocation
+// CHECK-SAME: scope: ![[#var_scope:]], inlinedAt: ![[#var_inlinedAt1:]]
+
+// Find the first location's inlinedAt
+// NB: If we fail here it's *probably* because we failed to produce two
+// different locations and ended up reusing an earlier one.
+// CHECK: ![[#var_inlinedAt1]] = !DILocation
+// CHECK-SAME: scope: ![[var_inlinedAt1_scope:]]
+
+// Find the second location definition, still looking forwards.
+// NB: If we failed to produce two different locations, the test will
+// definitely fail by this point (if it hasn't already) because we won't
+// be able to find the same line again.
+// CHECK: ![[#var_loc2]] = !DILocation
+// CHECK-SAME: scope: ![[#var_scope]], inlinedAt: ![[#var_inlinedAt2:]]
+
+// Find the second location's inlinedAt.
+// CHECK: ![[#var_inlinedAt2]] = !DILocation
+// CHECK-SAME: scope: ![[#var_inlinedAt2_scope:]]
+
+// Finally, check that a discriminator was emitted for the second scope.
+// FIXMEkhuey ideally we would check that *either* scope has a discriminator
+// but I don't know that it's possible to check that with FileCheck.
+// CHECK: ![[#var_inlinedAt2_scope]] = !DILexicalBlockFile
+// CHECK-SAME: discriminator: [[#]]
+extern crate macro_def;
+
+use std::env;
+
+fn square(n: i32) -> i32 {
+    n * n
+}
+
+fn main() {
+    let (z1, z2) = macro_def::square_twice!();
+    println!("{z1} == {z2}");
+}
diff --git a/tests/codegen/float/f16-f128-inline.rs b/tests/codegen/float/f16-f128-inline.rs
new file mode 100644
index 00000000000..aa2c38c209e
--- /dev/null
+++ b/tests/codegen/float/f16-f128-inline.rs
@@ -0,0 +1,29 @@
+//@ revisions: default nopt
+//@[nopt] compile-flags: -Copt-level=0 -Zcross-crate-inline-threshold=never -Zmir-opt-level=0 -Cno-prepopulate-passes
+
+// Ensure that functions using `f16` and `f128` are always inlined to avoid crashes
+// when the backend does not support these types.
+
+#![crate_type = "lib"]
+#![feature(f128)]
+#![feature(f16)]
+
+pub fn f16_arg(_a: f16) {
+    // CHECK-NOT: f16_arg
+    todo!()
+}
+
+pub fn f16_ret() -> f16 {
+    // CHECK-NOT: f16_ret
+    todo!()
+}
+
+pub fn f128_arg(_a: f128) {
+    // CHECK-NOT: f128_arg
+    todo!()
+}
+
+pub fn f128_ret() -> f128 {
+    // CHECK-NOT: f128_ret
+    todo!()
+}
diff --git a/tests/codegen/function-arguments.rs b/tests/codegen/function-arguments.rs
index 7fa1d659885..503799d3ed2 100644
--- a/tests/codegen/function-arguments.rs
+++ b/tests/codegen/function-arguments.rs
@@ -1,5 +1,6 @@
 //@ compile-flags: -O -C no-prepopulate-passes
 #![crate_type = "lib"]
+#![feature(rustc_attrs)]
 #![feature(dyn_star)]
 #![feature(allocator_api)]
 
@@ -143,13 +144,28 @@ pub fn indirect_struct(_: S) {}
 #[no_mangle]
 pub fn borrowed_struct(_: &S) {}
 
-// CHECK: @option_borrow(ptr noalias noundef readonly align 4 dereferenceable_or_null(4) %x)
+// CHECK: @option_borrow(ptr noalias noundef readonly align 4 dereferenceable_or_null(4) %_x)
 #[no_mangle]
-pub fn option_borrow(x: Option<&i32>) {}
+pub fn option_borrow(_x: Option<&i32>) {}
 
-// CHECK: @option_borrow_mut(ptr noalias noundef align 4 dereferenceable_or_null(4) %x)
+// CHECK: @option_borrow_mut(ptr noalias noundef align 4 dereferenceable_or_null(4) %_x)
 #[no_mangle]
-pub fn option_borrow_mut(x: Option<&mut i32>) {}
+pub fn option_borrow_mut(_x: Option<&mut i32>) {}
+
+// Function that must NOT have `dereferenceable` or `align`.
+#[rustc_layout_scalar_valid_range_start(16)]
+pub struct RestrictedAddress(&'static i16);
+enum E {
+    A(RestrictedAddress),
+    B,
+    C,
+}
+// If the `nonnull` ever goes missing, you might have to tweak the
+// scalar_valid_range on `RestrictedAddress` to get it back. You
+// might even have to add a `rustc_layout_scalar_valid_range_end`.
+// CHECK: @nonnull_and_nondereferenceable(ptr noundef nonnull %_x)
+#[no_mangle]
+pub fn nonnull_and_nondereferenceable(_x: E) {}
 
 // CHECK: @raw_struct(ptr noundef %_1)
 #[no_mangle]
diff --git a/tests/codegen/integer-cmp.rs b/tests/codegen/integer-cmp.rs
index 8df68d8d490..9bbf243946d 100644
--- a/tests/codegen/integer-cmp.rs
+++ b/tests/codegen/integer-cmp.rs
@@ -3,7 +3,7 @@
 
 //@ revisions: llvm-pre-20 llvm-20
 //@ [llvm-20] min-llvm-version: 20
-//@ [llvm-pre-20] ignore-llvm-version: 20 - 99
+//@ [llvm-pre-20] max-llvm-major-version: 19
 //@ compile-flags: -C opt-level=3
 
 #![crate_type = "lib"]
diff --git a/tests/codegen/intrinsics/cold_path.rs b/tests/codegen/intrinsics/cold_path.rs
new file mode 100644
index 00000000000..24ee84e07bf
--- /dev/null
+++ b/tests/codegen/intrinsics/cold_path.rs
@@ -0,0 +1,13 @@
+//@ compile-flags: -O
+#![crate_type = "lib"]
+#![feature(core_intrinsics)]
+
+use std::intrinsics::cold_path;
+
+#[no_mangle]
+pub fn test_cold_path(x: bool) {
+    cold_path();
+}
+
+// CHECK-LABEL: @test_cold_path(
+// CHECK-NOT: cold_path
diff --git a/tests/codegen/intrinsics/likely.rs b/tests/codegen/intrinsics/likely.rs
index 9dc31d21045..e318390db20 100644
--- a/tests/codegen/intrinsics/likely.rs
+++ b/tests/codegen/intrinsics/likely.rs
@@ -1,22 +1,35 @@
-//@ compile-flags: -C no-prepopulate-passes -Copt-level=1
-
+//@ compile-flags: -O
 #![crate_type = "lib"]
 #![feature(core_intrinsics)]
 
-use std::intrinsics::{likely, unlikely};
+use std::intrinsics::likely;
 
+#[inline(never)]
 #[no_mangle]
-pub fn check_likely(x: i32, y: i32) -> Option<i32> {
-    unsafe {
-        // CHECK: call i1 @llvm.expect.i1(i1 %{{.*}}, i1 true)
-        if likely(x == y) { None } else { Some(x + y) }
-    }
+pub fn path_a() {
+    println!("path a");
+}
+
+#[inline(never)]
+#[no_mangle]
+pub fn path_b() {
+    println!("path b");
 }
 
 #[no_mangle]
-pub fn check_unlikely(x: i32, y: i32) -> Option<i32> {
-    unsafe {
-        // CHECK: call i1 @llvm.expect.i1(i1 %{{.*}}, i1 false)
-        if unlikely(x == y) { None } else { Some(x + y) }
+pub fn test_likely(x: bool) {
+    if likely(x) {
+        path_a();
+    } else {
+        path_b();
     }
 }
+
+// CHECK-LABEL: @test_likely(
+// CHECK: br i1 %x, label %bb2, label %bb3, !prof ![[NUM:[0-9]+]]
+// CHECK: bb3:
+// CHECK-NOT: cold_path
+// CHECK: path_b
+// CHECK: bb2:
+// CHECK: path_a
+// CHECK: ![[NUM]] = !{!"branch_weights", {{(!"expected", )?}}i32 2000, i32 1}
diff --git a/tests/codegen/intrinsics/likely_assert.rs b/tests/codegen/intrinsics/likely_assert.rs
new file mode 100644
index 00000000000..0ddbd6206ae
--- /dev/null
+++ b/tests/codegen/intrinsics/likely_assert.rs
@@ -0,0 +1,17 @@
+//@ compile-flags: -O
+#![crate_type = "lib"]
+
+#[no_mangle]
+pub fn test_assert(x: bool) {
+    assert!(x);
+}
+
+// check that assert! emits branch weights
+
+// CHECK-LABEL: @test_assert(
+// CHECK: br i1 %x, label %bb2, label %bb1, !prof ![[NUM:[0-9]+]]
+// CHECK: bb1:
+// CHECK: panic
+// CHECK: bb2:
+// CHECK: ret void
+// CHECK: ![[NUM]] = !{!"branch_weights", {{(!"expected", )?}}i32 2000, i32 1}
diff --git a/tests/codegen/intrinsics/unlikely.rs b/tests/codegen/intrinsics/unlikely.rs
new file mode 100644
index 00000000000..2d776031a52
--- /dev/null
+++ b/tests/codegen/intrinsics/unlikely.rs
@@ -0,0 +1,35 @@
+//@ compile-flags: -O
+#![crate_type = "lib"]
+#![feature(core_intrinsics)]
+
+use std::intrinsics::unlikely;
+
+#[inline(never)]
+#[no_mangle]
+pub fn path_a() {
+    println!("path a");
+}
+
+#[inline(never)]
+#[no_mangle]
+pub fn path_b() {
+    println!("path b");
+}
+
+#[no_mangle]
+pub fn test_unlikely(x: bool) {
+    if unlikely(x) {
+        path_a();
+    } else {
+        path_b();
+    }
+}
+
+// CHECK-LABEL: @test_unlikely(
+// CHECK: br i1 %x, label %bb2, label %bb4, !prof ![[NUM:[0-9]+]]
+// CHECK: bb4:
+// CHECK: path_b
+// CHECK: bb2:
+// CHECK-NOT: cold_path
+// CHECK: path_a
+// CHECK: ![[NUM]] = !{!"branch_weights", {{(!"expected", )?}}i32 1, i32 2000}
diff --git a/tests/codegen/sanitizer/cfi/dbg-location-on-cfi-blocks.rs b/tests/codegen/sanitizer/cfi/dbg-location-on-cfi-blocks.rs
new file mode 100644
index 00000000000..df65960dfe0
--- /dev/null
+++ b/tests/codegen/sanitizer/cfi/dbg-location-on-cfi-blocks.rs
@@ -0,0 +1,19 @@
+// Verifies that the parent block's debug information are assigned to the inserted cfi block.
+//
+//@ needs-sanitizer-cfi
+//@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static -Cdebuginfo=1
+
+#![crate_type = "lib"]
+
+pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 {
+    // CHECK-LABEL: define{{.*}}foo{{.*}}!dbg !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
+    // CHECK:       start:
+    // CHECK:       [[TT:%.+]] = call i1 @llvm.type.test(ptr {{%f|%0}}, metadata !"{{[[:print:]]+}}"), !dbg !{{[0-9]+}}
+    // CHECK-NEXT:  br i1 [[TT]], label %type_test.pass, label %type_test.fail, !dbg !{{[0-9]+}}
+    // CHECK:       type_test.pass:                                   ; preds = %start
+    // CHECK-NEXT:  {{%.+}} = call i32 %f(i32{{.*}} %arg), !dbg !{{[0-9]+}}
+    // CHECK:       type_test.fail:                                   ; preds = %start
+    // CHECK-NEXT:  call void @llvm.trap(), !dbg !{{[0-9]+}}
+    // CHECK-NEXT:  unreachable, !dbg !{{[0-9]+}}
+    f(arg)
+}
diff --git a/tests/codegen/sanitizer/no-sanitize.rs b/tests/codegen/sanitizer/no-sanitize.rs
index 47d3fd83f11..2a309f6b9c6 100644
--- a/tests/codegen/sanitizer/no-sanitize.rs
+++ b/tests/codegen/sanitizer/no-sanitize.rs
@@ -7,6 +7,16 @@
 #![crate_type = "lib"]
 #![feature(no_sanitize)]
 
+// CHECK:     @UNSANITIZED = constant{{.*}} no_sanitize_address
+// CHECK-NOT: @__asan_global_UNSANITIZED
+#[no_mangle]
+#[no_sanitize(address)]
+pub static UNSANITIZED: u32 = 0;
+
+// CHECK: @__asan_global_SANITIZED
+#[no_mangle]
+pub static SANITIZED: u32 = 0;
+
 // CHECK-LABEL: ; no_sanitize::unsanitized
 // CHECK-NEXT:  ; Function Attrs:
 // CHECK-NOT:   sanitize_address
diff --git a/tests/codegen/try_question_mark_nop.rs b/tests/codegen/try_question_mark_nop.rs
index bbab0d9eb1d..36a0d9066c8 100644
--- a/tests/codegen/try_question_mark_nop.rs
+++ b/tests/codegen/try_question_mark_nop.rs
@@ -1,6 +1,9 @@
 //@ compile-flags: -O -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"]
@@ -13,8 +16,11 @@ use std::ptr::NonNull;
 #[no_mangle]
 pub fn option_nop_match_32(x: Option<u32>) -> Option<u32> {
     // CHECK: start:
+    // TWENTY-NEXT: %trunc = trunc nuw i32 %0 to i1
+    // TWENTY-NEXT: %.2 = select i1 %trunc, i32 %1, i32 undef
     // CHECK-NEXT: [[REG1:%.*]] = insertvalue { i32, i32 } poison, i32 %0, 0
-    // CHECK-NEXT: [[REG2:%.*]] = insertvalue { i32, i32 } [[REG1]], i32 %1, 1
+    // NINETEEN-NEXT: [[REG2:%.*]] = insertvalue { i32, i32 } [[REG1]], i32 %1, 1
+    // TWENTY-NEXT: [[REG2:%.*]] = insertvalue { i32, i32 } [[REG1]], i32 %.2, 1
     // CHECK-NEXT: ret { i32, i32 } [[REG2]]
     match x {
         Some(x) => Some(x),
@@ -26,6 +32,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: %trunc = trunc nuw i32 %0 to i1
+    // TWENTY-NEXT: %.1 = select i1 %trunc, i32 %1, i32 undef
     // CHECK-NEXT: insertvalue { i32, i32 }
     // CHECK-NEXT: insertvalue { i32, i32 }
     // CHECK-NEXT: ret { i32, i32 }