diff options
| author | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2025-07-21 14:34:12 +0200 |
|---|---|---|
| committer | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2025-07-22 14:28:48 +0200 |
| commit | a27f3e3fd1e4d16160f8885b6b06665b5319f56c (patch) | |
| tree | b033935392cbadf6f85d2dbddf433a88e323aeeb /tests/codegen/enum | |
| parent | ed93c1783b404d728d4809973a0550eb33cd293f (diff) | |
| download | rust-a27f3e3fd1e4d16160f8885b6b06665b5319f56c.tar.gz rust-a27f3e3fd1e4d16160f8885b6b06665b5319f56c.zip | |
Rename `tests/codegen` into `tests/codegen-llvm`
Diffstat (limited to 'tests/codegen/enum')
| -rw-r--r-- | tests/codegen/enum/enum-aggregate.rs | 126 | ||||
| -rw-r--r-- | tests/codegen/enum/enum-bounds-check-derived-idx.rs | 24 | ||||
| -rw-r--r-- | tests/codegen/enum/enum-bounds-check-issue-13926.rs | 18 | ||||
| -rw-r--r-- | tests/codegen/enum/enum-bounds-check-issue-82871.rs | 18 | ||||
| -rw-r--r-- | tests/codegen/enum/enum-bounds-check.rs | 27 | ||||
| -rw-r--r-- | tests/codegen/enum/enum-debug-clike.rs | 28 | ||||
| -rw-r--r-- | tests/codegen/enum/enum-debug-niche-2.rs | 47 | ||||
| -rw-r--r-- | tests/codegen/enum/enum-debug-niche.rs | 35 | ||||
| -rw-r--r-- | tests/codegen/enum/enum-debug-tagged.rs | 31 | ||||
| -rw-r--r-- | tests/codegen/enum/enum-discriminant-eq.rs | 223 | ||||
| -rw-r--r-- | tests/codegen/enum/enum-discriminant-value.rs | 27 | ||||
| -rw-r--r-- | tests/codegen/enum/enum-early-otherwise-branch.rs | 25 | ||||
| -rw-r--r-- | tests/codegen/enum/enum-match.rs | 779 | ||||
| -rw-r--r-- | tests/codegen/enum/enum-two-variants-match.rs | 130 | ||||
| -rw-r--r-- | tests/codegen/enum/enum-u128.rs | 25 | ||||
| -rw-r--r-- | tests/codegen/enum/unreachable_enum_default_branch.rs | 40 |
16 files changed, 0 insertions, 1603 deletions
diff --git a/tests/codegen/enum/enum-aggregate.rs b/tests/codegen/enum/enum-aggregate.rs deleted file mode 100644 index 0161e5f3fa1..00000000000 --- a/tests/codegen/enum/enum-aggregate.rs +++ /dev/null @@ -1,126 +0,0 @@ -//@ compile-flags: -Copt-level=0 -Cno-prepopulate-passes -//@ min-llvm-version: 19 -//@ only-64bit - -#![crate_type = "lib"] - -use std::cmp::Ordering; -use std::num::NonZero; -use std::ptr::NonNull; - -#[no_mangle] -fn make_some_bool(x: bool) -> Option<bool> { - // CHECK-LABEL: i8 @make_some_bool(i1 zeroext %x) - // CHECK-NEXT: start: - // CHECK-NEXT: %[[WIDER:.+]] = zext i1 %x to i8 - // CHECK-NEXT: ret i8 %[[WIDER]] - Some(x) -} - -#[no_mangle] -fn make_none_bool() -> Option<bool> { - // CHECK-LABEL: i8 @make_none_bool() - // CHECK-NEXT: start: - // CHECK-NEXT: ret i8 2 - None -} - -#[no_mangle] -fn make_some_ordering(x: Ordering) -> Option<Ordering> { - // CHECK-LABEL: i8 @make_some_ordering(i8 %x) - // CHECK-NEXT: start: - // CHECK-NEXT: ret i8 %x - Some(x) -} - -#[no_mangle] -fn make_some_u16(x: u16) -> Option<u16> { - // CHECK-LABEL: { i16, i16 } @make_some_u16(i16 %x) - // CHECK-NEXT: start: - // CHECK-NEXT: %0 = insertvalue { i16, i16 } { i16 1, i16 poison }, i16 %x, 1 - // CHECK-NEXT: ret { i16, i16 } %0 - Some(x) -} - -#[no_mangle] -fn make_none_u16() -> Option<u16> { - // CHECK-LABEL: { i16, i16 } @make_none_u16() - // CHECK-NEXT: start: - // CHECK-NEXT: ret { i16, i16 } { i16 0, i16 undef } - None -} - -#[no_mangle] -fn make_some_nzu32(x: NonZero<u32>) -> Option<NonZero<u32>> { - // CHECK-LABEL: i32 @make_some_nzu32(i32 %x) - // CHECK-NEXT: start: - // CHECK-NEXT: ret i32 %x - Some(x) -} - -#[no_mangle] -fn make_ok_ptr(x: NonNull<u16>) -> Result<NonNull<u16>, usize> { - // CHECK-LABEL: { i64, ptr } @make_ok_ptr(ptr %x) - // CHECK-NEXT: start: - // CHECK-NEXT: %0 = insertvalue { i64, ptr } { i64 0, ptr poison }, ptr %x, 1 - // CHECK-NEXT: ret { i64, ptr } %0 - Ok(x) -} - -#[no_mangle] -fn make_ok_int(x: usize) -> Result<usize, NonNull<u16>> { - // CHECK-LABEL: { i64, ptr } @make_ok_int(i64 %x) - // CHECK-NEXT: start: - // CHECK-NEXT: %[[NOPROV:.+]] = getelementptr i8, ptr null, i64 %x - // CHECK-NEXT: %[[R:.+]] = insertvalue { i64, ptr } { i64 0, ptr poison }, ptr %[[NOPROV]], 1 - // CHECK-NEXT: ret { i64, ptr } %[[R]] - Ok(x) -} - -#[no_mangle] -fn make_some_ref(x: &u16) -> Option<&u16> { - // CHECK-LABEL: ptr @make_some_ref(ptr align 2 %x) - // CHECK-NEXT: start: - // CHECK-NEXT: ret ptr %x - Some(x) -} - -#[no_mangle] -fn make_none_ref<'a>() -> Option<&'a u16> { - // CHECK-LABEL: ptr @make_none_ref() - // CHECK-NEXT: start: - // CHECK-NEXT: ret ptr null - None -} - -#[inline(never)] -fn make_err_generic<E>(e: E) -> Result<u32, E> { - // CHECK-LABEL: define{{.+}}make_err_generic - // CHECK-NEXT: start: - // CHECK-NEXT: call void @llvm.trap() - // CHECK-NEXT: ret i32 poison - Err(e) -} - -#[no_mangle] -fn make_uninhabited_err_indirectly(n: Never) -> Result<u32, Never> { - // CHECK-LABEL: i32 @make_uninhabited_err_indirectly() - // CHECK-NEXT: start: - // CHECK-NEXT: call{{.+}}make_err_generic - make_err_generic(n) -} - -#[no_mangle] -fn make_fully_uninhabited_result(v: u32, n: Never) -> Result<(u32, Never), (Never, u32)> { - // Actually reaching this would be UB, so we don't actually build a result. - - // CHECK-LABEL: { i32, i32 } @make_fully_uninhabited_result(i32 %v) - // CHECK-NEXT: start: - // CHECK-NEXT: call void @llvm.trap() - // CHECK-NEXT: call void @llvm.trap() - // CHECK-NEXT: call void @llvm.trap() - // CHECK-NEXT: unreachable - Ok((v, n)) -} - -enum Never {} diff --git a/tests/codegen/enum/enum-bounds-check-derived-idx.rs b/tests/codegen/enum/enum-bounds-check-derived-idx.rs deleted file mode 100644 index a5785f4addf..00000000000 --- a/tests/codegen/enum/enum-bounds-check-derived-idx.rs +++ /dev/null @@ -1,24 +0,0 @@ -// This test checks an optimization that is not guaranteed to work. This test case should not block -// a future LLVM update. -//@ compile-flags: -Copt-level=3 - -#![crate_type = "lib"] - -pub enum Bar { - A = 1, - B = 3, -} - -// CHECK-LABEL: @lookup_inc -#[no_mangle] -pub fn lookup_inc(buf: &[u8; 5], f: Bar) -> u8 { - // CHECK-NOT: panic_bounds_check - buf[f as usize + 1] -} - -// CHECK-LABEL: @lookup_dec -#[no_mangle] -pub fn lookup_dec(buf: &[u8; 5], f: Bar) -> u8 { - // CHECK-NOT: panic_bounds_check - buf[f as usize - 1] -} diff --git a/tests/codegen/enum/enum-bounds-check-issue-13926.rs b/tests/codegen/enum/enum-bounds-check-issue-13926.rs deleted file mode 100644 index 6e8e5035b0d..00000000000 --- a/tests/codegen/enum/enum-bounds-check-issue-13926.rs +++ /dev/null @@ -1,18 +0,0 @@ -// This test checks an optimization that is not guaranteed to work. This test case should not block -// a future LLVM update. -//@ compile-flags: -Copt-level=3 - -#![crate_type = "lib"] - -#[repr(u8)] -pub enum Exception { - Low = 5, - High = 10, -} - -// CHECK-LABEL: @access -#[no_mangle] -pub fn access(array: &[usize; 12], exc: Exception) -> usize { - // CHECK-NOT: panic_bounds_check - array[(exc as u8 - 4) as usize] -} diff --git a/tests/codegen/enum/enum-bounds-check-issue-82871.rs b/tests/codegen/enum/enum-bounds-check-issue-82871.rs deleted file mode 100644 index 3b8a146838a..00000000000 --- a/tests/codegen/enum/enum-bounds-check-issue-82871.rs +++ /dev/null @@ -1,18 +0,0 @@ -//@ compile-flags: -C opt-level=0 - -#![crate_type = "lib"] - -#[repr(C)] -pub enum E { - A, -} - -// CHECK-LABEL: @index -#[no_mangle] -pub fn index(x: &[u32; 3], ind: E) -> u32 { - // Canary: we should be able to optimize out the bounds check, but we need - // to track the range of the discriminant result in order to be able to do that. - // oli-obk tried to add that, but that caused miscompilations all over the place. - // CHECK: panic_bounds_check - x[ind as usize] -} diff --git a/tests/codegen/enum/enum-bounds-check.rs b/tests/codegen/enum/enum-bounds-check.rs deleted file mode 100644 index 5362598ca7c..00000000000 --- a/tests/codegen/enum/enum-bounds-check.rs +++ /dev/null @@ -1,27 +0,0 @@ -//@ compile-flags: -Copt-level=3 - -#![crate_type = "lib"] - -pub enum Foo { - A, - B, -} - -// CHECK-LABEL: @lookup -#[no_mangle] -pub fn lookup(buf: &[u8; 2], f: Foo) -> u8 { - // CHECK-NOT: panic_bounds_check - buf[f as usize] -} - -pub enum Bar { - A = 2, - B = 3, -} - -// CHECK-LABEL: @lookup_unmodified -#[no_mangle] -pub fn lookup_unmodified(buf: &[u8; 5], f: Bar) -> u8 { - // CHECK-NOT: panic_bounds_check - buf[f as usize] -} diff --git a/tests/codegen/enum/enum-debug-clike.rs b/tests/codegen/enum/enum-debug-clike.rs deleted file mode 100644 index 89c803cce5e..00000000000 --- a/tests/codegen/enum/enum-debug-clike.rs +++ /dev/null @@ -1,28 +0,0 @@ -// This tests that debug info for "c-like" enums is properly emitted. -// This is ignored for the fallback mode on MSVC due to problems with PDB. - -// -//@ ignore-msvc -//@ ignore-wasi wasi codegens the main symbol differently - -//@ compile-flags: -g -C no-prepopulate-passes - -// CHECK-LABEL: @main -// CHECK: {{.*}}DICompositeType{{.*}}tag: DW_TAG_enumeration_type,{{.*}}name: "E",{{.*}}flags: DIFlagEnumClass,{{.*}} -// CHECK: {{.*}}DIEnumerator{{.*}}name: "A",{{.*}}value: {{[0-9].*}} -// CHECK: {{.*}}DIEnumerator{{.*}}name: "B",{{.*}}value: {{[0-9].*}} -// CHECK: {{.*}}DIEnumerator{{.*}}name: "C",{{.*}}value: {{[0-9].*}} - -#![allow(dead_code)] -#![allow(unused_variables)] -#![allow(unused_assignments)] - -enum E { - A, - B, - C, -} - -pub fn main() { - let e = E::C; -} diff --git a/tests/codegen/enum/enum-debug-niche-2.rs b/tests/codegen/enum/enum-debug-niche-2.rs deleted file mode 100644 index 80a4081f15b..00000000000 --- a/tests/codegen/enum/enum-debug-niche-2.rs +++ /dev/null @@ -1,47 +0,0 @@ -//! This tests that optimized enum debug info accurately reflects the enum layout. -//! This is ignored for the fallback mode on MSVC due to problems with PDB. -//! -//@ compile-flags: -g -C no-prepopulate-passes -//@ ignore-msvc -// -// CHECK: {{.*}}DICompositeType{{.*}}tag: DW_TAG_variant_part,{{.*}}size: 32,{{.*}} -// CHECK: {{.*}}DIDerivedType{{.*}}tag: DW_TAG_member,{{.*}}name: "Placeholder",{{.*}}extraData: i32 -1{{[,)].*}} -// CHECK: {{.*}}DIDerivedType{{.*}}tag: DW_TAG_member,{{.*}}name: "Error",{{.*}}extraData: i32 0{{[,)].*}} -#![feature(never_type)] - -#[derive(Copy, Clone)] -pub struct Entity { - private: std::num::NonZero<u32>, -} - -#[derive(Copy, Clone, PartialEq, Eq)] -pub struct Declaration; - -impl TypeFamily for Declaration { - type Base = Base; - type Placeholder = !; - - fn intern_base_data(_: BaseKind<Self>) {} -} - -#[derive(Copy, Clone)] -pub struct Base; - -pub trait TypeFamily: Copy + 'static { - type Base: Copy; - type Placeholder: Copy; - - fn intern_base_data(_: BaseKind<Self>); -} - -#[derive(Copy, Clone)] -pub enum BaseKind<F: TypeFamily> { - Named(Entity), - Placeholder(F::Placeholder), - Error, -} - -pub fn main() { - let x = BaseKind::Error::<Declaration>; - let y = 7; -} diff --git a/tests/codegen/enum/enum-debug-niche.rs b/tests/codegen/enum/enum-debug-niche.rs deleted file mode 100644 index 59e8b8a78b4..00000000000 --- a/tests/codegen/enum/enum-debug-niche.rs +++ /dev/null @@ -1,35 +0,0 @@ -// This tests that optimized enum debug info accurately reflects the enum layout. -// This is ignored for the fallback mode on MSVC due to problems with PDB. - -//@ ignore-msvc -//@ ignore-wasi wasi codegens the main symbol differently - -//@ compile-flags: -g -C no-prepopulate-passes - -// CHECK-LABEL: @main -// CHECK: {{.*}}DICompositeType{{.*}}tag: DW_TAG_variant_part,{{.*}}discriminator:{{.*}} -// CHECK: {{.*}}DIDerivedType{{.*}}tag: DW_TAG_member,{{.*}}name: "A",{{.*}}extraData:{{.*}} -// CHECK: {{.*}}DICompositeType{{.*}}tag: DW_TAG_structure_type,{{.*}}name: "A",{{.*}} -// CHECK: {{.*}}DIDerivedType{{.*}}tag: DW_TAG_member,{{.*}}name: "B",{{.*}}extraData:{{.*}} -// CHECK: {{.*}}DICompositeType{{.*}}tag: DW_TAG_structure_type,{{.*}}name: "B",{{.*}} -// CHECK: {{.*}}DIDerivedType{{.*}}tag: DW_TAG_member,{{.*}}name: "C",{{.*}}extraData:{{.*}} -// CHECK: {{.*}}DICompositeType{{.*}}tag: DW_TAG_structure_type,{{.*}}name: "C",{{.*}} -// CHECK-NOT: {{.*}}DIDerivedType{{.*}}name: "D",{{.*}}extraData:{{.*}} -// CHECK: {{.*}}DIDerivedType{{.*}}tag: DW_TAG_member,{{.*}}name: "D",{{.*}} -// CHECK: {{.*}}DICompositeType{{.*}}tag: DW_TAG_structure_type,{{.*}}name: "D",{{.*}} -// CHECK: {{.*}}DIDerivedType{{.*}}tag: DW_TAG_member,{{.*}}flags: DIFlagArtificial{{.*}} - -#![allow(dead_code)] -#![allow(unused_variables)] -#![allow(unused_assignments)] - -enum E { - A, - B, - C, - D(bool), -} - -pub fn main() { - let e = E::D(true); -} diff --git a/tests/codegen/enum/enum-debug-tagged.rs b/tests/codegen/enum/enum-debug-tagged.rs deleted file mode 100644 index e8f147665b0..00000000000 --- a/tests/codegen/enum/enum-debug-tagged.rs +++ /dev/null @@ -1,31 +0,0 @@ -// This tests that debug info for tagged (ordinary) enums is properly emitted. -// This is ignored for the fallback mode on MSVC due to problems with PDB. - -//@ ignore-msvc -//@ ignore-wasi wasi codegens the main symbol differently - -//@ compile-flags: -g -C no-prepopulate-passes - -// CHECK-LABEL: @main -// CHECK: {{.*}}DICompositeType{{.*}}tag: DW_TAG_structure_type,{{.*}}name: "E",{{.*}} -// CHECK: {{.*}}DICompositeType{{.*}}tag: DW_TAG_variant_part,{{.*}}discriminator:{{.*}} -// CHECK: {{.*}}DIDerivedType{{.*}}tag: DW_TAG_member,{{.*}}name: "A",{{.*}}extraData:{{.*}} -// CHECK: {{.*}}DICompositeType{{.*}}tag: DW_TAG_structure_type,{{.*}}name: "A",{{.*}} -// CHECK: {{.*}}DIDerivedType{{.*}}tag: DW_TAG_member,{{.*}}name: "__0",{{.*}} -// CHECK: {{.*}}DIDerivedType{{.*}}tag: DW_TAG_member,{{.*}}name: "B",{{.*}}extraData:{{.*}} -// CHECK: {{.*}}DICompositeType{{.*}}tag: DW_TAG_structure_type,{{.*}}name: "B",{{.*}} -// CHECK: {{.*}}DIDerivedType{{.*}}tag: DW_TAG_member,{{.*}}name: "__0",{{.*}} -// CHECK: {{.*}}DIDerivedType{{.*}}tag: DW_TAG_member,{{.*}}flags: DIFlagArtificial{{.*}} - -#![allow(dead_code)] -#![allow(unused_variables)] -#![allow(unused_assignments)] - -enum E { - A(u32), - B(u32), -} - -pub fn main() { - let e = E::A(23); -} diff --git a/tests/codegen/enum/enum-discriminant-eq.rs b/tests/codegen/enum/enum-discriminant-eq.rs deleted file mode 100644 index 0494c5f551b..00000000000 --- a/tests/codegen/enum/enum-discriminant-eq.rs +++ /dev/null @@ -1,223 +0,0 @@ -//@ compile-flags: -Copt-level=3 -Zmerge-functions=disabled -//@ min-llvm-version: 20 -//@ only-64bit - -// The `derive(PartialEq)` on enums with field-less variants compares discriminants, -// so make sure we emit that in some reasonable way. - -#![crate_type = "lib"] -#![feature(ascii_char)] -#![feature(core_intrinsics)] -#![feature(repr128)] - -use std::ascii::Char as AC; -use std::cmp::Ordering; -use std::intrinsics::discriminant_value; -use std::num::NonZero; - -// A type that's bigger than `isize`, unlike the usual cases that have small tags. -#[repr(u128)] -pub enum Giant { - Two = 2, - Three = 3, - Four = 4, -} - -#[unsafe(no_mangle)] -pub fn opt_bool_eq_discr(a: Option<bool>, b: Option<bool>) -> bool { - // CHECK-LABEL: @opt_bool_eq_discr( - // CHECK: %[[A:.+]] = icmp ne i8 %a, 2 - // CHECK: %[[B:.+]] = icmp eq i8 %b, 2 - // CHECK: %[[R:.+]] = xor i1 %[[A]], %[[B]] - // CHECK: ret i1 %[[R]] - - discriminant_value(&a) == discriminant_value(&b) -} - -#[unsafe(no_mangle)] -pub fn opt_ord_eq_discr(a: Option<Ordering>, b: Option<Ordering>) -> bool { - // CHECK-LABEL: @opt_ord_eq_discr( - // CHECK: %[[A:.+]] = icmp ne i8 %a, 2 - // CHECK: %[[B:.+]] = icmp eq i8 %b, 2 - // CHECK: %[[R:.+]] = xor i1 %[[A]], %[[B]] - // CHECK: ret i1 %[[R]] - - discriminant_value(&a) == discriminant_value(&b) -} - -#[unsafe(no_mangle)] -pub fn opt_nz32_eq_discr(a: Option<NonZero<u32>>, b: Option<NonZero<u32>>) -> bool { - // CHECK-LABEL: @opt_nz32_eq_discr( - // CHECK: %[[A:.+]] = icmp ne i32 %a, 0 - // CHECK: %[[B:.+]] = icmp eq i32 %b, 0 - // CHECK: %[[R:.+]] = xor i1 %[[A]], %[[B]] - // CHECK: ret i1 %[[R]] - - discriminant_value(&a) == discriminant_value(&b) -} - -#[unsafe(no_mangle)] -pub fn opt_ac_eq_discr(a: Option<AC>, b: Option<AC>) -> bool { - // CHECK-LABEL: @opt_ac_eq_discr( - // CHECK: %[[A:.+]] = icmp ne i8 %a, -128 - // CHECK: %[[B:.+]] = icmp eq i8 %b, -128 - // CHECK: %[[R:.+]] = xor i1 %[[A]], %[[B]] - // CHECK: ret i1 %[[R]] - - discriminant_value(&a) == discriminant_value(&b) -} - -#[unsafe(no_mangle)] -pub fn opt_giant_eq_discr(a: Option<Giant>, b: Option<Giant>) -> bool { - // CHECK-LABEL: @opt_giant_eq_discr( - // CHECK: %[[A:.+]] = icmp ne i128 %a, 1 - // CHECK: %[[B:.+]] = icmp eq i128 %b, 1 - // CHECK: %[[R:.+]] = xor i1 %[[A]], %[[B]] - // CHECK: ret i1 %[[R]] - - discriminant_value(&a) == discriminant_value(&b) -} - -pub enum Mid<T> { - Before, - Thing(T), - After, -} - -#[unsafe(no_mangle)] -pub fn mid_bool_eq_discr(a: Mid<bool>, b: Mid<bool>) -> bool { - // CHECK-LABEL: @mid_bool_eq_discr( - - // CHECK: %[[A_REL_DISCR:.+]] = add nsw i8 %a, -2 - // CHECK: %[[A_IS_NICHE:.+]] = icmp samesign ugt i8 %a, 1 - // CHECK: %[[A_NOT_HOLE:.+]] = icmp ne i8 %[[A_REL_DISCR]], 1 - // CHECK: tail call void @llvm.assume(i1 %[[A_NOT_HOLE]]) - // CHECK: %[[A_DISCR:.+]] = select i1 %[[A_IS_NICHE]], i8 %[[A_REL_DISCR]], i8 1 - - // CHECK: %[[B_REL_DISCR:.+]] = add nsw i8 %b, -2 - // CHECK: %[[B_IS_NICHE:.+]] = icmp samesign ugt i8 %b, 1 - // CHECK: %[[B_NOT_HOLE:.+]] = icmp ne i8 %[[B_REL_DISCR]], 1 - // CHECK: tail call void @llvm.assume(i1 %[[B_NOT_HOLE]]) - // CHECK: %[[B_DISCR:.+]] = select i1 %[[B_IS_NICHE]], i8 %[[B_REL_DISCR]], i8 1 - - // CHECK: ret i1 %[[R]] - discriminant_value(&a) == discriminant_value(&b) -} - -#[unsafe(no_mangle)] -pub fn mid_ord_eq_discr(a: Mid<Ordering>, b: Mid<Ordering>) -> bool { - // CHECK-LABEL: @mid_ord_eq_discr( - - // CHECK: %[[A_REL_DISCR:.+]] = add nsw i8 %a, -2 - // CHECK: %[[A_IS_NICHE:.+]] = icmp sgt i8 %a, 1 - // CHECK: %[[A_NOT_HOLE:.+]] = icmp ne i8 %[[A_REL_DISCR]], 1 - // CHECK: tail call void @llvm.assume(i1 %[[A_NOT_HOLE]]) - // CHECK: %[[A_DISCR:.+]] = select i1 %[[A_IS_NICHE]], i8 %[[A_REL_DISCR]], i8 1 - - // CHECK: %[[B_REL_DISCR:.+]] = add nsw i8 %b, -2 - // CHECK: %[[B_IS_NICHE:.+]] = icmp sgt i8 %b, 1 - // CHECK: %[[B_NOT_HOLE:.+]] = icmp ne i8 %[[B_REL_DISCR]], 1 - // CHECK: tail call void @llvm.assume(i1 %[[B_NOT_HOLE]]) - // CHECK: %[[B_DISCR:.+]] = select i1 %[[B_IS_NICHE]], i8 %[[B_REL_DISCR]], i8 1 - - // CHECK: %[[R:.+]] = icmp eq i8 %[[A_DISCR]], %[[B_DISCR]] - // CHECK: ret i1 %[[R]] - discriminant_value(&a) == discriminant_value(&b) -} - -#[unsafe(no_mangle)] -pub fn mid_nz32_eq_discr(a: Mid<NonZero<u32>>, b: Mid<NonZero<u32>>) -> bool { - // CHECK-LABEL: @mid_nz32_eq_discr( - // CHECK: %[[R:.+]] = icmp eq i32 %a.0, %b.0 - // CHECK: ret i1 %[[R]] - discriminant_value(&a) == discriminant_value(&b) -} - -#[unsafe(no_mangle)] -pub fn mid_ac_eq_discr(a: Mid<AC>, b: Mid<AC>) -> bool { - // CHECK-LABEL: @mid_ac_eq_discr( - - // CHECK: %[[A_REL_DISCR:.+]] = xor i8 %a, -128 - // CHECK: %[[A_IS_NICHE:.+]] = icmp slt i8 %a, 0 - // CHECK: %[[A_NOT_HOLE:.+]] = icmp ne i8 %a, -127 - // CHECK: tail call void @llvm.assume(i1 %[[A_NOT_HOLE]]) - // CHECK: %[[A_DISCR:.+]] = select i1 %[[A_IS_NICHE]], i8 %[[A_REL_DISCR]], i8 1 - - // CHECK: %[[B_REL_DISCR:.+]] = xor i8 %b, -128 - // CHECK: %[[B_IS_NICHE:.+]] = icmp slt i8 %b, 0 - // CHECK: %[[B_NOT_HOLE:.+]] = icmp ne i8 %b, -127 - // CHECK: tail call void @llvm.assume(i1 %[[B_NOT_HOLE]]) - // CHECK: %[[B_DISCR:.+]] = select i1 %[[B_IS_NICHE]], i8 %[[B_REL_DISCR]], i8 1 - - // CHECK: %[[R:.+]] = icmp eq i8 %[[A_DISCR]], %[[B_DISCR]] - // CHECK: ret i1 %[[R]] - discriminant_value(&a) == discriminant_value(&b) -} - -// FIXME: This should be improved once our LLVM fork picks up the fix for -// <https://github.com/llvm/llvm-project/issues/134024> -#[unsafe(no_mangle)] -pub fn mid_giant_eq_discr(a: Mid<Giant>, b: Mid<Giant>) -> bool { - // CHECK-LABEL: @mid_giant_eq_discr( - - // CHECK: %[[A_TRUNC:.+]] = trunc nuw nsw i128 %a to i64 - // CHECK: %[[A_REL_DISCR:.+]] = add nsw i64 %[[A_TRUNC]], -5 - // CHECK: %[[A_IS_NICHE:.+]] = icmp samesign ugt i128 %a, 4 - // CHECK: %[[A_NOT_HOLE:.+]] = icmp ne i64 %[[A_REL_DISCR]], 1 - // CHECK: tail call void @llvm.assume(i1 %[[A_NOT_HOLE]]) - // CHECK: %[[A_DISCR:.+]] = select i1 %[[A_IS_NICHE]], i64 %[[A_REL_DISCR]], i64 1 - - // CHECK: %[[B_TRUNC:.+]] = trunc nuw nsw i128 %b to i64 - // CHECK: %[[B_REL_DISCR:.+]] = add nsw i64 %[[B_TRUNC]], -5 - // CHECK: %[[B_IS_NICHE:.+]] = icmp samesign ugt i128 %b, 4 - // CHECK: %[[B_NOT_HOLE:.+]] = icmp ne i64 %[[B_REL_DISCR]], 1 - // CHECK: tail call void @llvm.assume(i1 %[[B_NOT_HOLE]]) - // CHECK: %[[B_DISCR:.+]] = select i1 %[[B_IS_NICHE]], i64 %[[B_REL_DISCR]], i64 1 - - // CHECK: %[[R:.+]] = icmp eq i64 %[[A_DISCR]], %[[B_DISCR]] - // CHECK: ret i1 %[[R]] - discriminant_value(&a) == discriminant_value(&b) -} - -// In niche-encoded enums, testing for the untagged variant should optimize to a -// straight-forward comparison looking for the natural range of the payload value. - -#[unsafe(no_mangle)] -pub fn mid_bool_is_thing(a: Mid<bool>) -> bool { - // CHECK-LABEL: @mid_bool_is_thing( - // CHECK: %[[R:.+]] = icmp samesign ult i8 %a, 2 - // CHECK: ret i1 %[[R]] - discriminant_value(&a) == 1 -} - -#[unsafe(no_mangle)] -pub fn mid_ord_is_thing(a: Mid<Ordering>) -> bool { - // CHECK-LABEL: @mid_ord_is_thing( - // CHECK: %[[R:.+]] = icmp slt i8 %a, 2 - // CHECK: ret i1 %[[R]] - discriminant_value(&a) == 1 -} - -#[unsafe(no_mangle)] -pub fn mid_nz32_is_thing(a: Mid<NonZero<u32>>) -> bool { - // CHECK-LABEL: @mid_nz32_is_thing( - // CHECK: %[[R:.+]] = icmp eq i32 %a.0, 1 - // CHECK: ret i1 %[[R]] - discriminant_value(&a) == 1 -} - -#[unsafe(no_mangle)] -pub fn mid_ac_is_thing(a: Mid<AC>) -> bool { - // CHECK-LABEL: @mid_ac_is_thing( - // CHECK: %[[R:.+]] = icmp sgt i8 %a, -1 - // CHECK: ret i1 %[[R]] - discriminant_value(&a) == 1 -} - -#[unsafe(no_mangle)] -pub fn mid_giant_is_thing(a: Mid<Giant>) -> bool { - // CHECK-LABEL: @mid_giant_is_thing( - // CHECK: %[[R:.+]] = icmp samesign ult i128 %a, 5 - // CHECK: ret i1 %[[R]] - discriminant_value(&a) == 1 -} diff --git a/tests/codegen/enum/enum-discriminant-value.rs b/tests/codegen/enum/enum-discriminant-value.rs deleted file mode 100644 index d6b0c6d6c10..00000000000 --- a/tests/codegen/enum/enum-discriminant-value.rs +++ /dev/null @@ -1,27 +0,0 @@ -// Verify that DIEnumerator uses isUnsigned flag when appropriate. -// -//@ compile-flags: -g -C no-prepopulate-passes - -#[repr(i64)] -pub enum I64 { - I64Min = i64::MIN, - I64Max = i64::MAX, -} - -#[repr(u64)] -pub enum U64 { - U64Min = u64::MIN, - U64Max = u64::MAX, -} - -fn main() { - let _a = I64::I64Min; - let _b = I64::I64Max; - let _c = U64::U64Min; - let _d = U64::U64Max; -} - -// CHECK: !DIEnumerator(name: "I64Min", value: -9223372036854775808) -// CHECK: !DIEnumerator(name: "I64Max", value: 9223372036854775807) -// CHECK: !DIEnumerator(name: "U64Min", value: 0, isUnsigned: true) -// CHECK: !DIEnumerator(name: "U64Max", value: 18446744073709551615, isUnsigned: true) diff --git a/tests/codegen/enum/enum-early-otherwise-branch.rs b/tests/codegen/enum/enum-early-otherwise-branch.rs deleted file mode 100644 index 8d39d8e9b74..00000000000 --- a/tests/codegen/enum/enum-early-otherwise-branch.rs +++ /dev/null @@ -1,25 +0,0 @@ -//@ compile-flags: -Copt-level=3 - -#![crate_type = "lib"] - -pub enum Enum { - A(u32), - B(u32), - C(u32), -} - -#[no_mangle] -pub fn foo(lhs: &Enum, rhs: &Enum) -> bool { - // CHECK-LABEL: define{{.*}}i1 @foo( - // CHECK-NOT: switch - // CHECK-NOT: br - // CHECK: [[SELECT:%.*]] = select - // CHECK-NEXT: ret i1 [[SELECT]] - // CHECK-NEXT: } - match (lhs, rhs) { - (Enum::A(lhs), Enum::A(rhs)) => lhs == rhs, - (Enum::B(lhs), Enum::B(rhs)) => lhs == rhs, - (Enum::C(lhs), Enum::C(rhs)) => lhs == rhs, - _ => false, - } -} diff --git a/tests/codegen/enum/enum-match.rs b/tests/codegen/enum/enum-match.rs deleted file mode 100644 index 57db44ec74e..00000000000 --- a/tests/codegen/enum/enum-match.rs +++ /dev/null @@ -1,779 +0,0 @@ -//@ compile-flags: -Copt-level=1 -//@ only-64bit - -#![crate_type = "lib"] -#![feature(core_intrinsics)] - -// Check each of the 3 cases for `codegen_get_discr`. - -// FIXME: once our min-bar LLVM has `range` attributes, update the various -// tests here to no longer have the `range`s and `nsw`s as optional. - -// Case 0: One tagged variant. -pub enum Enum0 { - A(bool), - B, -} - -// CHECK-LABEL: define{{( dso_local)?}} noundef{{( range\(i8 [0-9]+, [0-9]+\))?}} i8 @match0(i8{{.+}}%0) -// CHECK-NEXT: start: -// CHECK-NEXT: %[[IS_B:.+]] = icmp eq i8 %0, 2 -// CHECK-NEXT: %[[TRUNC:.+]] = and i8 %0, 1 -// CHECK-NEXT: %[[R:.+]] = select i1 %[[IS_B]], i8 13, i8 %[[TRUNC]] -// CHECK-NEXT: ret i8 %[[R]] -#[no_mangle] -pub fn match0(e: Enum0) -> u8 { - use Enum0::*; - match e { - A(b) => b as u8, - B => 13, - } -} - -// Case 1: Niche values are on a boundary for `range`. -pub enum Enum1 { - A(bool), - B, - C, -} - -// CHECK-LABEL: define{{( dso_local)?}} noundef{{( range\(i8 [0-9]+, [0-9]+\))?}} i8 @match1(i8{{.+}}%0) -// CHECK-NEXT: start: -// CHECK-NEXT: %[[REL_VAR:.+]] = add{{( nsw)?}} i8 %0, -2 -// CHECK-NEXT: %[[REL_VAR_WIDE:.+]] = zext i8 %[[REL_VAR]] to i64 -// CHECK-NEXT: %[[IS_NICHE:.+]] = icmp{{( samesign)?}} ugt i8 %0, 1 -// CHECK-NEXT: %[[NICHE_DISCR:.+]] = add nuw nsw i64 %[[REL_VAR_WIDE]], 1 -// CHECK-NEXT: %[[DISCR:.+]] = select i1 %[[IS_NICHE]], i64 %[[NICHE_DISCR]], i64 0 -// CHECK-NEXT: switch i64 %[[DISCR]] -#[no_mangle] -pub fn match1(e: Enum1) -> u8 { - use Enum1::*; - match e { - A(b) => b as u8, - B => 13, - C => 100, - } -} - -// Case 2: Special cases don't apply. -#[rustfmt::skip] -pub enum X { - _2=2, _3, _4, _5, _6, _7, _8, _9, _10, _11, - _12, _13, _14, _15, _16, _17, _18, _19, _20, - _21, _22, _23, _24, _25, _26, _27, _28, _29, - _30, _31, _32, _33, _34, _35, _36, _37, _38, - _39, _40, _41, _42, _43, _44, _45, _46, _47, - _48, _49, _50, _51, _52, _53, _54, _55, _56, - _57, _58, _59, _60, _61, _62, _63, _64, _65, - _66, _67, _68, _69, _70, _71, _72, _73, _74, - _75, _76, _77, _78, _79, _80, _81, _82, _83, - _84, _85, _86, _87, _88, _89, _90, _91, _92, - _93, _94, _95, _96, _97, _98, _99, _100, _101, - _102, _103, _104, _105, _106, _107, _108, _109, - _110, _111, _112, _113, _114, _115, _116, _117, - _118, _119, _120, _121, _122, _123, _124, _125, - _126, _127, _128, _129, _130, _131, _132, _133, - _134, _135, _136, _137, _138, _139, _140, _141, - _142, _143, _144, _145, _146, _147, _148, _149, - _150, _151, _152, _153, _154, _155, _156, _157, - _158, _159, _160, _161, _162, _163, _164, _165, - _166, _167, _168, _169, _170, _171, _172, _173, - _174, _175, _176, _177, _178, _179, _180, _181, - _182, _183, _184, _185, _186, _187, _188, _189, - _190, _191, _192, _193, _194, _195, _196, _197, - _198, _199, _200, _201, _202, _203, _204, _205, - _206, _207, _208, _209, _210, _211, _212, _213, - _214, _215, _216, _217, _218, _219, _220, _221, - _222, _223, _224, _225, _226, _227, _228, _229, - _230, _231, _232, _233, _234, _235, _236, _237, - _238, _239, _240, _241, _242, _243, _244, _245, - _246, _247, _248, _249, _250, _251, _252, _253, -} - -pub enum Enum2 { - A(X), - B, - C, - D, - E, -} - -// CHECK-LABEL: define{{( dso_local)?}} noundef{{( range\(i8 [0-9]+, -?[0-9]+\))?}} i8 @match2(i8{{.+}}%0) -// CHECK-NEXT: start: -// CHECK-NEXT: %[[REL_VAR:.+]] = add i8 %0, 2 -// CHECK-NEXT: %[[REL_VAR_WIDE:.+]] = zext i8 %[[REL_VAR]] to i64 -// CHECK-NEXT: %[[IS_NICHE:.+]] = icmp ult i8 %[[REL_VAR]], 4 -// CHECK-NEXT: %[[NICHE_DISCR:.+]] = add nuw nsw i64 %[[REL_VAR_WIDE]], 1 -// CHECK-NEXT: %[[DISCR:.+]] = select i1 %[[IS_NICHE]], i64 %[[NICHE_DISCR]], i64 0 -// CHECK-NEXT: switch i64 %[[DISCR]] -#[no_mangle] -pub fn match2(e: Enum2) -> u8 { - use Enum2::*; - match e { - A(b) => b as u8, - B => 13, - C => 100, - D => 200, - E => 250, - } -} - -// And make sure it works even if the niched scalar is a pointer. -// (For example, that we don't try to `sub` on pointers.) - -// CHECK-LABEL: define{{( dso_local)?}} noundef{{( range\(i16 -?[0-9]+, -?[0-9]+\))?}} i16 @match3(ptr{{.+}}%0) -// CHECK-NEXT: start: -// CHECK-NEXT: %[[IS_NULL:.+]] = icmp eq ptr %0, null -// CHECK-NEXT: br i1 %[[IS_NULL]] -#[no_mangle] -pub fn match3(e: Option<&u8>) -> i16 { - match e { - Some(r) => *r as _, - None => -1, - } -} - -// If the untagged variant is in the middle, there's an impossible value that's -// not reflected in the `range` parameter attribute, so we assume it away. - -#[derive(PartialEq)] -pub enum MiddleNiche { - A, - B, - C(bool), - D, - E, -} - -// CHECK-LABEL: define{{( dso_local)?}} noundef{{( range\(i8 -?[0-9]+, -?[0-9]+\))?}} i8 @match4(i8{{.+}}%0) -// CHECK-NEXT: start: -// CHECK-NEXT: %[[REL_VAR:.+]] = add{{( nsw)?}} i8 %0, -2 -// CHECK-NEXT: %[[NOT_IMPOSSIBLE:.+]] = icmp ne i8 %[[REL_VAR]], 2 -// CHECK-NEXT: call void @llvm.assume(i1 %[[NOT_IMPOSSIBLE]]) -// CHECK-NEXT: %[[NOT_NICHE:.+]] = icmp{{( samesign)?}} ult i8 %0, 2 -// CHECK-NEXT: %[[DISCR:.+]] = select i1 %[[NOT_NICHE]], i8 2, i8 %[[REL_VAR]] -// CHECK-NEXT: switch i8 %[[DISCR]] -#[no_mangle] -pub fn match4(e: MiddleNiche) -> u8 { - use MiddleNiche::*; - match e { - A => 13, - B => 100, - C(b) => b as u8, - D => 200, - E => 250, - } -} - -// CHECK-LABEL: define{{.+}}i1 @match4_is_c(i8{{.+}}%e) -// CHECK-NEXT: start -// CHECK-NEXT: %[[NOT_IMPOSSIBLE:.+]] = icmp ne i8 %e, 4 -// CHECK-NEXT: call void @llvm.assume(i1 %[[NOT_IMPOSSIBLE]]) -// CHECK-NEXT: %[[IS_C:.+]] = icmp{{( samesign)?}} ult i8 %e, 2 -// CHECK-NEXT: ret i1 %[[IS_C]] -#[no_mangle] -pub fn match4_is_c(e: MiddleNiche) -> bool { - // Before #139098, this couldn't optimize out the `select` because it looked - // like it was possible for a `2` to be produced on both sides. - - std::intrinsics::discriminant_value(&e) == 2 -} - -// You have to do something pretty obnoxious to get a variant index that doesn't -// fit in the tag size, but it's possible - -pub enum Never {} - -pub enum HugeVariantIndex { - V000(Never), - V001(Never), - V002(Never), - V003(Never), - V004(Never), - V005(Never), - V006(Never), - V007(Never), - V008(Never), - V009(Never), - V010(Never), - V011(Never), - V012(Never), - V013(Never), - V014(Never), - V015(Never), - V016(Never), - V017(Never), - V018(Never), - V019(Never), - V020(Never), - V021(Never), - V022(Never), - V023(Never), - V024(Never), - V025(Never), - V026(Never), - V027(Never), - V028(Never), - V029(Never), - V030(Never), - V031(Never), - V032(Never), - V033(Never), - V034(Never), - V035(Never), - V036(Never), - V037(Never), - V038(Never), - V039(Never), - V040(Never), - V041(Never), - V042(Never), - V043(Never), - V044(Never), - V045(Never), - V046(Never), - V047(Never), - V048(Never), - V049(Never), - V050(Never), - V051(Never), - V052(Never), - V053(Never), - V054(Never), - V055(Never), - V056(Never), - V057(Never), - V058(Never), - V059(Never), - V060(Never), - V061(Never), - V062(Never), - V063(Never), - V064(Never), - V065(Never), - V066(Never), - V067(Never), - V068(Never), - V069(Never), - V070(Never), - V071(Never), - V072(Never), - V073(Never), - V074(Never), - V075(Never), - V076(Never), - V077(Never), - V078(Never), - V079(Never), - V080(Never), - V081(Never), - V082(Never), - V083(Never), - V084(Never), - V085(Never), - V086(Never), - V087(Never), - V088(Never), - V089(Never), - V090(Never), - V091(Never), - V092(Never), - V093(Never), - V094(Never), - V095(Never), - V096(Never), - V097(Never), - V098(Never), - V099(Never), - V100(Never), - V101(Never), - V102(Never), - V103(Never), - V104(Never), - V105(Never), - V106(Never), - V107(Never), - V108(Never), - V109(Never), - V110(Never), - V111(Never), - V112(Never), - V113(Never), - V114(Never), - V115(Never), - V116(Never), - V117(Never), - V118(Never), - V119(Never), - V120(Never), - V121(Never), - V122(Never), - V123(Never), - V124(Never), - V125(Never), - V126(Never), - V127(Never), - V128(Never), - V129(Never), - V130(Never), - V131(Never), - V132(Never), - V133(Never), - V134(Never), - V135(Never), - V136(Never), - V137(Never), - V138(Never), - V139(Never), - V140(Never), - V141(Never), - V142(Never), - V143(Never), - V144(Never), - V145(Never), - V146(Never), - V147(Never), - V148(Never), - V149(Never), - V150(Never), - V151(Never), - V152(Never), - V153(Never), - V154(Never), - V155(Never), - V156(Never), - V157(Never), - V158(Never), - V159(Never), - V160(Never), - V161(Never), - V162(Never), - V163(Never), - V164(Never), - V165(Never), - V166(Never), - V167(Never), - V168(Never), - V169(Never), - V170(Never), - V171(Never), - V172(Never), - V173(Never), - V174(Never), - V175(Never), - V176(Never), - V177(Never), - V178(Never), - V179(Never), - V180(Never), - V181(Never), - V182(Never), - V183(Never), - V184(Never), - V185(Never), - V186(Never), - V187(Never), - V188(Never), - V189(Never), - V190(Never), - V191(Never), - V192(Never), - V193(Never), - V194(Never), - V195(Never), - V196(Never), - V197(Never), - V198(Never), - V199(Never), - V200(Never), - V201(Never), - V202(Never), - V203(Never), - V204(Never), - V205(Never), - V206(Never), - V207(Never), - V208(Never), - V209(Never), - V210(Never), - V211(Never), - V212(Never), - V213(Never), - V214(Never), - V215(Never), - V216(Never), - V217(Never), - V218(Never), - V219(Never), - V220(Never), - V221(Never), - V222(Never), - V223(Never), - V224(Never), - V225(Never), - V226(Never), - V227(Never), - V228(Never), - V229(Never), - V230(Never), - V231(Never), - V232(Never), - V233(Never), - V234(Never), - V235(Never), - V236(Never), - V237(Never), - V238(Never), - V239(Never), - V240(Never), - V241(Never), - V242(Never), - V243(Never), - V244(Never), - V245(Never), - V246(Never), - V247(Never), - V248(Never), - V249(Never), - V250(Never), - V251(Never), - V252(Never), - V253(Never), - V254(Never), - V255(Never), - V256(Never), - - Possible257, - Bool258(bool), - Possible259, -} - -// CHECK-LABEL: define{{( dso_local)?}} noundef{{( range\(i8 [0-9]+, [0-9]+\))?}} i8 @match5(i8{{.+}}%0) -// CHECK-NEXT: start: -// CHECK-NEXT: %[[REL_VAR:.+]] = add{{( nsw)?}} i8 %0, -2 -// CHECK-NEXT: %[[REL_VAR_WIDE:.+]] = zext i8 %[[REL_VAR]] to i64 -// CHECK-NEXT: %[[IS_NICHE:.+]] = icmp{{( samesign)?}} ugt i8 %0, 1 -// CHECK-NEXT: %[[NICHE_DISCR:.+]] = add nuw nsw i64 %[[REL_VAR_WIDE]], 257 -// CHECK-NEXT: %[[NOT_IMPOSSIBLE:.+]] = icmp ne i64 %[[NICHE_DISCR]], 258 -// CHECK-NEXT: call void @llvm.assume(i1 %[[NOT_IMPOSSIBLE]]) -// CHECK-NEXT: %[[DISCR:.+]] = select i1 %[[IS_NICHE]], i64 %[[NICHE_DISCR]], i64 258 -// CHECK-NEXT: switch i64 %[[DISCR]], -// CHECK-NEXT: i64 257, -// CHECK-NEXT: i64 258, -// CHECK-NEXT: i64 259, -#[no_mangle] -pub fn match5(e: HugeVariantIndex) -> u8 { - use HugeVariantIndex::*; - match e { - Possible257 => 13, - Bool258(b) => b as u8, - Possible259 => 100, - } -} - -// Make an enum where the niche tags wrap both as signed and as unsigned, to hit -// the most-fallback case where there's just nothing smart to do. - -pub enum E10Through65 { - D10 = 10, - D11 = 11, - D12 = 12, - D13 = 13, - D14 = 14, - D15 = 15, - D16 = 16, - D17 = 17, - D18 = 18, - D19 = 19, - D20 = 20, - D21 = 21, - D22 = 22, - D23 = 23, - D24 = 24, - D25 = 25, - D26 = 26, - D27 = 27, - D28 = 28, - D29 = 29, - D30 = 30, - D31 = 31, - D32 = 32, - D33 = 33, - D34 = 34, - D35 = 35, - D36 = 36, - D37 = 37, - D38 = 38, - D39 = 39, - D40 = 40, - D41 = 41, - D42 = 42, - D43 = 43, - D44 = 44, - D45 = 45, - D46 = 46, - D47 = 47, - D48 = 48, - D49 = 49, - D50 = 50, - D51 = 51, - D52 = 52, - D53 = 53, - D54 = 54, - D55 = 55, - D56 = 56, - D57 = 57, - D58 = 58, - D59 = 59, - D60 = 60, - D61 = 61, - D62 = 62, - D63 = 63, - D64 = 64, - D65 = 65, -} - -pub enum Tricky { - Untagged(E10Through65), - V001, - V002, - V003, - V004, - V005, - V006, - V007, - V008, - V009, - V010, - V011, - V012, - V013, - V014, - V015, - V016, - V017, - V018, - V019, - V020, - V021, - V022, - V023, - V024, - V025, - V026, - V027, - V028, - V029, - V030, - V031, - V032, - V033, - V034, - V035, - V036, - V037, - V038, - V039, - V040, - V041, - V042, - V043, - V044, - V045, - V046, - V047, - V048, - V049, - V050, - V051, - V052, - V053, - V054, - V055, - V056, - V057, - V058, - V059, - V060, - V061, - V062, - V063, - V064, - V065, - V066, - V067, - V068, - V069, - V070, - V071, - V072, - V073, - V074, - V075, - V076, - V077, - V078, - V079, - V080, - V081, - V082, - V083, - V084, - V085, - V086, - V087, - V088, - V089, - V090, - V091, - V092, - V093, - V094, - V095, - V096, - V097, - V098, - V099, - V100, - V101, - V102, - V103, - V104, - V105, - V106, - V107, - V108, - V109, - V110, - V111, - V112, - V113, - V114, - V115, - V116, - V117, - V118, - V119, - V120, - V121, - V122, - V123, - V124, - V125, - V126, - V127, - V128, - V129, - V130, - V131, - V132, - V133, - V134, - V135, - V136, - V137, - V138, - V139, - V140, - V141, - V142, - V143, - V144, - V145, - V146, - V147, - V148, - V149, - V150, - V151, - V152, - V153, - V154, - V155, - V156, - V157, - V158, - V159, - V160, - V161, - V162, - V163, - V164, - V165, - V166, - V167, - V168, - V169, - V170, - V171, - V172, - V173, - V174, - V175, - V176, - V177, - V178, - V179, - V180, - V181, - V182, - V183, - V184, - V185, - V186, - V187, - V188, - V189, - V190, - V191, - V192, - V193, - V194, - V195, - V196, - V197, - V198, - V199, - V200, -} - -const _: () = assert!(std::intrinsics::discriminant_value(&Tricky::V100) == 100); - -// CHECK-LABEL: define noundef{{( range\(i8 [0-9]+, [0-9]+\))?}} i8 @discriminant6(i8 noundef %e) -// CHECK-NEXT: start: -// CHECK-NEXT: %[[REL_VAR:.+]] = add i8 %e, -66 -// CHECK-NEXT: %[[IS_NICHE:.+]] = icmp ult i8 %[[REL_VAR]], -56 -// CHECK-NEXT: %[[TAGGED_DISCR:.+]] = add i8 %e, -65 -// CHECK-NEXT: %[[DISCR:.+]] = select i1 %[[IS_NICHE]], i8 %[[TAGGED_DISCR]], i8 0 -// CHECK-NEXT: ret i8 %[[DISCR]] -#[no_mangle] -pub fn discriminant6(e: Tricky) -> u8 { - std::intrinsics::discriminant_value(&e) as _ -} - -// Case from <https://github.com/rust-lang/rust/issues/104519>, -// where sign-extension is important. - -pub enum OpenResult { - Ok(()), - Err(()), - TransportErr(TransportErr), -} - -#[repr(i32)] -pub enum TransportErr { - UnknownMethod = -2, -} - -#[no_mangle] -pub fn match7(result: OpenResult) -> u8 { - // CHECK-LABEL: define noundef{{( range\(i8 [0-9]+, [0-9]+\))?}} i8 @match7(i32{{.+}}%result) - // CHECK-NEXT: start: - // CHECK-NEXT: %[[NOT_OK:.+]] = icmp ne i32 %result, -1 - // CHECK-NEXT: %[[RET:.+]] = zext i1 %[[NOT_OK]] to i8 - // CHECK-NEXT: ret i8 %[[RET]] - match result { - OpenResult::Ok(()) => 0, - _ => 1, - } -} diff --git a/tests/codegen/enum/enum-two-variants-match.rs b/tests/codegen/enum/enum-two-variants-match.rs deleted file mode 100644 index 12d9edc4d62..00000000000 --- a/tests/codegen/enum/enum-two-variants-match.rs +++ /dev/null @@ -1,130 +0,0 @@ -//@ compile-flags: -Copt-level=3 -C no-prepopulate-passes -//@ only-64bit (because these discriminants are isize) - -#![crate_type = "lib"] - -// This directly tests what we emit for these matches, rather than what happens -// after optimization, so it doesn't need to worry about extra flags on the -// instructions and is less susceptible to being broken on LLVM updates. - -// CHECK-LABEL: @option_match -#[no_mangle] -pub fn option_match(x: Option<i32>) -> u16 { - // CHECK-NOT: %x = alloca - // CHECK: %[[OUT:.+]] = alloca [2 x i8] - // CHECK-NOT: %x = alloca - - // CHECK: %[[DISCR:.+]] = zext i32 %x.0 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, ptr %[[OUT]] - - // CHECK: [[FALSE]]: - // CHECK: store i16 42, ptr %[[OUT]] - - // CHECK: %[[RET:.+]] = load i16, ptr %[[OUT]] - // CHECK: ret i16 %[[RET]] - match x { - Some(_) => 13, - None => 42, - } -} - -// CHECK-LABEL: @result_match -#[no_mangle] -pub fn result_match(x: Result<u64, i64>) -> u16 { - // CHECK-NOT: %x = alloca - // CHECK: %[[OUT:.+]] = alloca [2 x i8] - // CHECK-NOT: %x = alloca - - // CHECK: %[[COND:.+]] = trunc nuw i64 %x.0 to i1 - // CHECK: br i1 %[[COND]], label %[[TRUE:[a-z0-9]+]], label %[[FALSE:[a-z0-9]+]] - - // CHECK: [[TRUE]]: - // CHECK: store i16 13, ptr %[[OUT]] - - // CHECK: [[FALSE]]: - // CHECK: store i16 42, ptr %[[OUT]] - - // CHECK: %[[RET:.+]] = load i16, ptr %[[OUT]] - // CHECK: ret i16 %[[RET]] - match x { - Err(_) => 13, - Ok(_) => 42, - } -} - -// CHECK-LABEL: @option_bool_match( -#[no_mangle] -pub fn option_bool_match(x: Option<bool>) -> char { - // CHECK: %[[RAW:.+]] = load i8, ptr %x - // CHECK: %[[IS_NONE:.+]] = icmp eq i8 %[[RAW]], 2 - // CHECK: %[[OPT_DISCR:.+]] = select i1 %[[IS_NONE]], i64 0, i64 1 - // CHECK: %[[OPT_DISCR_T:.+]] = trunc nuw i64 %[[OPT_DISCR]] to i1 - // CHECK: br i1 %[[OPT_DISCR_T]], label %[[BB_SOME:.+]], label %[[BB_NONE:.+]] - - // CHECK: [[BB_SOME]]: - // CHECK: %[[FIELD:.+]] = load i8, ptr %x - // CHECK: %[[FIELD_T:.+]] = trunc nuw i8 %[[FIELD]] to i1 - // CHECK: br i1 %[[FIELD_T]] - match x { - None => 'n', - Some(false) => 'f', - Some(true) => 't', - } -} - -use std::cmp::Ordering::{self, *}; -// CHECK-LABEL: @option_ordering_match( -#[no_mangle] -pub fn option_ordering_match(x: Option<Ordering>) -> char { - // CHECK: %[[RAW:.+]] = load i8, ptr %x - // CHECK: %[[IS_NONE:.+]] = icmp eq i8 %[[RAW]], 2 - // CHECK: %[[OPT_DISCR:.+]] = select i1 %[[IS_NONE]], i64 0, i64 1 - // CHECK: %[[OPT_DISCR_T:.+]] = trunc nuw i64 %[[OPT_DISCR]] to i1 - // CHECK: br i1 %[[OPT_DISCR_T]], label %[[BB_SOME:.+]], label %[[BB_NONE:.+]] - - // CHECK: [[BB_SOME]]: - // CHECK: %[[FIELD:.+]] = load i8, ptr %x - // CHECK: switch i8 %[[FIELD]], label %[[UNREACHABLE:.+]] [ - // CHECK-NEXT: i8 -1, label - // CHECK-NEXT: i8 0, label - // CHECK-NEXT: i8 1, label - // CHECK-NEXT: ] - - // CHECK: [[UNREACHABLE]]: - // CHECK-NEXT: unreachable - match x { - None => '?', - Some(Less) => '<', - Some(Equal) => '=', - Some(Greater) => '>', - } -} - -// CHECK-LABEL: @option_nonzero_match( -#[no_mangle] -pub fn option_nonzero_match(x: Option<std::num::NonZero<u16>>) -> u16 { - // CHECK: %[[OUT:.+]] = alloca [2 x i8] - - // CHECK: %[[IS_NONE:.+]] = icmp eq i16 %x, 0 - // CHECK: %[[OPT_DISCR:.+]] = select i1 %[[IS_NONE]], i64 0, i64 1 - // CHECK: %[[OPT_DISCR_T:.+]] = trunc nuw i64 %[[OPT_DISCR]] to i1 - // CHECK: br i1 %[[OPT_DISCR_T]], label %[[BB_SOME:.+]], label %[[BB_NONE:.+]] - - // CHECK: [[BB_SOME]]: - // CHECK: store i16 987, ptr %[[OUT]] - - // CHECK: [[BB_NONE]]: - // CHECK: store i16 123, ptr %[[OUT]] - - // CHECK: %[[RET:.+]] = load i16, ptr %[[OUT]] - // CHECK: ret i16 %[[RET]] - - match x { - None => 123, - Some(_) => 987, - } -} diff --git a/tests/codegen/enum/enum-u128.rs b/tests/codegen/enum/enum-u128.rs deleted file mode 100644 index 2676669f3e3..00000000000 --- a/tests/codegen/enum/enum-u128.rs +++ /dev/null @@ -1,25 +0,0 @@ -// This tests that debug info for "c-like" 128bit enums is properly emitted. -// This is ignored for the fallback mode on MSVC due to problems with PDB. - -// -//@ ignore-msvc -//@ ignore-wasi wasi codegens the main symbol differently - -//@ compile-flags: -g -C no-prepopulate-passes - -// CHECK-LABEL: @main -// CHECK: {{.*}}DICompositeType{{.*}}tag: DW_TAG_enumeration_type,{{.*}}name: "Foo",{{.*}}flags: DIFlagEnumClass,{{.*}} -// CHECK: {{.*}}DIEnumerator{{.*}}name: "Lo",{{.*}}value: 0,{{.*}} -// CHECK: {{.*}}DIEnumerator{{.*}}name: "Hi",{{.*}}value: 18446744073709551616,{{.*}} -// CHECK: {{.*}}DIEnumerator{{.*}}name: "Bar",{{.*}}value: 18446745000000000123,{{.*}} - -#[repr(u128)] -pub enum Foo { - Lo, - Hi = 1 << 64, - Bar = 18_446_745_000_000_000_123, -} - -pub fn main() { - let foo = Foo::Bar; -} diff --git a/tests/codegen/enum/unreachable_enum_default_branch.rs b/tests/codegen/enum/unreachable_enum_default_branch.rs deleted file mode 100644 index 55b165fc111..00000000000 --- a/tests/codegen/enum/unreachable_enum_default_branch.rs +++ /dev/null @@ -1,40 +0,0 @@ -//@ compile-flags: -Copt-level=3 - -#![crate_type = "lib"] - -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -pub struct Int(u32); - -const A: Int = Int(201); -const B: Int = Int(270); -const C: Int = Int(153); - -// The code is from https://github.com/rust-lang/rust/issues/119520. -// This code will basically turn into `matches!(x.partial_cmp(&A), Some(Greater | Equal))`. -// The otherwise branch must be `Less`. -// CHECK-LABEL: @implicit_match( -// CHECK-SAME: [[TMP0:%.*]]) -// CHECK-NEXT: start: -// CHECK-NEXT: [[TMP1:%.*]] = add i32 [[TMP0]], -201 -// CHECK-NEXT: icmp ult i32 [[TMP1]], 70 -// CHECK-NEXT: icmp eq i32 [[TMP0]], 153 -// CHECK-NEXT: [[SPEC_SELECT:%.*]] = or i1 -// CHECK-NEXT: ret i1 [[SPEC_SELECT]] -#[no_mangle] -pub fn implicit_match(x: Int) -> bool { - (x >= A && x <= B) || x == C -} - -// The code is from https://github.com/rust-lang/rust/issues/110097. -// We expect it to generate the same optimized code as a full match. -// CHECK-LABEL: @if_let( -// CHECK: start: -// CHECK-NOT: zext -// CHECK: select -// CHECK-NEXT: insertvalue -// CHECK-NEXT: insertvalue -// CHECK-NEXT: ret -#[no_mangle] -pub fn if_let(val: Result<i32, ()>) -> Result<i32, ()> { - if let Ok(x) = val { Ok(x * 2) } else { Err(()) } -} |
