[PATCH] Improve VPR for some builtins and non pointer checks

Georg-Johann Lay gjl@gcc.gnu.org
Mon Sep 3 06:37:00 GMT 2012


Andrew Pinski schrieb:
> Hi,
>   While fixing some code not to have aliasing violations in it, I can
> across that some builtins were not causing their arguments or their
> return values being marked as non-null.  This patch implements just
> that in VPR while allowing to remove some null pointer checks later
> on.
> 
> OK?  Bootstrapped and tested on x86_64-linux-gnu with no regressions.
> 
> Thanks,
> Andrew Pinski
> 
> ChangeLog:
>         * tree-vrp.c (vrp_stmt_computes_nonzero): Return true for some
>         builtins (memcpy and memmove).
>         (infer_value_range): Infer nonzero for some arguments to
>         some builtins (memcpy, memmove, strcmp and memcmp).
> 
> testsuite/ChangeLog:
>         * gcc.dg/tree-ssa/vrp-builtins1.c: New testcase.
> 
> 
> 
> Index: tree-vrp.c
> ===================================================================
> --- tree-vrp.c	(revision 190868)
> +++ tree-vrp.c	(working copy)
> @@ -1057,6 +1057,20 @@ vrp_stmt_computes_nonzero (gimple stmt,
>  	}
>      }
>  
> +  /* With some builtins, we can infer if the pointer return value
> +     will be non null.  */
> +  if (flag_delete_null_pointer_checks
> +      && is_gimple_call (stmt) && gimple_call_fndecl (stmt)
> +      && DECL_BUILT_IN_CLASS (gimple_call_fndecl (stmt)) == BUILT_IN_NORMAL)
> +    {
> +      switch (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt)))
> +	{
> +	  case BUILT_IN_MEMCPY:
> +	  case BUILT_IN_MEMMOVE:
> +	    return true;
> +	}
> +    }
> +
>    return false;
>  }
>  
> @@ -4231,6 +4245,32 @@ infer_value_range (gimple stmt, tree op,
>  	}
>      }
>  
> +  /* With some builtins, we can infer if the pointer argument
> +     will be non null.  */
> +  if (flag_delete_null_pointer_checks
> +      && is_gimple_call (stmt) && gimple_call_fndecl (stmt))
> +    {
> +      tree callee = gimple_call_fndecl (stmt);
> +      if (DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL)
> +	{
> +	  switch (DECL_FUNCTION_CODE (callee))
> +	    {
> +	      case BUILT_IN_MEMCPY:
> +	      case BUILT_IN_MEMMOVE:
> +	      case BUILT_IN_STRCMP:
> +	      case BUILT_IN_MEMCMP:
> +		/* The first and second arguments of memcpy and memmove will be non null after the call. */
> +		if (gimple_call_arg (stmt, 0) == op
> +		    || gimple_call_arg (stmt, 1) == op)
> +		  {
> +		    *val_p = build_int_cst (TREE_TYPE (op), 0);
> +		    *comp_code_p = NE_EXPR;
> +		    return true;
> +		  }
> +	    }
> +	}
> +    }
> +
>    return false;
>  }
>  
> Index: testsuite/gcc.dg/tree-ssa/vrp-builtins1.c
> ===================================================================
> --- testsuite/gcc.dg/tree-ssa/vrp-builtins1.c	(revision 0)
> +++ testsuite/gcc.dg/tree-ssa/vrp-builtins1.c	(revision 0)
> @@ -0,0 +1,30 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-vrp1" } */

Shouldn't this xfail for avr and other targets that set
flag_delete_null_pointer_checks = 0, cf.
avr.c:avr_option_override() for example.

Johann

> +
> +struct f1
> +{
> +char a[4];
> +};
> +
> +int f(int *a, struct f1 b)
> +{
> +  int *c = __builtin_memcpy(a, b.a, 4);
> +  if (c == 0)
> +    return 0;
> +  return *a;
> +}
> +
> +
> +int f1(int *a, struct f1 b)
> +{
> +  int *c = __builtin_memcpy(a, b.a, 4);
> +  if (a == 0)
> +    return 0;
> +  return *a;
> +}
> +
> +/* Both the if statements should be folded when the target does not keep around null pointer checks. */
> +/* { dg-final { scan-tree-dump-times "Folding predicate" 0 "vrp1" { target {   keeps_null_pointer_checks } } } } */
> +/* { dg-final { scan-tree-dump-times "Folding predicate" 2 "vrp1" { target { ! keeps_null_pointer_checks } } } } */
> +/* { dg-final { cleanup-tree-dump "vrp1" } } */
> +



More information about the Gcc-patches mailing list