Hi! We can't create a vector type with aggregate elements. In the past we used to reject BLKmode aggregates, but accepted (and ICEd on) [QHSD]Imode aggregates. On the other side, as the FIXME says, we should accept any argument type if it is uniform (linear should be only integers or pointers or references and we do already accept those). From what I can see, aarch64 will not already let aggregates through (but, it could be changed to ignore uniform argument types).
Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk. 2019-02-02 Jakub Jelinek <ja...@redhat.com> PR middle-end/87887 * config/i386/i386.c (ix86_simd_clone_compute_vecsize_and_simdlen): Punt with warning on aggregate return or argument types. Ignore type/mode checking for uniform arguments. * gcc.dg/gomp/pr87887-1.c: New test. * gcc.dg/gomp/pr87887-2.c: New test. --- gcc/config/i386/i386.c.jj 2019-01-30 08:50:26.824223494 +0100 +++ gcc/config/i386/i386.c 2019-02-01 23:14:10.450518093 +0100 @@ -50433,7 +50433,9 @@ ix86_simd_clone_compute_vecsize_and_simd case E_DFmode: /* case E_SCmode: */ /* case E_DCmode: */ - break; + if (!AGGREGATE_TYPE_P (ret_type)) + break; + /* FALLTHRU */ default: warning_at (DECL_SOURCE_LOCATION (node->decl), 0, "unsupported return type %qT for simd", ret_type); @@ -50444,7 +50446,6 @@ ix86_simd_clone_compute_vecsize_and_simd int i; for (t = DECL_ARGUMENTS (node->decl), i = 0; t; t = DECL_CHAIN (t), i++) - /* FIXME: Shouldn't we allow such arguments if they are uniform? */ switch (TYPE_MODE (TREE_TYPE (t))) { case E_QImode: @@ -50455,8 +50456,12 @@ ix86_simd_clone_compute_vecsize_and_simd case E_DFmode: /* case E_SCmode: */ /* case E_DCmode: */ - break; + if (!AGGREGATE_TYPE_P (TREE_TYPE (t))) + break; + /* FALLTHRU */ default: + if (clonei->args[i].arg_type == SIMD_CLONE_ARG_TYPE_UNIFORM) + break; warning_at (DECL_SOURCE_LOCATION (node->decl), 0, "unsupported argument type %qT for simd", TREE_TYPE (t)); return 0; --- gcc/testsuite/gcc.dg/gomp/pr87887-1.c.jj 2019-02-01 20:55:11.383755787 +0100 +++ gcc/testsuite/gcc.dg/gomp/pr87887-1.c 2019-02-01 23:15:07.376587238 +0100 @@ -0,0 +1,26 @@ +/* PR middle-end/87887 */ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_simd_clones } */ +/* { dg-additional-options "-w" } */ + +struct S { int n; }; +#pragma omp declare simd +struct S +foo (int x) +{ + return (struct S) { x }; +} + +#pragma omp declare simd +int +bar (struct S x) +{ + return x.n; +} + +#pragma omp declare simd uniform (x) +int +baz (int w, struct S x, int y) +{ + return w + x.n + y; +} --- gcc/testsuite/gcc.dg/gomp/pr87887-2.c.jj 2019-02-01 20:55:18.618636600 +0100 +++ gcc/testsuite/gcc.dg/gomp/pr87887-2.c 2019-02-01 23:15:14.118476995 +0100 @@ -0,0 +1,25 @@ +/* PR middle-end/87887 */ +/* { dg-do compile { target i?86-*-* x86_64-*-* } } */ +/* { dg-require-effective-target vect_simd_clones } */ + +struct S { int n; }; +#pragma omp declare simd +struct S +foo (int x) /* { dg-warning "unsupported return type 'struct S' for simd" } */ +{ + return (struct S) { x }; +} + +#pragma omp declare simd +int +bar (struct S x) /* { dg-warning "unsupported argument type 'struct S' for simd" } */ +{ + return x.n; +} + +#pragma omp declare simd uniform (x) +int +baz (int w, struct S x, int y) +{ + return w + x.n + y; +} Jakub