blob: 3430d6f5aa4f3ae3ed8bdfda80ef99d5517f15c6 [file] [log] [blame]
/* { dg-require-effective-target vect_simd_clones } */
/* { dg-additional-options "-fopenmp-simd --param vect-epilogues-nomask=0" } */
/* { dg-additional-options "-mavx" { target avx_runtime } } */
/* Test that simd inbranch clones work correctly. */
#ifndef TYPE
#define TYPE int
#endif
/* A simple function that will be cloned. */
#pragma omp declare simd inbranch uniform(b)
TYPE __attribute__((noinline))
foo (TYPE a, TYPE b)
{
return a + b;
}
/* Check that "inbranch" clones are called correctly. */
void __attribute__((noipa))
masked (TYPE * __restrict a, TYPE * __restrict b, int size)
{
#pragma omp simd
for (int i = 0; i < size; i++)
b[i] = a[i]<1 ? foo(a[i], 1) : a[i];
}
/* Check that "inbranch" works when there might be unrolling. */
void __attribute__((noipa))
masked_fixed (TYPE * __restrict a, TYPE * __restrict b)
{
#pragma omp simd
for (int i = 0; i < 128; i++)
b[i] = a[i]<1 ? foo(a[i], 1) : a[i];
}
/* Validate the outputs. */
void
check_masked (TYPE *b, int size)
{
for (int i = 0; i < size; i++)
if (((TYPE)i < 1 && b[i] != (TYPE)(i + 1))
|| ((TYPE)i >= 1 && b[i] != (TYPE)i))
{
__builtin_printf ("error at %d\n", i);
__builtin_exit (1);
}
}
int
main ()
{
TYPE a[1024];
TYPE b[1024];
for (int i = 0; i < 1024; i++)
a[i] = i;
masked_fixed (a, b);
check_masked (b, 128);
/* Test various sizes to cover machines with different vectorization
factors. */
for (int size = 8; size <= 1024; size *= 2)
{
masked (a, b, size);
check_masked (b, size);
}
/* Test sizes that might exercise the partial vector code-path. */
for (int size = 8; size <= 1024; size *= 2)
{
masked (a, b, size-4);
check_masked (b, size-4);
}
return 0;
}
/* Ensure the the in-branch simd clones are used on targets that support them. */
/* { dg-final { scan-tree-dump-times {[\n\r] [^\n]* = foo\.simdclone} 2 "vect" } } */
/* The LTO test produces two dump files and we scan the wrong one. */
/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */