Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit f0a4148

Browse files
authored
Rollup merge of #145380 - okaneco:add-codegen-tests, r=Mark-Simulacrum
Add codegen-llvm regression tests Most of these regressions deal with elimination of panics and bounds checks that were fixed upstream by LLVM. closes #141497 closes #131162 closes #129583 closes #110971 closes #91109 closes #80075 closes #74917 closes #71997 closes #71257 closes #59352
2 parents 5cfdbd6 + 9e28de2 commit f0a4148

10 files changed

+182
-0
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//@ compile-flags: -Copt-level=3
2+
//@ min-llvm-version: 20
3+
4+
#![crate_type = "lib"]
5+
6+
// CHECK-LABEL: @issue_131162
7+
#[no_mangle]
8+
pub fn issue_131162(a1: usize, a2: usize) -> bool {
9+
const MASK: usize = 1;
10+
11+
// CHECK-NOT: xor
12+
// CHECK-NOT: trunc
13+
// CHECK-NOT: and i1
14+
// CHECK: icmp
15+
// CHECK-NEXT: ret
16+
(a1 & !MASK) == (a2 & !MASK) && (a1 & MASK) == (a2 & MASK)
17+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Tests that there's no bounds check within for-loop after asserting that
2+
// the range start and end are within bounds.
3+
4+
//@ compile-flags: -Copt-level=3
5+
6+
#![crate_type = "lib"]
7+
8+
// CHECK-LABEL: @no_bounds_check_after_assert
9+
#[no_mangle]
10+
fn no_bounds_check_after_assert(slice: &[u64], start: usize, end: usize) -> u64 {
11+
// CHECK-NOT: panic_bounds_check
12+
let mut total = 0;
13+
assert!(start < end && start < slice.len() && end <= slice.len());
14+
for i in start..end {
15+
total += slice[i];
16+
}
17+
total
18+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Tests that there is no check for dividing by zero since the
2+
// denominator, `(x - y)`, will always be greater than 0 since `x > y`.
3+
4+
//@ compile-flags: -Copt-level=3
5+
6+
#![crate_type = "lib"]
7+
8+
// CHECK-LABEL: @issue_74917
9+
#[no_mangle]
10+
pub fn issue_74917(x: u16, y: u16) -> u16 {
11+
// CHECK-NOT: panic
12+
if x > y { 100 / (x - y) } else { 100 }
13+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Tests that there's no bounds check for the inner loop after the assert.
2+
3+
//@ compile-flags: -Copt-level=3
4+
5+
#![crate_type = "lib"]
6+
7+
// CHECK-LABEL: @zero
8+
#[no_mangle]
9+
pub fn zero(d: &mut [Vec<i32>]) {
10+
// CHECK-NOT: panic_bounds_check
11+
let n = d.len();
12+
for i in 0..n {
13+
assert!(d[i].len() == n);
14+
for j in 0..n {
15+
d[i][j] = 0;
16+
}
17+
}
18+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Tests that `unwrap` is optimized out when the slice has a known length.
2+
// The iterator may unroll for values smaller than a certain threshold so we
3+
// use a larger value to prevent unrolling.
4+
5+
//@ compile-flags: -Copt-level=3
6+
//@ min-llvm-version: 20
7+
8+
#![crate_type = "lib"]
9+
10+
// CHECK-LABEL: @infallible_max_not_unrolled
11+
#[no_mangle]
12+
pub fn infallible_max_not_unrolled(x: &[u8; 1024]) -> u8 {
13+
// CHECK-NOT: panic
14+
// CHECK-NOT: unwrap_failed
15+
*x.iter().max().unwrap()
16+
}
17+
18+
// CHECK-LABEL: @infallible_max_unrolled
19+
#[no_mangle]
20+
pub fn infallible_max_unrolled(x: &[u8; 10]) -> u8 {
21+
// CHECK-NOT: panic
22+
// CHECK-NOT: unwrap_failed
23+
*x.iter().max().unwrap()
24+
}
25+
26+
// CHECK-LABEL: @may_panic_max
27+
#[no_mangle]
28+
pub fn may_panic_max(x: &[u8]) -> u8 {
29+
// CHECK: unwrap_failed
30+
*x.iter().max().unwrap()
31+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Tests that `matches!` optimizes the same as
2+
// `f == FrameType::Inter || f == FrameType::Switch`.
3+
4+
//@ compile-flags: -Copt-level=3
5+
//@ min-llvm-version: 21
6+
7+
#![crate_type = "lib"]
8+
9+
#[derive(Clone, Copy, PartialEq, Eq)]
10+
pub enum FrameType {
11+
Key = 0,
12+
Inter = 1,
13+
Intra = 2,
14+
Switch = 3,
15+
}
16+
17+
// CHECK-LABEL: @is_inter_or_switch
18+
#[no_mangle]
19+
pub fn is_inter_or_switch(f: FrameType) -> bool {
20+
// CHECK-NEXT: start:
21+
// CHECK-NEXT: and i8
22+
// CHECK-NEXT: icmp
23+
// CHECK-NEXT: ret
24+
matches!(f, FrameType::Inter | FrameType::Switch)
25+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Tests that the slice access for `j` doesn't have a bounds check panic after
2+
// being asserted as less than half of the slice length.
3+
4+
//@ compile-flags: -Copt-level=3
5+
6+
#![crate_type = "lib"]
7+
8+
// CHECK-LABEL: @check_only_assert_panic
9+
#[no_mangle]
10+
pub fn check_only_assert_panic(arr: &[u32], j: usize) -> u32 {
11+
// CHECK-NOT: panic_bounds_check
12+
assert!(j < arr.len() / 2);
13+
arr[j]
14+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Tests that the `unwrap` branch is optimized out from the `pop` since the
2+
// length has already been validated.
3+
4+
//@ compile-flags: -Copt-level=3
5+
6+
#![crate_type = "lib"]
7+
8+
pub enum Foo {
9+
First(usize),
10+
Second(usize),
11+
}
12+
13+
// CHECK-LABEL: @check_only_one_panic
14+
#[no_mangle]
15+
pub fn check_only_one_panic(v: &mut Vec<Foo>) -> Foo {
16+
// CHECK-COUNT-1: call{{.+}}panic
17+
assert!(v.len() == 1);
18+
v.pop().unwrap()
19+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Tests that there's no panic on unwrapping `to_digit` call after checking
2+
// with `is_digit`.
3+
4+
//@ compile-flags: -Copt-level=3
5+
6+
#![crate_type = "lib"]
7+
8+
// CHECK-LABEL: @num_to_digit_slow
9+
#[no_mangle]
10+
pub fn num_to_digit_slow(num: char) -> u32 {
11+
// CHECK-NOT: br
12+
// CHECK-NOT: panic
13+
if num.is_digit(8) { num.to_digit(8).unwrap() } else { 0 }
14+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Tests that no bounds check panic is generated for `j` since
2+
// `j <= i < data.len()`.
3+
4+
//@ compile-flags: -Copt-level=3
5+
6+
#![crate_type = "lib"]
7+
8+
// CHECK-LABEL: @issue_80075
9+
#[no_mangle]
10+
pub fn issue_80075(data: &[u8], i: usize, j: usize) -> u8 {
11+
// CHECK-NOT: panic_bounds_check
12+
if i < data.len() && j <= i { data[j] } else { 0 }
13+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /