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

Reply via email to