diff mbox

Fix PR51692

Message ID alpine.LNX.2.00.1201031146360.4999@zhemvz.fhfr.qr
State New
Headers show

Commit Message

Richard Biener Jan. 3, 2012, 10:47 a.m. UTC
This fixes PR51692, we shouldn't remove the lhs of allocation
calls before the special malloc/free pair removal code kicks in.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

Richard.

2012-01-03  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/51692
	* tree-ssa-dce.c (eliminate_unnecessary_stmts): Do not remove
	the LHS of allocation stmts.

	* gcc.dg/torture/pr51692.c: New testcase.
diff mbox

Patch

Index: gcc/tree-ssa-dce.c
===================================================================
--- gcc/tree-ssa-dce.c	(revision 182829)
+++ gcc/tree-ssa-dce.c	(working copy)
@@ -1329,31 +1329,38 @@  eliminate_unnecessary_stmts (void)
 	    }
 	  else if (is_gimple_call (stmt))
 	    {
-	      call = gimple_call_fndecl (stmt);
-	      if (call)
-		{
-		  tree name;
+	      tree name = gimple_call_lhs (stmt);
 
-		  /* When LHS of var = call (); is dead, simplify it into
-		     call (); saving one operand.  */
-		  name = gimple_call_lhs (stmt);
-		  if (name && TREE_CODE (name) == SSA_NAME
-		           && !TEST_BIT (processed, SSA_NAME_VERSION (name)))
-		    {
-		      something_changed = true;
-		      if (dump_file && (dump_flags & TDF_DETAILS))
-			{
-			  fprintf (dump_file, "Deleting LHS of call: ");
-			  print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
-			  fprintf (dump_file, "\n");
-			}
+	      notice_special_calls (stmt);
 
-		      gimple_call_set_lhs (stmt, NULL_TREE);
-		      maybe_clean_or_replace_eh_stmt (stmt, stmt);
-		      update_stmt (stmt);
-		      release_ssa_name (name);
+	      /* When LHS of var = call (); is dead, simplify it into
+		 call (); saving one operand.  */
+	      if (name
+		  && TREE_CODE (name) == SSA_NAME
+		  && !TEST_BIT (processed, SSA_NAME_VERSION (name))
+		  /* Avoid doing so for allocation calls which we
+		     did not mark as necessary, it will confuse the
+		     special logic we apply to malloc/free pair removal.  */
+		  && (!(call = gimple_call_fndecl (stmt))
+		      || DECL_BUILT_IN_CLASS (call) != BUILT_IN_NORMAL
+		      || (DECL_FUNCTION_CODE (call) != BUILT_IN_MALLOC
+			  && DECL_FUNCTION_CODE (call) != BUILT_IN_CALLOC
+			  && DECL_FUNCTION_CODE (call) != BUILT_IN_ALLOCA
+			  && (DECL_FUNCTION_CODE (call)
+			      != BUILT_IN_ALLOCA_WITH_ALIGN))))
+		{
+		  something_changed = true;
+		  if (dump_file && (dump_flags & TDF_DETAILS))
+		    {
+		      fprintf (dump_file, "Deleting LHS of call: ");
+		      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
+		      fprintf (dump_file, "\n");
 		    }
-		  notice_special_calls (stmt);
+
+		  gimple_call_set_lhs (stmt, NULL_TREE);
+		  maybe_clean_or_replace_eh_stmt (stmt, stmt);
+		  update_stmt (stmt);
+		  release_ssa_name (name);
 		}
 	    }
 	}
Index: gcc/testsuite/gcc.dg/torture/pr51692.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr51692.c	(revision 0)
+++ gcc/testsuite/gcc.dg/torture/pr51692.c	(revision 0)
@@ -0,0 +1,13 @@ 
+/* { dg-do compile } */
+
+int
+main ()
+{
+  volatile double d = 0.0;
+  double *p = __builtin_calloc (1, sizeof (double));
+  d += 1.0;
+  *p += 2.0;
+  __builtin_free (p);
+  return 0;
+}
+