On Mon, 24 Nov 2025, Jakub Jelinek wrote:

> On Mon, Nov 24, 2025 at 02:28:40PM +0100, Richard Biener wrote:
> > The following recors both a possibly notinbranch and an inbranch
> > SIMD clone during analysis so that we can properly handle the
> > late decision on loop masking.  I'm not sure to which extent things
> > like SIMD_CLONE_ARG_TYPE_LINEAR_* and friends are uniform amongst
> > all SIMD clones for a function.  If there can be actual differences
> > that would result in different recordings in simd_clone_info[]
> > we'd have to duplicate those as well.
> 
> If it is a result from the same declare simd directive, then
> it is necessarily the same, like for
>   #pragma omp declare simd linear(a:4) uniform(b) simdlen(8)
>   int foo (int a, int b, int c);
> for both inbranch and notinbranch clones linear & uniform will be
> the same.
> But it can be different, either from multiple declare simd on the
> same decl or from multiple declarations.
>   #pragma omp declare simd linear(a:4) simdlen(8) inbranch
>   #pragma omp declare simd linear(a:8) uniform(b) simdlen(8) notinbranch
>   int bar (int a, int b, int c);
> or
>   #pragma omp declare simd linear(a:4) simdlen(8) inbranch
>   int baz (int a, int b, int c);
>   #pragma omp declare simd linear(a:8) uniform(b) simdlen(8) notinbranch
>   int baz (int a, int b, int c);
> For bar and baz, the notinbranch clones have middle argument uniform
> and first argument linear with step 8, while the inbranch clones have
> the middle argument normally vectorized and first argument linear with step
> 4 instead (but could be any other clause combination).
> So I wonder if you shouldn't use both clone and clone_inbranch solely
> if the analysis phase finds that there are clones with the same badness
> when ignoring inbranch vs. notinbranch.

The linear() clauses are basically constraints on the caller side?
Likewise uniform()?  I suppose a linear() or uniform() clause arg
can be handled as normal vector in the SIMD function, but not all
normal vector arguments can be handled with linar() or uniform)
SIMD function?

Looking I also see that while we attempt to support SLP for SIMD calls
we do not handle uniform()/linear() correctly there.  I'll fix that.

I'm not sure same "badness" is a good measure for compatibility, but
yes, I'd like to pick a pair of clones that only differ in
inbranch vs. notinbranch, if only for simplicity at this point.

The easiest way to achieve this would be to post-process after the
current decision, discarding the inbranch clone if its args do
not match up (or even contain any of the linear() clauses which
I do not really understand).

So like the following, linear_step is verified to be in-line with
the actual arguments already, so it should be enough to verify
arg_type?

Richard.

@@ -4372,6 +4375,17 @@ vectorizable_simd_clone_call (vec_info *vinfo, 
stmt_vec_info stmt_info,
   if (bestn == NULL)
     return false;
 
+  /* Make sure the shape of the inbranch SIMD clone matches that of the
+     possibly notinbranch one.  */
+  if (bestn_inbranch && bestn_inbranch != bestn)
+    for (unsigned i = 0; i < nargs; ++i)
+      if (bestn->simdclone->args[i].arg_type
+         != bestn_inbranch->simdclone->args[i].arg_type)
+       {
+         bestn_inbranch = NULL;
+         break;
+       }
+
   fndecl = bestn->decl;
   nunits = bestn->simdclone->simdlen;
   int ncopies = vector_unroll_factor (vf * group_size, nunits);

Reply via email to