https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122868

Tamar Christina <tnfchris at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|[16 Regression] Wrong code  |[15/16 Regression]
                   |generated for vector<bool>  |vectorizer pulls loop
                   |operator== since            |invariant loads across
                   |r16-4414-gc078309cda304f    |multiple exits
   Target Milestone|16.0                        |15.4
             Status|NEW                         |ASSIGNED

--- Comment #5 from Tamar Christina <tnfchris at gcc dot gnu.org> ---
> Loop bounds seem to be wrong. The scalar loop does 64 iterations, and we
> vectorize with a VF of 4.
> 
> The initial bounds is codegened as
> 
> ivtmp_127 = PHI <0(6), ivtmp_59(10)>
> 
> and the guard is ivtmp_127 > 16.
> 
> So somehow the initial bounds is wrong. should be 64 << 2.
> 

The initial bounds value is unused so it's fine as is.

This segfault happens because we have a control flow like

 if (a)
   return

 if (*b > *c)
   ...

where *b is invariant and we're not peeling for alignment.
The vectorizer pulls the load of b out into the preheader,
which is not a valid thing to do as *b can trap.

*b is a conditional load so can't be safely lifted as it's
after an early exit needed to make it valid.

So a C testcase for this:

__attribute__ ((noipa))
int f (int a[12], int b[12], int n)
{
    a = __builtin_assume_aligned (a, 16);
    b = __builtin_assume_aligned (b, 16);
    for (int i = 0; i < n; i++)
      {
        if (b[i] == 0)
          return 0;
        if (a[0] > b[i])
          return 1;
      }
    return 2;
}

int main ()
{
   int *a = 0;
   int b[12] = {0};
   return f (a, b, 10);
}

compiled at -O3

Reply via email to