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

            Bug ID: 111796
           Summary: OMP SIMD call vectorization fails for arguments
                    subject to integer promotion rules
           Product: gcc
           Version: 14.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: rguenth at gcc dot gnu.org
  Target Milestone: ---

For example

int x[1024];

#pragma omp declare simd simdlen(8)
__attribute__((noinline)) int
foo (int a, short b)
{
  return a + b;
}

void __attribute__((noipa))
bar (void)
{
#pragma omp simd
  for (int i = 0; i < 1024; i++)
    x[i] = foo (x[i], x[i]);
}

fails to vetorize because for the scalar code we see

  _4 = x[i_12];
  _5 = (short int) _4;
  _6 = (int) _5;
  _7 = foo (_4, _6);

thus the second argument to 'foo' is promoted to 'int', but the SIMD clone
at least on x86_64 expects vector(8) short int simd.6 as argument.

vectorizable_simd_clone_call has the following, which will result in
rejecting the call.

        for (i = 0; i < nargs; i++)
          {
            switch (n->simdclone->args[i].arg_type)
              {
              case SIMD_CLONE_ARG_TYPE_VECTOR:
                if (!useless_type_conversion_p
                        (n->simdclone->args[i].orig_type,
                         TREE_TYPE (gimple_call_arg (stmt, i + arg_offset))))
                  i = -1;

This argument promotion is exposed by the frontend, controlled by a target
hook.  IIRC it is intended to allow more optimization, so maybe it can be
disabled for calls to OMP SIMD functions.

Alternatively the vectorizer needs to deal with this somehow, for example
in vectorizable_simd_clone_call by allowing this and instead peeking 
through the conversion.  Possibly also done via pattern recognizing the call
itself.

Reply via email to