This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Fix masked loads/stores with -fnon-call-exceptions (PR tree-optimization/60023)


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  <jakub@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 <rguenther@suse.de>
SUSE / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746
GF: Jeff Hawn, Jennifer Guild, Felix Imend"orffer


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]