diff --git a/tests/codegen-llvm/issues/and-masked-comparison-131162.rs b/tests/codegen-llvm/issues/and-masked-comparison-131162.rs new file mode 100644 index 0000000000000..bdf021092fda4 --- /dev/null +++ b/tests/codegen-llvm/issues/and-masked-comparison-131162.rs @@ -0,0 +1,17 @@ +//@ compile-flags: -Copt-level=3 +//@ min-llvm-version: 20 + +#![crate_type = "lib"] + +// CHECK-LABEL: @issue_131162 +#[no_mangle] +pub fn issue_131162(a1: usize, a2: usize) -> bool { + const MASK: usize = 1; + + // CHECK-NOT: xor + // CHECK-NOT: trunc + // CHECK-NOT: and i1 + // CHECK: icmp + // CHECK-NEXT: ret + (a1 & !MASK) == (a2 & !MASK) && (a1 & MASK) == (a2 & MASK) +} diff --git a/tests/codegen-llvm/issues/assert-for-loop-bounds-check-71997.rs b/tests/codegen-llvm/issues/assert-for-loop-bounds-check-71997.rs new file mode 100644 index 0000000000000..a0c64d607a8f2 --- /dev/null +++ b/tests/codegen-llvm/issues/assert-for-loop-bounds-check-71997.rs @@ -0,0 +1,18 @@ +// Tests that there's no bounds check within for-loop after asserting that +// the range start and end are within bounds. + +//@ compile-flags: -Copt-level=3 + +#![crate_type = "lib"] + +// CHECK-LABEL: @no_bounds_check_after_assert +#[no_mangle] +fn no_bounds_check_after_assert(slice: &[u64], start: usize, end: usize) -> u64 { + // CHECK-NOT: panic_bounds_check + let mut total = 0; + assert!(start < end && start < slice.len() && end <= slice.len()); + for i in start..end { + total += slice[i]; + } + total +} diff --git a/tests/codegen-llvm/issues/elided-division-by-zero-check-74917.rs b/tests/codegen-llvm/issues/elided-division-by-zero-check-74917.rs new file mode 100644 index 0000000000000..9e890e148527a --- /dev/null +++ b/tests/codegen-llvm/issues/elided-division-by-zero-check-74917.rs @@ -0,0 +1,13 @@ +// Tests that there is no check for dividing by zero since the +// denominator, `(x - y)`, will always be greater than 0 since `x > y`. + +//@ compile-flags: -Copt-level=3 + +#![crate_type = "lib"] + +// CHECK-LABEL: @issue_74917 +#[no_mangle] +pub fn issue_74917(x: u16, y: u16) -> u16 { + // CHECK-NOT: panic + if x > y { 100 / (x - y) } else { 100 } +} diff --git a/tests/codegen-llvm/issues/for-loop-inner-assert-91109.rs b/tests/codegen-llvm/issues/for-loop-inner-assert-91109.rs new file mode 100644 index 0000000000000..bffbcd7d069e8 --- /dev/null +++ b/tests/codegen-llvm/issues/for-loop-inner-assert-91109.rs @@ -0,0 +1,18 @@ +// Tests that there's no bounds check for the inner loop after the assert. + +//@ compile-flags: -Copt-level=3 + +#![crate_type = "lib"] + +// CHECK-LABEL: @zero +#[no_mangle] +pub fn zero(d: &mut [Vec]) { + // CHECK-NOT: panic_bounds_check + let n = d.len(); + for i in 0..n { + assert!(d[i].len() == n); + for j in 0..n { + d[i][j] = 0; + } + } +} diff --git a/tests/codegen-llvm/issues/iter-max-no-unwrap-failed-129583.rs b/tests/codegen-llvm/issues/iter-max-no-unwrap-failed-129583.rs new file mode 100644 index 0000000000000..4d3fa4993ef72 --- /dev/null +++ b/tests/codegen-llvm/issues/iter-max-no-unwrap-failed-129583.rs @@ -0,0 +1,31 @@ +// Tests that `unwrap` is optimized out when the slice has a known length. +// The iterator may unroll for values smaller than a certain threshold so we +// use a larger value to prevent unrolling. + +//@ compile-flags: -Copt-level=3 +//@ min-llvm-version: 20 + +#![crate_type = "lib"] + +// CHECK-LABEL: @infallible_max_not_unrolled +#[no_mangle] +pub fn infallible_max_not_unrolled(x: &[u8; 1024]) -> u8 { + // CHECK-NOT: panic + // CHECK-NOT: unwrap_failed + *x.iter().max().unwrap() +} + +// CHECK-LABEL: @infallible_max_unrolled +#[no_mangle] +pub fn infallible_max_unrolled(x: &[u8; 10]) -> u8 { + // CHECK-NOT: panic + // CHECK-NOT: unwrap_failed + *x.iter().max().unwrap() +} + +// CHECK-LABEL: @may_panic_max +#[no_mangle] +pub fn may_panic_max(x: &[u8]) -> u8 { + // CHECK: unwrap_failed + *x.iter().max().unwrap() +} diff --git a/tests/codegen-llvm/issues/matches-logical-or-141497.rs b/tests/codegen-llvm/issues/matches-logical-or-141497.rs new file mode 100644 index 0000000000000..348f62096a5f2 --- /dev/null +++ b/tests/codegen-llvm/issues/matches-logical-or-141497.rs @@ -0,0 +1,25 @@ +// Tests that `matches!` optimizes the same as +// `f == FrameType::Inter || f == FrameType::Switch`. + +//@ compile-flags: -Copt-level=3 +//@ min-llvm-version: 21 + +#![crate_type = "lib"] + +#[derive(Clone, Copy, PartialEq, Eq)] +pub enum FrameType { + Key = 0, + Inter = 1, + Intra = 2, + Switch = 3, +} + +// CHECK-LABEL: @is_inter_or_switch +#[no_mangle] +pub fn is_inter_or_switch(f: FrameType) -> bool { + // CHECK-NEXT: start: + // CHECK-NEXT: and i8 + // CHECK-NEXT: icmp + // CHECK-NEXT: ret + matches!(f, FrameType::Inter | FrameType::Switch) +} diff --git a/tests/codegen-llvm/issues/no-bounds-check-after-assert-110971.rs b/tests/codegen-llvm/issues/no-bounds-check-after-assert-110971.rs new file mode 100644 index 0000000000000..aa4002f176da5 --- /dev/null +++ b/tests/codegen-llvm/issues/no-bounds-check-after-assert-110971.rs @@ -0,0 +1,14 @@ +// Tests that the slice access for `j` doesn't have a bounds check panic after +// being asserted as less than half of the slice length. + +//@ compile-flags: -Copt-level=3 + +#![crate_type = "lib"] + +// CHECK-LABEL: @check_only_assert_panic +#[no_mangle] +pub fn check_only_assert_panic(arr: &[u32], j: usize) -> u32 { + // CHECK-NOT: panic_bounds_check + assert!(j < arr.len() / 2); + arr[j] +} diff --git a/tests/codegen-llvm/issues/no-panic-for-pop-after-assert-71257.rs b/tests/codegen-llvm/issues/no-panic-for-pop-after-assert-71257.rs new file mode 100644 index 0000000000000..68877c28d6cee --- /dev/null +++ b/tests/codegen-llvm/issues/no-panic-for-pop-after-assert-71257.rs @@ -0,0 +1,19 @@ +// Tests that the `unwrap` branch is optimized out from the `pop` since the +// length has already been validated. + +//@ compile-flags: -Copt-level=3 + +#![crate_type = "lib"] + +pub enum Foo { + First(usize), + Second(usize), +} + +// CHECK-LABEL: @check_only_one_panic +#[no_mangle] +pub fn check_only_one_panic(v: &mut Vec) -> Foo { + // CHECK-COUNT-1: call{{.+}}panic + assert!(v.len() == 1); + v.pop().unwrap() +} diff --git a/tests/codegen-llvm/issues/num-is-digit-to-digit-59352.rs b/tests/codegen-llvm/issues/num-is-digit-to-digit-59352.rs new file mode 100644 index 0000000000000..1d23eb2cdf9e4 --- /dev/null +++ b/tests/codegen-llvm/issues/num-is-digit-to-digit-59352.rs @@ -0,0 +1,14 @@ +// Tests that there's no panic on unwrapping `to_digit` call after checking +// with `is_digit`. + +//@ compile-flags: -Copt-level=3 + +#![crate_type = "lib"] + +// CHECK-LABEL: @num_to_digit_slow +#[no_mangle] +pub fn num_to_digit_slow(num: char) -> u32 { + // CHECK-NOT: br + // CHECK-NOT: panic + if num.is_digit(8) { num.to_digit(8).unwrap() } else { 0 } +} diff --git a/tests/codegen-llvm/issues/slice-index-bounds-check-80075.rs b/tests/codegen-llvm/issues/slice-index-bounds-check-80075.rs new file mode 100644 index 0000000000000..ecb5eb787c70e --- /dev/null +++ b/tests/codegen-llvm/issues/slice-index-bounds-check-80075.rs @@ -0,0 +1,13 @@ +// Tests that no bounds check panic is generated for `j` since +// `j <= i < data.len()`. + +//@ compile-flags: -Copt-level=3 + +#![crate_type = "lib"] + +// CHECK-LABEL: @issue_80075 +#[no_mangle] +pub fn issue_80075(data: &[u8], i: usize, j: usize) -> u8 { + // CHECK-NOT: panic_bounds_check + if i < data.len() && j <= i { data[j] } else { 0 } +}