https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128587
Richard Biener <rguenth at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Ever confirmed|0 |1
Priority|P3 |P2
Last reconfirmed| |2026-11-10
Blocks| |24639
Status|UNCONFIRMED |NEW
Keywords| |missed-optimization
CC| |rguenth at gcc dot gnu.org
--- Comment #9 from Richard Biener <rguenth at gcc dot gnu.org> ---
We vectorize the tail loop in main () and yes, we fail to record an upper bound
for the number of iterations based on the access to target[] but that's
"obfuscated" a bit as the loop looks like the following:
<bb 19> [local count: 659862668]:
# PT = nonlocal escaped null
_43 = MEM[(struct layer_t *)l_23 + 56B].output;
# RANGE [frange] float [1.0e+0 (0x0.8p+1), 4.294967296e+9 (0x0.8p+33)]
_126 = (float) _57;
<bb 20> [local count: 5998751563]:
# RANGE [irange] unsigned int [0, 4294967294]
# i_37 = PHI <i_60(24), 0(19)>
# etotal_147 = PHI <etotal_59(24), 0.0(19)>
# RANGE [irange] long unsigned int [0, 4294967294] MASK 0xffffffff VALUE 0x0
_45 = (long unsigned int) i_37;
# RANGE [irange] long unsigned int [0, 0][4, 17179869176] MASK 0x3fffffffc
VALUE 0x0
_46 = _45 * 4;
# PT = nonlocal escaped null
_47 = _43 + _46;
_48 = *_47;
# PT = { D.5503 }
# ALIGN = 4, MISALIGN = 0
_49 = &target + _46; <===
_50 = *_49; <===
# PT = nonlocal escaped null
_52 = pretmp_231 + _46;
err_124 = _50 - _48;
# RANGE [frange] float [-0.0 (-0x0.0p+0), +Inf] +-NAN
_125 = err_124 * err_124;
# RANGE [frange] float [-0.0 (-0x0.0p+0), +Inf] +-NAN
_127 = _125 / _126;
*_52 = _127;
etotal_59 = _127 + etotal_147;
# RANGE [irange] unsigned int [1, +INF]
i_60 = i_37 + 1;
if (_57 > i_60)
goto <bb 24>; [89.00%]
else
goto <bb 44>; [11.00%]
<bb 24> [local count: 5338888895]:
goto <bb 20>; [100.00%]
<bb 44> [local count: 659862668]:
# etotal_238 = PHI <etotal_59(20)>
niter analysis only has infer_loop_bounds_from_pointer_arith for this
here, arriving at
{&target, +, 4}<nw>_1
but then infer_loop_bounds_from_pointer_arith does not consider a
pointed-to object size. It could be improved to handle this similar
to the infer_loop_bounds_from_array handling [at the expense of
exposing more UB ...]
A smaller testcase for that missed optimization is the following, for which
we also warn with -mavx2 (we diagnose for the vector epilog only):
unsigned foo(int n)
{
unsigned target[2] = { 2, 3 };
unsigned sum = 0;
for (int i = 0; i < n; ++i)
{
unsigned *t = target;
sum += *(t + i);
}
return sum;
}
t.c:5:21: optimized: loop vectorized using 32 byte vectors and unroll factor 8
t.c:5:21: optimized: epilogue loop vectorized using 16 byte vectors and unroll
factor 4
t.c:3:12: optimized: basic block part vectorized using 8 byte vectors
t.c: In function ‘foo’:
t.c:8:14: warning: ‘target’ may be used uninitialized [-Wmaybe-uninitialized]
8 | sum += *(t + i);
| ^~~~~~~~
t.c:3:12: note: ‘target’ declared here
3 | unsigned target[2] = { 2, 3 };
| ^~~~~~
Referenced Bugs:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=24639
[Bug 24639] [meta-bug] bug to track all Wuninitialized issues