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] Add workaround for PR64715


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.

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

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


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