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