On Mon, Aug 25, 2025 at 11:58:17AM +0200, Tobias Burnus wrote: > Am 25.08.25 um 08:13 schrieb Jakub Jelinek: > > On Sun, Aug 24, 2025 at 08:16:32PM -0600, Sandra Loosemore wrote: > > > As noted in PR middle-end/121630, GCC seems to think that the "simd" > > > construct selector on "declare variant" implies that the variant > > > function accepts vectorized arguments, although this is not anywhere > > > in the OpenMP specification. > > It does imply that. > > I am not sure that the spec implies this, but it permits it. And there > are hints in the spec that members of the language committee intended > that it will work like ...
The reason it is implementation defined is that the standard can't require a vector ABI exists at all (we have many ABIs which don't define it at all). For declare simd it is easier, the compiler does all the magic of cloning the functions and if there is no vector ABI, it just ignores the directive altogether (sure, diagnoses invalid OpenMP cases and the like). For declare variant it is more problematic, the user needs to know the vector ABI. > > it has always been the intent when declare simd > > has been introduced that simd trait will be treated like that on compilers > > with some kind of vector ABI and the reason why various simd related > > restrictions exist for declare variant: > > * * * > > > Yes, GCC doesn't have it implemented fully, but that doesn't mean it should > > be ripped off, the implementation should be simply finished. > > I have to admit that it is not completely clear to me when/whether > 'declare variant' should just used a used-vectorized function vs. > SIMD-izing a function; and, for the latter, how this is supposed to > get handled when in the 'declare variant' TU is only a declaration > and not the definition. > As the word "implementation defined" appears, I guess we eventually > need to document this. (As the spec requires this for implementation > defined features, contrary to unspecified ones.) > > Looking at the examples, I only found one pattern (4 tests): Sure, the limited test coverage for it is because I didn't get to finishing it (and I even don't remember where exactly I stopped). The C case is easier, there is function overloading, so for the simd trait case it is about just verification whether the function prototype matches the right types of the declare simd variant. Slightly more complicated by the fact that we don't have just one variant as Intel has, but several, so we need to figure out which one of those it is and remember it for vectorization purposes. And need to deal even with functions with the right VECTOR_TYPEs but without necessary ISA enabled where it actually is passed differently, guess we want to error on those if TYPE_MODE of the VECTOR_TYPEs is not the expected mode even if it is a vector type with the right element type and number of elements. The C++ case is harder, we need to do name lookup with the right argument types, so we need to iterate over the declare simd variants for the target for the given simdlen/{,not}inbranch and look up all of them and those that we find and are ok remember, those which aren't find ignore silently unless none are found. Furthermore, a question is what exact element type to choose, e.g. for declare simd we just use integral element type for pointer types and it is ok to require users to do that, but shall it be unsigned or signed element type in that case, and which of say unsigned long or unsigned long long if they have the same mode. E.g. the Intel vector ABI is officially defined in terms of __m128{,d,i}/__m256{,d,i}/__m512{,d,i} I think, so we could be using the signedness matching those types. For Fortran unsure, it has some kind of overloading with interfaces, though unsure if we support generic vectors in the FE at all. All even more complicated by offloading but guess we already have big problems with mixing declare simd and calls from target regions. Jakub