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

Reply via email to