<html>
<head>
<base href="https://bugs.llvm.org/">
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW - Iteration over arrays until end pointer (C++ vector iterator, Rust iterators) doesn't preserve number of iterations for the optimizer"
href="https://bugs.llvm.org/show_bug.cgi?id=48965">48965</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>Iteration over arrays until end pointer (C++ vector iterator, Rust iterators) doesn't preserve number of iterations for the optimizer
</td>
</tr>
<tr>
<th>Product</th>
<td>new-bugs
</td>
</tr>
<tr>
<th>Version</th>
<td>11.0
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>Linux
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>enhancement
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>new bugs
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>slomo@coaxion.net
</td>
</tr>
<tr>
<th>CC</th>
<td>htmldeveloper@gmail.com, llvm-bugs@lists.llvm.org
</td>
</tr></table>
<p>
<div>
<pre>This was originally reported here:
<a href="https://github.com/rust-lang/rust/issues/75935">https://github.com/rust-lang/rust/issues/75935</a>
In the end it boils down to the following minimal testcases in C/C++/Rust.
Godbolt links: <a href="https://godbolt.org/z/s6reoz">https://godbolt.org/z/s6reoz</a> and
<a href="https://rust.godbolt.org/z/a7f6rj">https://rust.godbolt.org/z/a7f6rj</a>
All of them have in common that the iteration happens not by having a counter
but instead iterating until the end pointer. When additionally counting the
iterations, the maximum (or here: exact) number of iterations does not seem to
be available during optimizations. As such the two assertions are not detected
as dead code and not optimized away. In this specific minimal case, the whole
function should've been possible to optimize away.
The testcase is extremely contrived but it also happens in real code (the Rust
issue contains something closer to my original code) and causes missed
optimization opportunities, and is especially problematic with Rust because of
automatic bounds checks for array indexing that can be impossible to optimize
away because of this and then preventing other optimizations (like
auto-vectorization or loop unrolling) to kick in.
# C
void foo(const uint32_t *y, size_t y_len) {
const uint32_t *y_end = y + y_len;
size_t c = 0;
for (const uint32_t *y_iter = y; y_iter != y_end; y_iter++, c++) {
assert(c < y_len);
}
assert(c == y_len);
}
# C++
void foo(const std::vector<uint32_t>& y) {
size_t c = 0;
for (auto y_iter = y.cbegin(); y_iter != y.cend(); y_iter++, c++) {
assert(c < y.size());
}
assert(c == y.size());
}
# Rust
pub fn foo(y: &[u32]) {
let mut x = 0;
for (c, _y) in y.iter().enumerate() {
assert!(c < y.len());
x = c;
}
assert!(x == y.len());
}</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>