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.