[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