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]

[patch] PR23234 (take 2)


Hello,

So again...   This fixes PR23234.  Bootstrapped and tested (all
languages except ada) on x86_64-unknown-linux-gnu.  OK for mainline?

Gr.
Steven

	PR tree-optimization/23234
	* tree-ssa-math-opts.c (gate_cse_reciprocals): Rename the 'phi'
	function argument to 'before_bsi'.
	(execute_cse_reciprocals): Add reciprocals for function arguments
	before the last statement of the first basic block.

Index: tree-ssa-math-opts.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-math-opts.c,v
retrieving revision 2.4
diff -u -3 -p -r2.4 tree-ssa-math-opts.c
--- tree-ssa-math-opts.c	1 Aug 2005 08:58:25 -0000	2.4
+++ tree-ssa-math-opts.c	7 Aug 2005 16:35:23 -0000
@@ -56,14 +56,15 @@ gate_cse_reciprocals (void)
 
 /* Check if DEF's uses include more than one floating-point division,
    and if so replace them by multiplications with the reciprocal.  If
-   PHI is true, insert the reciprocal calculation before BSI, otherwise
-   insert it after and move BSI to the new statement.
+   BEFORE_BSI is true, insert the reciprocal calculation before BSI,
+   otherwise insert it after and move BSI to the new statement.
 
    Does not check the type of DEF, nor that DEF is a GIMPLE register.
    This is done in the caller for speed, because otherwise this routine
    would be called for every definition and phi node.  */
 static void
-execute_cse_reciprocals_1 (block_stmt_iterator *bsi, tree def, bool phi)
+execute_cse_reciprocals_1 (block_stmt_iterator *bsi,
+			   tree def, bool before_bsi)
 {
   use_operand_p use_p;
   imm_use_iterator use_iter;
@@ -99,7 +100,7 @@ execute_cse_reciprocals_1 (block_stmt_it
 		     fold_build2 (RDIV_EXPR, type, build_real (type, dconst1),
 				  def));
 
-  if (phi)
+  if (before_bsi)
     bsi_insert_before (bsi, new_stmt, BSI_SAME_STMT);
   else
     bsi_insert_after (bsi, new_stmt, BSI_NEW_STMT);
@@ -127,14 +128,21 @@ execute_cse_reciprocals (void)
   if (flag_trapping_math)
     calculate_dominance_info (CDI_POST_DOMINATORS);
 
-  if (single_succ_p (ENTRY_BLOCK_PTR))
-    for (arg = DECL_ARGUMENTS (cfun->decl); arg; arg = TREE_CHAIN (arg))
-      if (default_def (arg))
-	{
-	  block_stmt_iterator bsi;
-	  bsi = bsi_start (single_succ (ENTRY_BLOCK_PTR));
-          execute_cse_reciprocals_1 (&bsi, default_def (arg), false);
-	}
+  if (single_succ_p (ENTRY_BLOCK_PTR) && DECL_ARGUMENTS (cfun->decl))
+    {
+      block_stmt_iterator bsi;
+      basic_block first_block = single_succ (ENTRY_BLOCK_PTR);
+      bsi = bsi_start (first_block);
+      /* ??? bsi_after_labels doesn't work if there is no label in the
+	 basic block, which is the common situation for the first block
+	 of a function.  */
+      while (!bsi_end_p (bsi) && TREE_CODE (bsi_stmt (bsi)) == LABEL_EXPR)
+	bsi_next (&bsi);
+      
+      for (arg = DECL_ARGUMENTS (cfun->decl); arg; arg = TREE_CHAIN (arg))
+	if (default_def (arg))
+          execute_cse_reciprocals_1 (&bsi, default_def (arg), true);
+    }
 
   FOR_EACH_BB (bb)
     {
Index: testsuite/gcc.dg/tree-ssa/pr23234.c
===================================================================
RCS file: testsuite/gcc.dg/tree-ssa/pr23234.c
diff -N testsuite/gcc.dg/tree-ssa/pr23234.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.dg/tree-ssa/pr23234.c	7 Aug 2005 16:35:32 -0000
@@ -0,0 +1,52 @@
+/* The problem in this PR was mostly finding a suitable place to insert
+   the reciprocals of the function arguments.  This test case tries to
+   test three possible ways of how this may go wrong.  */
+/* { dg-options "-O2 -ffast-math" } */
+/* { dg-do compile } */
+
+/* The original test case.  */
+double
+f1 (double a, double b, double c)
+{
+  double y0;
+
+  if (a == 0.0)
+    {
+      y0 = -c / b;
+      return y0;
+    }
+  y0 = c / b;
+  return y0;
+}
+
+/* Labels may end up in the middle of a block.  Also bad.  */
+double
+f2 (double a, double b, double c)
+{
+  double y0;
+
+a_label:
+another_label:
+  if (a == 0.0)
+    {
+      y0 = -c / b;
+      return y0;
+    }
+  y0 = c / b;
+  return y0;
+}
+
+/* Uses must still be dominated by their defs.  */
+double
+f3 (double a, double b, double c)
+{
+  double y0;
+
+  y0 = -c / b;
+  if (a == 0.0)
+    {
+      return y0;
+    }
+  y0 = c / b;
+  return y0;
+}


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