| // This test ensures that Range iterators are optimizable, to | |
| // the point that some loops can be entirely optimized out. | |
| //@ compile-flags: -Copt-level=3 | |
| #![crate_type = "lib"] | |
| use std::num::NonZeroU8; | |
| use std::ops::{Range, RangeInclusive}; | |
| // CHECK-LABEL: @rangeinclusive_noop_loop = unnamed_addr alias void (), ptr @range_noop_loop | |
| // CHECK-LABEL: @rangeinclusive_nz_noop_loop = unnamed_addr alias void (), ptr @range_noop_loop | |
| // CHECK-LABEL: @range_noop_loop( | |
| #[no_mangle] | |
| pub unsafe fn range_noop_loop() { | |
| // CHECK-NEXT: start: | |
| // CHECK-NEXT: ret void | |
| // This loop should be optimized out entirely. | |
| for _ in 0_u8..100 { | |
| () | |
| } | |
| } | |
| // CHECK-LABEL: @range_count( | |
| #[no_mangle] | |
| pub unsafe fn range_count(s: u8, e: u8) -> usize { | |
| // CHECK-NOT: br {{.*}} | |
| // CHECK: ret i{{8|16|32|64}} | |
| // This loop should be optimized to arithmetic. | |
| let mut count = 0; | |
| for _ in s..e { | |
| count += 1; | |
| } | |
| count | |
| } | |
| // Deduplicated to alias of range_noop_loop, checked above | |
| #[no_mangle] | |
| pub unsafe fn rangeinclusive_noop_loop() { | |
| // This loop should be optimized out entirely. | |
| for _ in 0_u8..=100 { | |
| () | |
| } | |
| } | |
| // CHECK-LABEL: @rangeinclusive_count( | |
| #[no_mangle] | |
| pub unsafe fn rangeinclusive_count(s: u8, e: u8) -> usize { | |
| // CHECK-NOT: br {{.*}} | |
| // CHECK: ret i{{8|16|32|64}} | |
| // This loop should be optimized to arithmetic. | |
| let mut count = 0; | |
| for _ in s..=e { | |
| count += 1; | |
| } | |
| count | |
| } | |
| // Deduplicated to alias of range_noop_loop, checked above | |
| #[no_mangle] | |
| pub unsafe fn rangeinclusive_nz_noop_loop() { | |
| // This loop should be optimized out entirely. | |
| for _ in NonZeroU8::new(1).unwrap()..=NonZeroU8::new(100).unwrap() { | |
| () | |
| } | |
| } | |
| // CHECK-LABEL: @rangeinclusive_nz_count( | |
| #[no_mangle] | |
| pub unsafe fn rangeinclusive_nz_count(s: NonZeroU8, e: NonZeroU8) -> usize { | |
| // CHECK: br {{.*}} | |
| // CHECK: ret i{{8|16|32|64}} | |
| // RangeInclusive<NonZero> cannot optimize the same way | |
| // because Step::forward_overflowing on NonZero cannot | |
| // be allowed to wrap to 0. | |
| let mut count = 0; | |
| for _ in s..=e { | |
| count += 1; | |
| } | |
| count | |
| } |