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

Andrew Pinski andrew.pinski@caviumnetworks.com
Mon Sep 3 05:18:00 GMT 2012


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