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);