[PATCH] Add workaround for PR64715

Richard Biener rguenther@suse.de
Thu Mar 26 09:32:00 GMT 2015


On Thu, 26 Mar 2015, Jakub Jelinek wrote:

> On Thu, Mar 26, 2015 at 09:33:56AM +0100, Richard Biener wrote:
> > this hunk which I think is not really necessary given that
> > the late object-size pass now runs right before FRE which
> 
> Not really immediately before that, but a few passes appart.
> And in the -Og case, while the immediately next pass is fab which doesn't
> manage to optimize it, then there is copyprop pass which does
> (at least on the pr64715-2.c testcase where I had to change objsz2 dump
> in which it doesn't happen to optimized dump (could be also fre2, but
> dind't want to make the testcase too fragile on pass reordering)).
> 
> The propagation was introduced by you in 2013, perhaps it is unnecessary now
> with the introduction of match.pd and trying to fold stuff much more often
> than previously.

I think I simply didn't want to change more testcases at that point,
but I can't see how followup passes at the very point wouldn't
clean things up very quickly (via fre or copyprop).  Eventually
it was -Og and pass_fold_builtins interaction (thinking of
__builtin_constant_p (__builtin_object_size (...)) or so).
If so I'm sure I added a testcase.

> So here is the updated patch I'm going to retest before installing:

Thanks,
Richard.

> 2015-03-26  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR tree-optimization/64715
> 	* passes.def: Add another instance of pass_object_sizes before
> 	ccp1.
> 	* tree-object-size.c (pass_object_sizes::execute): In
> 	first_pass_instance, only handle __bos (, 1) and __bos (, 3)
> 	calls, and keep the call in the IL, as {MIN,MAX}_EXPR of the
> 	__bos result and the computed constant.  Remove redundant
> 	checks, obsoleted by gimple_call_builtin_p test.
> 
> 	* gcc.dg/builtin-object-size-15.c: New test.
> 	* gcc.dg/pr64715-1.c: New test.
> 	* gcc.dg/pr64715-2.c: New test.
> 
> --- gcc/passes.def.jj	2015-03-26 09:36:13.117579045 +0100
> +++ gcc/passes.def	2015-03-26 09:44:53.680118862 +0100
> @@ -77,6 +77,7 @@ along with GCC; see the file COPYING3.
>        PUSH_INSERT_PASSES_WITHIN (pass_all_early_optimizations)
>  	  NEXT_PASS (pass_remove_cgraph_callee_edges);
>  	  NEXT_PASS (pass_rename_ssa_copies);
> +	  NEXT_PASS (pass_object_sizes);
>  	  NEXT_PASS (pass_ccp);
>  	  /* After CCP we rewrite no longer addressed locals into SSA
>  	     form if possible.  */
> --- gcc/tree-object-size.c.jj	2015-03-26 09:36:13.140578671 +0100
> +++ gcc/tree-object-size.c	2015-03-26 09:56:20.335960571 +0100
> @@ -1268,25 +1268,60 @@ pass_object_sizes::execute (function *fu
>  	    continue;
>  
>  	  init_object_sizes ();
> +
> +	  /* In the first pass instance, only attempt to fold
> +	     __builtin_object_size (x, 1) and __builtin_object_size (x, 3),
> +	     and rather than folding the builtin to the constant if any,
> +	     create a MIN_EXPR or MAX_EXPR of the __builtin_object_size
> +	     call result and the computed constant.  */
> +	  if (first_pass_instance)
> +	    {
> +	      tree ost = gimple_call_arg (call, 1);
> +	      if (tree_fits_uhwi_p (ost))
> +		{
> +		  unsigned HOST_WIDE_INT object_size_type = tree_to_uhwi (ost);
> +		  tree ptr = gimple_call_arg (call, 0);
> +		  tree lhs = gimple_call_lhs (call);
> +		  if ((object_size_type == 1 || object_size_type == 3)
> +		      && (TREE_CODE (ptr) == ADDR_EXPR
> +			  || TREE_CODE (ptr) == SSA_NAME)
> +		      && lhs)
> +		    {
> +		      tree type = TREE_TYPE (lhs);
> +		      unsigned HOST_WIDE_INT bytes
> +			= compute_builtin_object_size (ptr, object_size_type);
> +		      if (bytes != (unsigned HOST_WIDE_INT) (object_size_type == 1
> +							     ? -1 : 0)
> +			  && wi::fits_to_tree_p (bytes, type))
> +			{
> +			  tree tem = make_ssa_name (type);
> +			  gimple_call_set_lhs (call, tem);
> +			  enum tree_code code
> +			    = object_size_type == 1 ? MIN_EXPR : MAX_EXPR;
> +			  tree cst = build_int_cstu (type, bytes);
> +			  gimple g = gimple_build_assign (lhs, code, tem, cst);
> +			  gsi_insert_after (&i, g, GSI_NEW_STMT);
> +			  update_stmt (call);
> +			}
> +		    }
> +		}
> +	      continue;
> +	    }
> +
>  	  result = fold_call_stmt (as_a <gcall *> (call), false);
>  	  if (!result)
>  	    {
> -	      if (gimple_call_num_args (call) == 2
> -		  && POINTER_TYPE_P (TREE_TYPE (gimple_call_arg (call, 0))))
> -		{
> -		  tree ost = gimple_call_arg (call, 1);
> +	      tree ost = gimple_call_arg (call, 1);
>  
> -		  if (tree_fits_uhwi_p (ost))
> -		    {
> -		      unsigned HOST_WIDE_INT object_size_type
> -			= tree_to_uhwi (ost);
> +	      if (tree_fits_uhwi_p (ost))
> +		{
> +		  unsigned HOST_WIDE_INT object_size_type = tree_to_uhwi (ost);
>  
> -		      if (object_size_type < 2)
> -			result = fold_convert (size_type_node,
> -					       integer_minus_one_node);
> -		      else if (object_size_type < 4)
> -			result = build_zero_cst (size_type_node);
> -		    }
> +		  if (object_size_type < 2)
> +		    result = fold_convert (size_type_node,
> +					   integer_minus_one_node);
> +		  else if (object_size_type < 4)
> +		    result = build_zero_cst (size_type_node);
>  		}
>  
>  	      if (!result)
> --- gcc/testsuite/gcc.dg/builtin-object-size-15.c.jj	2015-03-26 09:44:53.681118846 +0100
> +++ gcc/testsuite/gcc.dg/builtin-object-size-15.c	2015-03-26 09:44:53.681118846 +0100
> @@ -0,0 +1,27 @@
> +/* { dg-do run } */
> +/* { dg-options "-O2" } */
> +
> +extern void abort (void);
> +
> +int
> +main ()
> +{
> +  struct A { char buf1[9]; char buf2[1]; } a;
> +
> +  if (__builtin_object_size (a.buf1 + (0 + 4), 1) != 5)
> +    abort ();
> +  char *p = a.buf1;
> +  p += 1;
> +  p += 3;
> +  if (__builtin_object_size (p, 1) != 5)
> +    abort ();
> +  p = (char *) &a;
> +  char *q = p + 1;
> +  char *r = q + 3;
> +  char *t = r;
> +  if (r != (char *) &a + 4)
> +    t = (char *) &a + 1;
> +  if (__builtin_object_size (t, 1) != 6)
> +    abort ();
> +  return 0;
> +}
> --- gcc/testsuite/gcc.dg/pr64715-1.c.jj	2015-03-26 09:44:53.682118830 +0100
> +++ gcc/testsuite/gcc.dg/pr64715-1.c	2015-03-26 09:44:53.682118830 +0100
> @@ -0,0 +1,23 @@
> +/* PR tree-optimization/64715 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +
> +extern inline __attribute__ ((always_inline, gnu_inline, artificial, nothrow, leaf)) char *
> +strcpy (char *__restrict dest, const char *__restrict src)
> +{
> +  return __builtin___strcpy_chk (dest, src, __builtin_object_size (dest, 2 > 1));
> +}
> +
> +const char *str1 = "JIHGFEDCBA";
> +void bar (char *);
> +
> +void
> +foo ()
> +{
> +  struct A { char buf1[9]; char buf2[1]; } a;
> +  strcpy (a.buf1 + (0 + 4), str1 + 5);
> +  bar ((char *) &a);
> +}
> +
> +/* { dg-final { scan-tree-dump "__builtin___strcpy_chk\[^;\n\r\]*, 5\\\);" "optimized" } } */
> +/* { dg-final { cleanup-tree-dump "optimized" } } */
> --- gcc/testsuite/gcc.dg/pr64715-2.c.jj	2015-03-26 09:44:53.682118830 +0100
> +++ gcc/testsuite/gcc.dg/pr64715-2.c	2015-03-26 09:57:50.198501347 +0100
> @@ -0,0 +1,19 @@
> +/* PR tree-optimization/64715 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +
> +void bar (char *, int);
> +
> +void
> +foo (int x)
> +{
> +  char p[16], *q;
> +  q = p;
> +  if (x)
> +    q = p + 3;
> +  __builtin___strcpy_chk (q, "abcdefghijkl", __builtin_object_size (q, 1));
> +  bar (p, x);
> +}
> +
> +/* { dg-final { scan-tree-dump "__builtin_memcpy \\\(\[^;\n\r\]*, \"abcdefghijkl\", 13\\\);" "optimized" } } */
> +/* { dg-final { cleanup-tree-dump "optimized" } } */
> 
> 
> 	Jakub
> 
> 

-- 
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Jennifer Guild,
Dilip Upmanyu, Graham Norton HRB 21284 (AG Nuernberg)



More information about the Gcc-patches mailing list