https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121630
Bug ID: 121630 Summary: incorrect/inconsistent "declare variant" handling of "simd" construct selector causes wrong code Product: gcc Version: 16.0 Status: UNCONFIRMED Keywords: openmp Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: sandra at gcc dot gnu.org Target Milestone: --- There is an existing test case c-c++-common/gomp/declare-variant-5.c that is doing typedef float __v4sf __attribute__((vector_size (16))); typedef int __v4si __attribute__((vector_size (16))); typedef float __v8sf __attribute__((vector_size (32))); typedef int __v8si __attribute__((vector_size (32))); __v4si f1 (__v4sf, __v4sf, float *); __v8si f2 (__v8sf, __v8sf, float *); __v4si f3 (__v4si, int, __v4si); #pragma omp declare variant (f1) match (construct={parallel,for,simd(simdlen(4),notinbranch,uniform(z),aligned(z:4 * sizeof (*z)))}) #pragma omp declare variant (f2) match (construct={for,simd(uniform(z),simdlen(8),notinbranch)}) int f4 (float x, float y, float *z); #pragma omp declare variant (f3) match (construct={simd(simdlen(4),inbranch,linear(y:1))}) int f5 (int x, int y); Likewise, there's a similar testcase for Fortran. The expectation here seems to be that replacement of the call to the base function with the variant will also vectorize it as if it were associated with a "declare simd" directive. But in fact that is not happening and AFAICT it has never worked that way, going back at least as far as GCC 10. I also cannot find any mention of this being the expected behavior in the OpenMP specification. Vectorizing calls for SIMD clones happens at a much later stage of compilation than where declare variant substitution normally happens in the gimplifier, so the two things have no coupling in GCC's implementation either. The existing C/C++ and Fortran test cases only appear to work because all three front ends presently skip error checking of the "declare variant" variant function for consistency with the base function when the "simd" construct selector is used in the "match" clause for that variant, and the test cases don't check the generated code, only that they compile without error. I think the expectation of these test cases is incorrect and the type of the user-supplied variant must always match the base function (modulo interop adjustments). Such a variant might be a candidate for a "declare simd" directive matching the clauses on the "simd" construct selector, and GCC might even attempt to add one implicitly, but I don't see anything in the OpenMP spec requiring that, either. Whether or not we decide to pursue that, we should fix the front ends not to skip the error checks and fix the test cases to check that the invalid variant functions are diagnosed (and use correct declarations for related testcases that are checking for other aspects of handling the "simd" construct selector).