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] Improve VPR for some builtins and non pointer checks


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" } } */
+


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