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/enum/enum-two-variants-match.rs51
-rw-r--r--tests/codegen/intrinsics/cold_path2.rs3
-rw-r--r--tests/codegen/intrinsics/transmute.rs25
-rw-r--r--tests/codegen/issues/issue-101082.rs1
-rw-r--r--tests/codegen/issues/issue-122600-ptr-discriminant-update.rs29
-rw-r--r--tests/codegen/target-feature-inline-closure.rs8
-rw-r--r--tests/codegen/try_question_mark_nop.rs8
7 files changed, 111 insertions, 14 deletions
diff --git a/tests/codegen/enum/enum-two-variants-match.rs b/tests/codegen/enum/enum-two-variants-match.rs
new file mode 100644
index 00000000000..e5978bfc761
--- /dev/null
+++ b/tests/codegen/enum/enum-two-variants-match.rs
@@ -0,0 +1,51 @@
+//@ 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"]
+
+// CHECK-LABEL: @option_match
+#[no_mangle]
+pub fn option_match(x: Option<i32>) -> u16 {
+    // CHECK: %x = alloca [8 x i8]
+    // CHECK: store i32 %0, ptr %x
+    // CHECK: %[[TAG:.+]] = load i32, ptr %x
+    // CHECK-SAME: !range ![[ZERO_ONE_32:[0-9]+]]
+    // CHECK: %[[DISCR:.+]] = zext i32 %[[TAG]] to i64
+    // CHECK: %[[COND:.+]] = trunc nuw i64 %[[DISCR]] to i1
+    // CHECK: br i1 %[[COND]], label %[[TRUE:[a-z0-9]+]], label %[[FALSE:[a-z0-9]+]]
+
+    // CHECK: [[TRUE]]:
+    // CHECK: store i16 13
+
+    // CHECK: [[FALSE]]:
+    // CHECK: store i16 42
+    match x {
+        Some(_) => 13,
+        None => 42,
+    }
+}
+
+// CHECK-LABEL: @result_match
+#[no_mangle]
+pub fn result_match(x: Result<u64, i64>) -> u16 {
+    // CHECK: %x = alloca [16 x i8]
+    // CHECK: store i64 %0, ptr %x
+    // CHECK: %[[DISCR:.+]] = load i64, ptr %x
+    // CHECK-SAME: !range ![[ZERO_ONE_64:[0-9]+]]
+    // CHECK: %[[COND:.+]] = trunc nuw i64 %[[DISCR]] to i1
+    // CHECK: br i1 %[[COND]], label %[[TRUE:[a-z0-9]+]], label %[[FALSE:[a-z0-9]+]]
+
+    // CHECK: [[TRUE]]:
+    // CHECK: store i16 13
+
+    // CHECK: [[FALSE]]:
+    // CHECK: store i16 42
+    match x {
+        Err(_) => 13,
+        Ok(_) => 42,
+    }
+}
+
+// CHECK: ![[ZERO_ONE_32]] = !{i32 0, i32 2}
+// CHECK: ![[ZERO_ONE_64]] = !{i64 0, i64 2}
diff --git a/tests/codegen/intrinsics/cold_path2.rs b/tests/codegen/intrinsics/cold_path2.rs
index 1e7e0478f4f..54ee473e620 100644
--- a/tests/codegen/intrinsics/cold_path2.rs
+++ b/tests/codegen/intrinsics/cold_path2.rs
@@ -26,7 +26,8 @@ pub fn test(x: Option<bool>) {
     }
 
     // CHECK-LABEL: @test(
-    // CHECK: br i1 %1, label %bb2, label %bb1, !prof ![[NUM:[0-9]+]]
+    // CHECK: %[[IS_NONE:.+]] = icmp eq i8 %0, 2
+    // CHECK: br i1 %[[IS_NONE]], label %bb2, label %bb1, !prof ![[NUM:[0-9]+]]
     // CHECK: bb1:
     // CHECK: path_a
     // CHECK: bb2:
diff --git a/tests/codegen/intrinsics/transmute.rs b/tests/codegen/intrinsics/transmute.rs
index ff297b27065..4849b88c09c 100644
--- a/tests/codegen/intrinsics/transmute.rs
+++ b/tests/codegen/intrinsics/transmute.rs
@@ -10,6 +10,7 @@
 use std::intrinsics::mir::*;
 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.
@@ -470,3 +471,27 @@ pub unsafe fn check_from_overalign(x: HighAlignScalar) -> u64 {
     // CHECK: ret i64 %[[VAL]]
     transmute(x)
 }
+
+#[repr(transparent)]
+struct Level1(std::num::NonZero<u32>);
+#[repr(transparent)]
+struct Level2(Level1);
+#[repr(transparent)]
+struct Level3(Level2);
+
+// CHECK-LABEL: @repeatedly_transparent_transmute
+// CHECK-SAME: (i32{{.+}}%[[ARG:[^)]+]])
+#[no_mangle]
+#[custom_mir(dialect = "runtime", phase = "optimized")]
+pub unsafe fn repeatedly_transparent_transmute(x: NonZero<u32>) -> Level3 {
+    // CHECK: start
+    // CHECK-NEXT: ret i32 %[[ARG]]
+    mir! {
+        {
+            let A = CastTransmute::<NonZero<u32>, Level1>(x);
+            let B = CastTransmute::<Level1, Level2>(A);
+            RET = CastTransmute::<Level2, Level3>(B);
+            Return()
+        }
+    }
+}
diff --git a/tests/codegen/issues/issue-101082.rs b/tests/codegen/issues/issue-101082.rs
index 048b69d207b..7fb850ca253 100644
--- a/tests/codegen/issues/issue-101082.rs
+++ b/tests/codegen/issues/issue-101082.rs
@@ -1,5 +1,6 @@
 //@ compile-flags: -Copt-level=3
 //@ revisions: host x86-64-v3
+//@ min-llvm-version: 20
 
 // This particular CPU regressed in #131563
 //@[x86-64-v3] only-x86_64
diff --git a/tests/codegen/issues/issue-122600-ptr-discriminant-update.rs b/tests/codegen/issues/issue-122600-ptr-discriminant-update.rs
index fdb8f06df80..fbea4ee8979 100644
--- a/tests/codegen/issues/issue-122600-ptr-discriminant-update.rs
+++ b/tests/codegen/issues/issue-122600-ptr-discriminant-update.rs
@@ -3,6 +3,11 @@
 
 #![crate_type = "lib"]
 
+// The bug here was that it was loading and storing the whole value.
+// It's ok for it to load the discriminant,
+// to preserve the UB from `unreachable_unchecked`,
+// but it better only store the constant discriminant of `B`.
+
 pub enum State {
     A([u8; 753]),
     B([u8; 753]),
@@ -11,9 +16,27 @@ pub enum State {
 // CHECK-LABEL: @update
 #[no_mangle]
 pub unsafe fn update(s: *mut State) {
-    // CHECK-NEXT: start:
-    // CHECK-NEXT: store i8
-    // CHECK-NEXT: ret
+    // CHECK-NOT: alloca
+
+    // CHECK-NOT: load
+    // CHECK-NOT: store
+    // CHECK-NOT: memcpy
+    // CHECK-NOT: 75{{3|4}}
+
+    // CHECK: %[[TAG:.+]] = load i8, ptr %s, align 1
+    // CHECK-NEXT: trunc nuw i8 %[[TAG]] to i1
+
+    // CHECK-NOT: load
+    // CHECK-NOT: store
+    // CHECK-NOT: memcpy
+    // CHECK-NOT: 75{{3|4}}
+
+    // CHECK: store i8 1, ptr %s, align 1
+
+    // CHECK-NOT: load
+    // CHECK-NOT: store
+    // CHECK-NOT: memcpy
+    // CHECK-NOT: 75{{3|4}}
     let State::A(v) = s.read() else { std::hint::unreachable_unchecked() };
     s.write(State::B(v));
 }
diff --git a/tests/codegen/target-feature-inline-closure.rs b/tests/codegen/target-feature-inline-closure.rs
index 73bdbc0e1a8..5d54444f994 100644
--- a/tests/codegen/target-feature-inline-closure.rs
+++ b/tests/codegen/target-feature-inline-closure.rs
@@ -12,7 +12,7 @@ use std::arch::x86_64::*;
 #[cfg(target_arch = "x86_64")]
 #[target_feature(enable = "avx")]
 fn with_avx(x: __m256) -> __m256 {
-    // CHECK: fadd
+    // CHECK: fadd <8 x float>
     let add = {
         #[inline(always)]
         |x, y| unsafe { _mm256_add_ps(x, y) }
@@ -24,14 +24,10 @@ fn with_avx(x: __m256) -> __m256 {
 #[no_mangle]
 #[cfg(target_arch = "x86_64")]
 unsafe fn without_avx(x: __m256) -> __m256 {
-    // CHECK-NOT: fadd
+    // CHECK-NOT: fadd <8 x float>
     let add = {
         #[inline(always)]
         |x, y| unsafe { _mm256_add_ps(x, y) }
     };
     add(x, x)
 }
-
-// Don't allow the above CHECK-NOT to accidentally match a commit hash in the
-// compiler version.
-// CHECK-LABEL: rustc version
diff --git a/tests/codegen/try_question_mark_nop.rs b/tests/codegen/try_question_mark_nop.rs
index 751d7ca9311..ca15e510173 100644
--- a/tests/codegen/try_question_mark_nop.rs
+++ b/tests/codegen/try_question_mark_nop.rs
@@ -16,8 +16,8 @@ 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
+    // TWENTY-NEXT: %[[IS_SOME:.+]] = trunc nuw i32 %0 to i1
+    // TWENTY-NEXT: %.2 = select i1 %[[IS_SOME]], i32 %1, i32 undef
     // CHECK-NEXT: [[REG1:%.*]] = insertvalue { i32, i32 } poison, i32 %0, 0
     // NINETEEN-NEXT: [[REG2:%.*]] = insertvalue { i32, i32 } [[REG1]], i32 %1, 1
     // TWENTY-NEXT: [[REG2:%.*]] = insertvalue { i32, i32 } [[REG1]], i32 %.2, 1
@@ -32,8 +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
+    // TWENTY-NEXT: %[[IS_SOME:.+]] = trunc nuw i32 %0 to i1
+    // TWENTY-NEXT: %.1 = select i1 %[[IS_SOME]], i32 %1, i32 undef
     // CHECK-NEXT: insertvalue { i32, i32 }
     // CHECK-NEXT: insertvalue { i32, i32 }
     // CHECK-NEXT: ret { i32, i32 }