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

--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Avinash Jayakar from comment #4)
> typedef unsigned long long u64;
> 
> u64 mobility(u64 * a, u64 * b) {
> 
>     u64 mobility = 0;
>     mobility += a[0];
>     mobility += a[1];
>     mobility += a[2];
>     mobility += a[3];
> 
>     mobility += b[0];
>     mobility += b[1];
>     mobility += b[2];
>     mobility += b[3];
> 
>     return mobility;
> }
> 
> even with same addition operation, the vectorization does happen, but is
> sub-optimal.
> Only one .REDUC_PLUS operation is seen in tree-slp pass, the other one stays
> in scalar form.
> Ideally something like this should have happened
> .REDUC_PLUS ( vector_a + vector_b)
> 
> but now 
> .REDUC_PLUS (vector_a)
> .. scalar reduction of b.
> .. add the results.

Yes, we currently are not set up to vectorize multiple pieces of the
reduction separately (and we still don't handle the MINUS, also not if
that were uniform).  Both is not difficult, it just requires some extra
bookkeeping.

For the case above, rather than two .REDUC_PLUS I'd do

   vector_a = *a;
   vector_b = *b;
   sum = vector_a + vector_b;
   .REDUC_PLUS (sum);

so handle it similar as to how we'd vectorize a 8 lane reduction.  The
'sum' would be a SLP node with a PLUS operation created by SLP reduction
discovery when it discovers more than one (same size!) reduction part.
Having two separate .REDUC_PLUS requires more surgery - like creating
more than one SLP instance and using separate root stmts which would
be an 'alternate' scalar input for the other SLP reduction instance.

Reply via email to