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

            Bug ID: 127549
           Summary: vect: Decrease reduction precision or type.
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Keywords: missed-optimization
          Severity: enhancement
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: rdapp at gcc dot gnu.org
  Target Milestone: ---
            Target: riscv

This is again an x264 topic :)

Given, the well-known loop

  int i_sum = 0;
  for (int y = 0; y < 16; y++)
    {
      for (int x = 0; x < 16; x++)
        {
          i_sum += __builtin_abs (pix1[x] - pix2[x]);
        }
      pix1 += i_stride_pix1;
      pix2 += i_stride_pix2;
    }
  return i_sum;

As opposed to all? other SAD instructions, RVV's only extends 2x i.e. from
uint8 to uint16 or uint16 to uint32.  This means we need two or three
instructions instead of just one per inner iteration.  So right now we do

 vabdu # abs difference
 vzext.vf4 # uint8 -> uint32
 vadd # accumulate

There are two minor hurdles here:
 - The sad optab is no convert optab so we cannot distinguish between 2x and 4x
extensions.
 - The vect/optab widening support is currently just n -> 2n for this path,
rather than n -> n.

Both are not too difficult to fix and are on my list.  Then, in the target we
could define our regular 2x sad and a synthetic 4x sad that would extend its
output by a separate instruction.

But while that might be independently useful, it would still not get us much
further, hence the question:

Would reducing the reduction/accumulation type depending on range as well as
num_iters be acceptable, basically ?  In the given loop we know that abs <=
255, so 16 * 16 * 255 fits inside uint16.  The number of iterations is known
here so I guess I could hack something together.  On the other hand, this seems
pretty specific and on the brink of being too targeted.  Ideal code for RVV
would be

16 times
load
load 
vwabdau to 16 bit
...
vwredusum to 32 bit

If we had this functionality we would need to guard it on optab availability I
suppose.  So in that case having a synthetic 4x pattern would be
counterproductive.

Reply via email to