Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add codegen tests for E-needs-test #125347

Merged
merged 14 commits into from
Jun 14, 2024
27 changes: 27 additions & 0 deletions tests/assembly/issue-83585-small-pod-struct-equality.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//@ assembly-output: emit-asm
//@ compile-flags: -Copt-level=3
//@ only-x86_64

#![crate_type = "lib"]

type T = u8;
type T1 = (T, T, T, T, T, T, T, T);

// CHECK-LABEL: foo1a
// CHECK: cmpq
// CHECK-NEXT: sete
// CHECK-NEXT: {{retq|popq}}
#[no_mangle]
pub fn foo1a(a: T1, b: T1) -> bool {
a == b
}

// CHECK-LABEL: foo1b
// CHECK: movq
// CHECK: cmpq
// CHECK-NEXT: sete
// CHECK-NEXT: {{retq|popq}}
#[no_mangle]
pub fn foo1b(a: &T1, b: &T1) -> bool {
a == b
}
16 changes: 16 additions & 0 deletions tests/codegen/issues/issue-109328-split_first.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//@ compile-flags: -O

#![crate_type = "lib"]

// CHECK-LABEL: @foo
// CHECK-NEXT: {{.*}}:
// CHECK-NEXT: getelementptr inbounds
// CHECK-NEXT: load [[TYPE:i(32|64)]]
// CHECK-NEXT: icmp eq [[TYPE]]
// CHECK-NEXT: br i1
#[no_mangle]
pub fn foo(input: &mut &[u64]) -> Option<u64> {
let (first, rest) = input.split_first()?;
*input = rest;
Some(*first)
}
26 changes: 26 additions & 0 deletions tests/codegen/issues/issue-110797-enum-jump-same.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//@ compile-flags: -O
//@ min-llvm-version: 18

#![crate_type = "lib"]

pub enum K {
A(Box<[i32]>),
B(Box<[u8]>),
C(Box<[String]>),
D(Box<[u16]>),
}

// CHECK-LABEL: @get_len
// CHECK-NEXT: {{.*}}:
// CHECK-NEXT: getelementptr inbounds
// CHECK-NEXT: load [[TYPE:i(32|64)]]
// CHECK-NEXT: ret [[TYPE]]
#[no_mangle]
pub fn get_len(arg: &K) -> usize {
match arg {
K::A(ref lst) => lst.len(),
K::B(ref lst) => lst.len(),
K::C(ref lst) => lst.len(),
K::D(ref lst) => lst.len(),
}
}
22 changes: 22 additions & 0 deletions tests/codegen/issues/issue-111508-vec-tryinto-array.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//@ compile-flags: -O
// This regress since Rust version 1.72.
//@ min-llvm-version: 18.1.4

#![crate_type = "lib"]

use std::convert::TryInto;

const N: usize = 24;

// CHECK-LABEL: @example
// CHECK-NOT: unwrap_failed
#[no_mangle]
pub fn example(a: Vec<u8>) -> u8 {
if a.len() != 32 {
return 0;
}

let a: [u8; 32] = a.try_into().unwrap();

a[15] + a[N]
}
12 changes: 12 additions & 0 deletions tests/codegen/issues/issue-112509-slice-get-andthen-get.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//@ compile-flags: -O
#![crate_type = "lib"]

// CHECK-LABEL: @write_u8_variant_a
// CHECK-NEXT: {{.*}}:
// CHECK-NEXT: getelementptr
// CHECK-NEXT: icmp ugt
#[no_mangle]
pub fn write_u8_variant_a(bytes: &mut [u8], buf: u8, offset: usize) -> Option<&mut [u8]> {
let buf = buf.to_le_bytes();
bytes.get_mut(offset..).and_then(|bytes| bytes.get_mut(..buf.len()))
}
18 changes: 18 additions & 0 deletions tests/codegen/issues/issue-113757-bounds-check-after-cmp-max.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// in Rust 1.73, -O and opt-level=3 optimizes differently
//@ compile-flags: -C opt-level=3
#![crate_type = "lib"]

use std::cmp::max;

// CHECK-LABEL: @foo
// CHECK-NOT: slice_start_index_len_fail
// CHECK-NOT: unreachable
#[no_mangle]
pub fn foo(v: &mut Vec<u8>, size: usize) -> Option<&mut [u8]> {
if v.len() > max(1, size) {
let start = v.len() - size;
Some(&mut v[start..])
} else {
None
}
}
11 changes: 11 additions & 0 deletions tests/codegen/issues/issue-118392.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//@ compile-flags: -O
//@ min-llvm-version: 18
#![crate_type = "lib"]

// CHECK-LABEL: @div2
// CHECK: ashr i32 %a, 1
// CHECK-NEXT: ret i32
#[no_mangle]
pub fn div2(a: i32) -> i32 {
a.div_euclid(2)
}
28 changes: 28 additions & 0 deletions tests/codegen/issues/issue-36010-some-box-is_some.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#![crate_type = "lib"]

//@ compile-flags: -O

use std::mem;

fn foo<T>(a: &mut T, b: T) -> bool {
let b = Some(mem::replace(a, b));
let ret = b.is_some();
mem::forget(b);
return ret;
}

// CHECK-LABEL: @foo_u32
// CHECK: store i32
// CHECK-NEXT: ret i1 true
#[no_mangle]
pub fn foo_u32(a: &mut u32, b: u32) -> bool {
foo(a, b)
}

// CHECK-LABEL: @foo_box
// CHECK: store ptr
// CHECK-NEXT: ret i1 true
#[no_mangle]
pub fn foo_box(a: &mut Box<u32>, b: Box<u32>) -> bool {
foo(a, b)
}
15 changes: 15 additions & 0 deletions tests/codegen/issues/issue-68667-unwrap-combinators.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#![crate_type = "lib"]

//@ compile-flags: -O

// MIR inlining now optimizes this code.

// CHECK-LABEL: @unwrap_combinators
// CHECK: icmp
// CHECK-NEXT: icmp
// CHECK-NEXT: select i1
// CHECK-NEXT: ret i1
#[no_mangle]
pub fn unwrap_combinators(a: Option<i32>, b: i32) -> bool {
a.map(|t| t >= b).unwrap_or(false)
}
14 changes: 14 additions & 0 deletions tests/codegen/issues/issue-74938-array-split-at.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//@ compile-flags: -O

#![crate_type = "lib"]

const N: usize = 3;
pub type T = u8;

// CHECK-LABEL: @split_multiple
// CHECK-NOT: unreachable
#[no_mangle]
pub fn split_multiple(slice: &[T]) -> (&[T], &[T]) {
let len = slice.len() / N;
slice.split_at(len * N)
}
14 changes: 14 additions & 0 deletions tests/codegen/issues/issue-93036-assert-index.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//@ compile-flags: -O

#![crate_type = "lib"]

#[no_mangle]
// CHECK-LABEL: @foo
// CHECK-NOT: unreachable
pub fn foo(arr: &mut [u32]) {
for i in 0..arr.len() {
for j in 0..i {
assert!(j < arr.len());
}
}
}
19 changes: 19 additions & 0 deletions tests/codegen/slice-pointer-nonnull-unwrap.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//@ compile-flags: -O
//@ min-llvm-version: 18
#![crate_type = "lib"]

use std::ptr::NonNull;

// CHECK-LABEL: @slice_ptr_len_1
// CHECK-NEXT: {{.*}}:
// CHECK-NEXT: ret {{i(32|64)}} %ptr.1
#[no_mangle]
pub fn slice_ptr_len_1(ptr: *const [u8]) -> usize {
let ptr = ptr.cast_mut();
if let Some(ptr) = NonNull::new(ptr) {
ptr.len()
} else {
// We know ptr is null, so we know ptr.wrapping_byte_add(1) is not null.
NonNull::new(ptr.wrapping_byte_add(1)).unwrap().len()
}
}
Loading