> On 16 Jun 2026, at 11:02, Richard Biener <[email protected]> wrote:
> 
> On Mon, 15 Jun 2026, [email protected] wrote:
> 
>> From: Kyrylo Tkachov <[email protected]>
>> 
>> vect_slp_analyze_data_ref_dependence conservatively reports a dependence
>> whenever the classical (affine) data-dependence test returns chrec_dont_know,
>> e.g. when one of the accesses has a non-affine or runtime array subscript.
>> In the BB SLP region check this is overly pessimistic: the unanalyzable
>> subscript says nothing about whether the two references can actually alias,
>> and the alias oracle can frequently still prove they cannot (distinct 
>> restrict
>> parameters, distinct non-escaping objects, TBAA-incompatible types, and so 
>> on).
>> When that happens a perfectly good SLP group can be torn down.
>> 
>> Consult the alias oracle (refs_may_alias_p) before assuming a dependence on
>> chrec_dont_know: if the two references cannot alias they are independent
>> regardless of the unanalyzable subscript, and BB SLP may proceed.
>> 
>> On the new gcc.dg/vect/bb-slp-dep-oracle.c the 8-lane reciprocal group is 
>> torn
>> down and emitted scalar without the patch
>> 
>> fmov d23, 1.0e+0
>> fdiv d8, d23, d8
>> fdiv d9, d23, d9
>> fdiv d10, d23, d10
>> fdiv d11, d23, d11
>> fdiv d12, d23, d12
>> fdiv d13, d23, d13
>> fdiv d14, d23, d14
>> fdiv d15, d23, d15
>> 
>> and vectorizes with it:
>> 
>> fmov v27.2d, 1.0e+0
>> fdiv v28.2d, v27.2d, v28.2d
>> fdiv v29.2d, v27.2d, v29.2d
>> fdiv v30.2d, v27.2d, v30.2d
>> fdiv v31.2d, v27.2d, v31.2d
>> 
>> Bootstrapped and tested on aarch64-none-linux-gnu.
>> Ok for trunk?
> 
> Hmm, but we already do
> 
>          /* If we couldn't record a (single) data reference for this
>             stmt we have to resort to the alias oracle.  */
>          stmt_vec_info stmt_info = vinfo->lookup_stmt (stmt);
>          data_reference *dr_b = STMT_VINFO_DATA_REF (stmt_info);
>          if (!dr_b)
>            {
>              /* We are moving a store - this means
>                 we cannot use TBAA for disambiguation.  */
>              if (!ref_initialized_p)
>                ao_ref_init (&ref, DR_REF (dr_a));
>              if (stmt_may_clobber_ref_p_1 (stmt, &ref, false)
>                  || ref_maybe_used_by_stmt_p (stmt, &ref, false))
>                return false;
>              continue;
> 
> on one path, so maybe refactor this so this is also done when 
> chrec_dont_know
> (have vect_slp_analyze_data_ref_dependence return
> chrec_known instead of false and then DDR_ARE_DEPENDENT so
> we can distinguish the three cases)?
> 
> Also because a generic refs_may_alias_p is too strong for
> the store vs. store case, so I'd like to see the fallback
> duplicated to all three places.

Thanks, I’ve sent an updated version separately.
Kyrill

> 
>> Thanks,
>> Kyrill
>> 
>> Signed-off-by: Kyrylo Tkachov <[email protected]>
>> 
>> gcc/ChangeLog:
>> 
>> * tree-vect-data-refs.cc (vect_slp_analyze_data_ref_dependence): On an
>> unknown (chrec_dont_know) dependence, consult the alias oracle on the
>> references and treat them as independent when they provably cannot
>> alias.
>> 
>> gcc/testsuite/ChangeLog:
>> 
>> * gcc.dg/vect/bb-slp-dep-oracle.c: New test.
>> ---
>> gcc/testsuite/gcc.dg/vect/bb-slp-dep-oracle.c | 40 +++++++++++++++++++
>> gcc/tree-vect-data-refs.cc                    |  8 ++++
>> 2 files changed, 48 insertions(+)
>> create mode 100644 gcc/testsuite/gcc.dg/vect/bb-slp-dep-oracle.c
>> 
>> diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-dep-oracle.c 
>> b/gcc/testsuite/gcc.dg/vect/bb-slp-dep-oracle.c
>> new file mode 100644
>> index 00000000000..b2551ef644c
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-dep-oracle.c
>> @@ -0,0 +1,40 @@
>> +/* BB SLP must not abandon a vectorizable group when the classical (affine)
>> +   data-dependence test cannot analyze a runtime array subscript but the 
>> alias
>> +   oracle can still prove the two references do not alias.
>> +
>> +   The per-lane reciprocals are discovered as an SLP group, then the group 
>> is
>> +   torn down by vect_slp_analyze_data_ref_dependence reporting "can't 
>> determine
>> +   dependence" between the restrict output store and a runtime-indexed input
>> +   load, even though the distinct restrict objects provably do not alias.  
>> */
>> +
>> +/* { dg-do compile } */
>> +/* { dg-require-effective-target vect_double } */
>> +/* { dg-additional-options "-O3 -ffast-math -fno-trapping-math" } */
>> +
>> +struct VA { double data[8]; };
>> +struct Tensor { struct VA comp[4]; };
>> +
>> +/* Opaque: the returned index is a runtime value the affine subscript test
>> +   cannot analyze.  */
>> +unsigned __attribute__((noipa)) pick (unsigned k) { return k & 3; }
>> +
>> +void f (const struct Tensor *in, double *__restrict out,
>> +        unsigned nq, unsigned base)
>> +{
>> +  for (unsigned q = 0; q < nq; q++)
>> +    {
>> +      const struct VA *rho = &in[q].comp[0];     /* divisor: contiguous 
>> .data[i] */
>> +      double inv[8];
>> +      for (unsigned i = 0; i < 8; i++)
>> +        inv[i] = 1.0 / rho->data[i];             /* reciprocal group, 
>> reused below */
>> +      for (unsigned d = 0; d < 3; d++)
>> +        {
>> +          const struct VA *mom = &in[q].comp[pick (base + d)];  /* 
>> runtime-indexed numerator */
>> +          for (unsigned i = 0; i < 8; i++)
>> +            out[(q * 3 + d) * 8 + i] = mom->data[i] * inv[i];
>> +        }
>> +    }
>> +}
>> +
>> +/* The reciprocal group must survive the dependence check and vectorize.  */
>> +/* { dg-final { scan-tree-dump "basic block part vectorized" "slp1" } } */
>> diff --git a/gcc/tree-vect-data-refs.cc b/gcc/tree-vect-data-refs.cc
>> index 0e57e1068d6..07d0d860d44 100644
>> --- a/gcc/tree-vect-data-refs.cc
>> +++ b/gcc/tree-vect-data-refs.cc
>> @@ -1011,6 +1011,14 @@ vect_slp_analyze_data_ref_dependence (vec_info *vinfo,
>>   /* Unknown data dependence.  */
>>   if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
>>     {
>> +      /* The classical (affine) dependence test gave up, e.g. a non-affine
>> +  or runtime array subscript.  Before conservatively assuming a
>> +  dependence (which prevents SLP), consult the alias oracle on the
>> +  actual references: if they provably cannot alias (e.g. based on
>> +  distinct restrict / non-escaping objects) they are independent
>> +  regardless of the unanalyzable subscript.  */
>> +      if (!refs_may_alias_p (DR_REF (dra), DR_REF (drb)))
>> + return false;
>>       if  (dump_enabled_p ())
>> dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
>>  "can't determine dependence between %T and %T\n",
>> 
> 
> -- 
> Richard Biener <[email protected]>
> SUSE Software Solutions Germany GmbH,
> Frankenstrasse 146, 90461 Nuernberg, Germany;
> GF: Jochen Jaser, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)


Reply via email to