Skip to content

Commit

Permalink
Add an overflow check in the Iter::next() impl for Range<_>
Browse files Browse the repository at this point in the history
This helps with vectorization in some cases, such as (0..u16::MAX).collect::<Vec<u16>>(),
 as LLVM is able to change the loop condition to use equality instead of less than
  • Loading branch information
oyvindln committed Aug 1, 2017
1 parent c240751 commit 4bb9a8b
Showing 1 changed file with 10 additions and 3 deletions.
13 changes: 10 additions & 3 deletions src/libcore/iter/range.rs
Expand Up @@ -214,9 +214,16 @@ impl<A: Step> Iterator for ops::Range<A> {
#[inline]
fn next(&mut self) -> Option<A> {
if self.start < self.end {
let mut n = self.start.add_one();
mem::swap(&mut n, &mut self.start);
Some(n)
// We check for overflow here, even though it can't actually
// happen. Adding this check does however help llvm vectorize loops
// for some ranges that don't get vectorized otherwise,
// and this won't actually result in an extra check in an optimized build.
if let Some(mut n) = self.start.add_usize(1) {
mem::swap(&mut n, &mut self.start);
Some(n)
} else {
None
}
} else {
None
}
Expand Down

0 comments on commit 4bb9a8b

Please sign in to comment.