On Mon, Nov 21, 2016 at 8:25 PM, Jakub Jelinek <ja...@redhat.com> wrote: > On Wed, Nov 16, 2016 at 09:14:57PM -0600, Bill Schmidt wrote: >> 2016-11-16 Bill Schmidt <wschm...@linux.vnet.ibm.com> >> Richard Biener <rguent...@suse.de> >> >> PR tree-optimization/77848 >> * tree-if-conv.c (tree_if_conversion): Always version loops unless >> the user specified -ftree-loop-if-convert. > > This broke the attached testcase. > >> --- gcc/tree-if-conv.c (revision 242521) >> +++ gcc/tree-if-conv.c (working copy) >> @@ -2803,10 +2803,12 @@ tree_if_conversion (struct loop *loop) >> || loop->dont_vectorize)) >> goto cleanup; >> >> - /* Either version this loop, or if the pattern is right for outer-loop >> - vectorization, version the outer loop. In the latter case we will >> - still if-convert the original inner loop. */ >> - if ((any_pred_load_store || any_complicated_phi) >> + /* Since we have no cost model, always version loops unless the user >> + specified -ftree-loop-if-convert. Either version this loop, or if >> + the pattern is right for outer-loop vectorization, version the >> + outer loop. In the latter case we will still if-convert the >> + original inner loop. */ >> + if (flag_tree_loop_if_convert != 1 >> && !version_loop_for_if_conversion >> (versionable_outer_loop_p (loop_outer (loop)) >> ? loop_outer (loop) : loop)) > > If there are masked loads/stores (and I assume also the complicated phi > stuff, but haven't verified), then it isn't just some kind of optimization > to version the loop based on LOOP_VECTORIZED ifn, it is a requirement > - MASK_LOAD/MASK_STORE aren't supported for scalar code, so they can only > appear in the vectorized version. Fixed by reverting that - if > -ftree-loop-if-convert we'll do what we used to do before, without it > we do what you've added, i.e. version always. > > The rest is just formatting fix, the too large argument that forces > call's ( on the next line and even misindented is IMHO much cleaner > if a temporary is used. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
Ok. Thanks, Richard. > 2016-11-21 Jakub Jelinek <ja...@redhat.com> > > PR tree-optimization/78445 > * tree-if-conv.c (tree_if_conversion): If any_pred_load_store or > any_complicated_phi, version loop even if flag_tree_loop_if_convert is > 1. Formatting fix. > > * gcc.dg/pr78445.c: New test. > > --- gcc/tree-if-conv.c.jj 2016-11-17 18:08:12.000000000 +0100 > +++ gcc/tree-if-conv.c 2016-11-21 17:28:30.807242395 +0100 > @@ -2804,15 +2804,20 @@ tree_if_conversion (struct loop *loop) > goto cleanup; > > /* Since we have no cost model, always version loops unless the user > - specified -ftree-loop-if-convert. Either version this loop, or if > - the pattern is right for outer-loop vectorization, version the > - outer loop. In the latter case we will still if-convert the > - original inner loop. */ > - if (flag_tree_loop_if_convert != 1 > - && !version_loop_for_if_conversion > - (versionable_outer_loop_p (loop_outer (loop)) > - ? loop_outer (loop) : loop)) > - goto cleanup; > + specified -ftree-loop-if-convert or unless versioning is required. > + Either version this loop, or if the pattern is right for outer-loop > + vectorization, version the outer loop. In the latter case we will > + still if-convert the original inner loop. */ > + if (any_pred_load_store > + || any_complicated_phi > + || flag_tree_loop_if_convert != 1) > + { > + struct loop *vloop > + = (versionable_outer_loop_p (loop_outer (loop)) > + ? loop_outer (loop) : loop); > + if (!version_loop_for_if_conversion (vloop)) > + goto cleanup; > + } > > /* Now all statements are if-convertible. Combine all the basic > blocks into one huge basic block doing the if-conversion > --- gcc/testsuite/gcc.dg/pr78445.c.jj 2016-11-21 17:30:58.534400256 +0100 > +++ gcc/testsuite/gcc.dg/pr78445.c 2016-11-21 17:30:41.000000000 +0100 > @@ -0,0 +1,19 @@ > +/* PR tree-optimization/78445 */ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -ftree-loop-if-convert -ftree-vectorize" } */ > +/* { dg-additional-options "-mavx2" { target { i?86-*-* x86_64-*-* } } } */ > + > +int a; > + > +void > +foo (int x, int *y) > +{ > + while (a != 0) > + if (x != 0) > + { > + *y = a; > + x = *y; > + } > + else > + x = a; > +} > > > Jakub