On Tue, 4 Feb 2014, Jakub Jelinek wrote: > Hi! > > If a load or store is in EH tables, but doesn't have EH edges out of it, > e.g. for must-not-throw regions, we weren't cleaning it up and adding > MASK_{LOAD,STORE} into EH region instead. > Similarly, the vectorizer needs to add the vectorized stmts to the same > EH region as the corresponding {,masked} load/store (second hunk). > The rest is just making the compiler more robust and not crash if DCE etc. > decides to remove the lhs of MASK_LOAD. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > > P.S.: the patch doesn't fix the old issue that -fnon-call-exceptions > loads are never removed from the vectorized loops, stores aren't actually > removed when transforming the stmt, but later on and handling scalar loads > similarly (turning them into say assignments of zero) didn't look trivial. > > 2014-02-04 Jakub Jelinek <ja...@redhat.com> > > PR tree-optimization/60023 > * tree-if-conv.c (predicate_mem_writes): Pass true instead of > false to gsi_replace. > * tree-vect-stmts.c (vect_finish_stmt_generation): If stmt > has been in some EH region and vec_stmt could throw, add > vec_stmt into the same EH region. > * tree-data-ref.c (get_references_in_stmt): If IFN_MASK_LOAD > has no lhs, ignore it. > * internal-fn.c (expand_MASK_LOAD): Likewise. > > * g++.dg/vect/pr60023.cc: New test. > > --- gcc/tree-if-conv.c.jj 2014-01-03 11:40:57.000000000 +0100 > +++ gcc/tree-if-conv.c 2014-02-03 16:01:40.250716523 +0100 > @@ -1723,7 +1723,7 @@ predicate_mem_writes (loop_p loop) > new_stmt > = gimple_build_call_internal (IFN_MASK_STORE, 4, addr, ptr, > mask, rhs); > - gsi_replace (&gsi, new_stmt, false); > + gsi_replace (&gsi, new_stmt, true); > } > else if (gimple_vdef (stmt)) > { > --- gcc/tree-vect-stmts.c.jj 2014-01-16 20:54:59.000000000 +0100 > +++ gcc/tree-vect-stmts.c 2014-02-03 16:29:00.881394627 +0100 > @@ -1691,6 +1691,13 @@ vect_finish_stmt_generation (gimple stmt > } > > gimple_set_location (vec_stmt, gimple_location (stmt)); > + > + /* While EH edges will generally prevent vectorization, stmt might > + e.g. be in a must-not-throw region. Ensure newly created stmts > + that could throw are part of the same region. */ > + int lp_nr = lookup_stmt_eh_lp (stmt); > + if (lp_nr != 0 && stmt_could_throw_p (vec_stmt)) > + add_stmt_to_eh_lp (vec_stmt, lp_nr);
Can you instead use maybe_clean_or_replace_eh_stmt (stmt, vec_stmt)? That should (maybe) take care of the missed DCE as well (maybe only for the first scalar stmt though). Otherwise ok. Thanks, Richard. > } > > /* Checks if CALL can be vectorized in type VECTYPE. Returns > --- gcc/tree-data-ref.c.jj 2014-01-03 11:40:57.000000000 +0100 > +++ gcc/tree-data-ref.c 2014-02-03 16:05:42.111480787 +0100 > @@ -4401,6 +4401,8 @@ get_references_in_stmt (gimple stmt, vec > switch (gimple_call_internal_fn (stmt)) > { > case IFN_MASK_LOAD: > + if (gimple_call_lhs (stmt) == NULL_TREE) > + break; > ref.is_read = true; > case IFN_MASK_STORE: > ref.ref = fold_build2 (MEM_REF, > --- gcc/internal-fn.c.jj 2014-02-03 11:48:17.000000000 +0100 > +++ gcc/internal-fn.c 2014-02-03 16:08:55.606492962 +0100 > @@ -820,6 +820,8 @@ expand_MASK_LOAD (gimple stmt) > > maskt = gimple_call_arg (stmt, 2); > lhs = gimple_call_lhs (stmt); > + if (lhs == NULL_TREE) > + return; > type = TREE_TYPE (lhs); > rhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0), > gimple_call_arg (stmt, 1)); > --- gcc/testsuite/g++.dg/vect/pr60023.cc.jj 2014-02-03 16:39:17.996271473 > +0100 > +++ gcc/testsuite/g++.dg/vect/pr60023.cc 2014-02-03 16:39:36.455176379 > +0100 > @@ -0,0 +1,80 @@ > +// PR tree-optimization/60023 > +// { dg-do compile } > +// { dg-additional-options "-O3 -std=c++11 -fnon-call-exceptions" } > +// { dg-additional-options "-mavx2" { target { i?86-*-* x86_64-*-* } } } > + > +struct A { A (); ~A (); }; > + > +void > +f1 (int *p, int *q, int *r) noexcept (true) > +{ > + int i; > + for (i = 0; i < 1024; i++) > + if (r[i]) > + p[i] = q[i] + 1; > +} > + > +void > +f2 (int *p, int *q, int *r) > +{ > + int i; > + for (i = 0; i < 1024; i++) > + if (r[i]) > + p[i] = q[i] + 1; > +} > + > +void > +f3 (int *p, int *q) noexcept (true) > +{ > + int i; > + for (i = 0; i < 1024; i++) > + p[i] = q[i] + 1; > +} > + > +void > +f4 (int *p, int *q) > +{ > + int i; > + for (i = 0; i < 1024; i++) > + p[i] = q[i] + 1; > +} > + > +void > +f5 (int *p, int *q, int *r) noexcept (true) > +{ > + int i; > + A a; > + for (i = 0; i < 1024; i++) > + if (r[i]) > + p[i] = q[i] + 1; > +} > + > +void > +f6 (int *p, int *q, int *r) > +{ > + int i; > + A a; > + for (i = 0; i < 1024; i++) > + if (r[i]) > + p[i] = q[i] + 1; > +} > + > +void > +f7 (int *p, int *q) noexcept (true) > +{ > + int i; > + A a; > + for (i = 0; i < 1024; i++) > + p[i] = q[i] + 1; > +} > + > +void > +f8 (int *p, int *q) > +{ > + int i; > + A a; > + for (i = 0; i < 1024; i++) > + p[i] = q[i] + 1; > +} > + > +// { dg-final { cleanup-tree-dump "vect" } } > > Jakub > > -- Richard Biener <rguent...@suse.de> SUSE / SUSE Labs SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746 GF: Jeff Hawn, Jennifer Guild, Felix Imend"orffer