On Fri, Feb 14, 2025 at 3:10 PM Richard Biener <rguent...@suse.de> wrote: > > 502.gcc_r when built with -fprofile-generate exposes a SLP discovery > issue where an IV forced live due to early break is not properly > discovered if its latch def is part of a different IVs SSA cycle. > To mitigate this we have to make sure to create an SLP instance > for the original IV. Ideally we'd handle all vect_induction_def > the same but this is left for next stage1. > > Bootstrap and regtest running on x86_64-unknown-linux-gnu. > > PR tree-optimizatio/118852 > * tree-vect-slp.cc (vect_analyze_slp): For early-break > forced-live IVs make sure we create an appropriate > entry into the SLP graph. > > * gcc.dg/vect/pr118852.c: New testcase. > --- > gcc/testsuite/gcc.dg/vect/pr118852.c | 109 +++++++++++++++++++++++++++ > gcc/tree-vect-slp.cc | 24 +++++- > 2 files changed, 130 insertions(+), 3 deletions(-) > create mode 100644 gcc/testsuite/gcc.dg/vect/pr118852.c > > diff --git a/gcc/testsuite/gcc.dg/vect/pr118852.c > b/gcc/testsuite/gcc.dg/vect/pr118852.c > new file mode 100644 > index 00000000000..71bfb450f7c > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/vect/pr118852.c > @@ -0,0 +1,109 @@ > +/* { dg-add-options vect_early_break } */ > +/* { dg-require-profiling "-fprofile-generate" } */ > +/* { dg-additional-options "-fallow-store-data-races -fprofile-arcs" } */ > +/* { dg-additional-options "-msse4.2 -mprefer-vector-width=128" { target { > x86_64-*-* i?86-*-* } } } */ > + > +#include "tree-vect.h" > + > +typedef unsigned int hashval_t; > +struct htab { > + void ** entries; > + unsigned long size; > +}; > +typedef struct htab *htab_t; > +unsigned long htab_size (htab_t h) > +{ > + return h->size; > +} > +typedef struct > +{ > + htab_t htab; > + void * *slot; > + void * *limit; > +} htab_iterator; > + > +static inline void * > +first_htab_element (htab_iterator *hti, htab_t table) > +{ > + hti->htab = table; > + hti->slot = table->entries; > + hti->limit = hti->slot + htab_size (table); > + do > + { > + void * x = *(hti->slot); > + if (x != ((void *) 0) && x != ((void *) 1)) > + break; > + } while (++(hti->slot) < hti->limit); > + > + if (hti->slot < hti->limit) > + return *(hti->slot); > + return > + ((void *)0) > + ;
"return (void *) 0;" ... > +} > + > +static inline unsigned char > +end_htab_p (const htab_iterator *hti) > +{ > + if (hti->slot >= hti->limit) > + return 1; > + return 0; > +} > + > +static inline void * > +next_htab_element (htab_iterator *hti) > +{ > + while (++(hti->slot) < hti->limit) > + { > + void * x = *(hti->slot); > + if (x != ((void *) 0) && x != ((void *) 1)) > + return x; > + } > + return > + ((void *)0) > + ; ... and also above. Uros.