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] Fix PR47271: only if-convert full writes.


Hi,

The following patch filters out before if-conversion all the loops
containing basic blocks with more than 2 predecessors or containing
basic blocks that have exactly 2 predecessors not post-dominated by
the basic block: these basic blocks may contain phi nodes that are not
full writes.  The current code generation for the tree-if-conversion
does not handle these cases.

I am regstrapping this patch on amd64-linux.  Ok for trunk?

Thanks,
Sebastian

2011-01-24  Sebastian Pop  <sebastian.pop@amd.com>
	    Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/47271
	* tree-if-conv.c (bb_postdominates_preds): New.
	(if_convertible_bb_p): Return false when bb has more than 2
	predecessors.  Call bb_postdominates_preds.
	(if_convertible_loop_p_1): Compute CDI_POST_DOMINATORS.
	(predicate_scalar_phi): Call bb_postdominates_preds.

	* gcc.dg/tree-ssa/ifc-pr47271.c: New.
---
 gcc/ChangeLog                               |   10 +++++
 gcc/testsuite/ChangeLog                     |    6 +++
 gcc/testsuite/gcc.dg/tree-ssa/ifc-pr47271.c |   49 +++++++++++++++++++++++++++
 gcc/tree-if-conv.c                          |   26 ++++++++++++++
 4 files changed, 91 insertions(+), 0 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ifc-pr47271.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7f3148a..84fb592 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2011-01-24  Sebastian Pop  <sebastian.pop@amd.com>
+	    Jakub Jelinek  <jakub@redhat.com>
+
+	PR tree-optimization/47271
+	* tree-if-conv.c (bb_postdominates_preds): New.
+	(if_convertible_bb_p): Return false when bb has more than 2
+	predecessors.  Call bb_postdominates_preds.
+	(if_convertible_loop_p_1): Compute CDI_POST_DOMINATORS.
+	(predicate_scalar_phi): Call bb_postdominates_preds.
+
 2011-01-23  Bernd Schmidt  <bernds@codesourcery.com>
 	    Richard Sandiford  <rdsandiford@googlemail.com>
 
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 33d1cda..3238e3a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2011-01-24  Sebastian Pop  <sebastian.pop@amd.com>
+	    Jakub Jelinek  <jakub@redhat.com>
+
+	PR tree-optimization/47271
+	* gcc.dg/tree-ssa/ifc-pr47271.c: New.
+
 2011-01-24  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
 
 	* lib/scanasm.exp (dg-function-on-line): Handle mips-sgi-irix*.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ifc-pr47271.c b/gcc/testsuite/gcc.dg/tree-ssa/ifc-pr47271.c
new file mode 100644
index 0000000..bf36079
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ifc-pr47271.c
@@ -0,0 +1,49 @@
+/* { dg-options "-O3" } */
+/* { dg-do run } */
+
+extern void abort (void);
+
+void func (void)
+{
+  int i;
+  int nops;
+  char *codestr =
+    "|\000\000Ee\000\000Z\001\000d\000\000Z\002\000d\025\000Z\003\000"
+    "\t\t\t\t\t\t\t\t\t\t\t\td\026\000Z\004\000d\005\000\204\000\000Z"
+    "\005\000e\006\000e\a\000j\005\000e\b\000d\006\000\204\002\000\203"
+    "\001\000Z\t\000d\a\000\204\000\000Z\n\000d\b\000\204\000\000Z\v\000d"
+    "\t\000\204\000\000Z\f\000d\n\000\204\000\000Z\r\000e\016\000e\017\000d"
+    "\v\000\203\001\000d\f\000d\r\000\203\001\001Z\020\000e\016\000e\017"
+    "\000d\016\000\203\001\000d\f\000d\017\000\203\001\001Z\021\000e\016"
+    "\000e\017\000d\020\000\203\001\000d\f\000d\021\000\203\001\001Z\022"
+    "\000e\016\000e\017\000d\022\000\203\001\000d\f\000d\023\000\203\001"
+    "\001Z\023\000d\024\000S";
+  int codelen = 209;
+  int addrmap[500];
+
+  for (i=0, nops=0 ; i<codelen ; i += ((codestr[i] >= 90) ? 3 : 1))
+    {
+      addrmap[i] = i - nops;
+      if (codestr[i] == 9)
+	nops++;
+    }
+
+  if (addrmap[0] != 0
+      || addrmap[3] != 3
+      || addrmap[4] != 4
+      || addrmap[7] != 7
+      || addrmap[10] != 10
+      || addrmap[13] != 13
+      || addrmap[16] != 16
+      || addrmap[19] != 19
+      || addrmap[22] != 22
+      || addrmap[23] != 22
+      || addrmap[24] != 22)
+    abort ();
+}
+
+int main ()
+{
+  func ();
+  return 0;
+}
diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c
index 46b20c2..269bad9 100644
--- a/gcc/tree-if-conv.c
+++ b/gcc/tree-if-conv.c
@@ -716,6 +716,20 @@ if_convertible_stmt_p (gimple stmt, VEC (data_reference_p, heap) *refs)
   return true;
 }
 
+/* Return true when BB post-dominates all its predecessors.  */
+
+static bool
+bb_postdominates_preds (basic_block bb)
+{
+  unsigned i;
+
+  for (i = 0; i < EDGE_COUNT (bb->preds); i++)
+    if (!dominated_by_p (CDI_POST_DOMINATORS, EDGE_PRED (bb, i)->src, bb))
+      return false;
+
+  return true;
+}
+
 /* Return true when BB is if-convertible.  This routine does not check
    basic block's statements and phis.
 
@@ -774,6 +788,14 @@ if_convertible_bb_p (struct loop *loop, basic_block bb, basic_block exit_bb)
 	return false;
       }
 
+  if (EDGE_COUNT (bb->preds) > 2)
+    return false;
+
+  if (EDGE_COUNT (bb->preds) == 2
+      && bb != loop->header
+      && !bb_postdominates_preds (bb))
+    return false;
+
   return true;
 }
 
@@ -992,6 +1014,7 @@ if_convertible_loop_p_1 (struct loop *loop,
     return false;
 
   calculate_dominance_info (CDI_DOMINATORS);
+  calculate_dominance_info (CDI_POST_DOMINATORS);
 
   /* Allow statements that can be handled during if-conversion.  */
   ifc_bbs = get_loop_body_in_if_conv_order (loop);
@@ -1262,6 +1285,9 @@ predicate_scalar_phi (gimple phi, tree cond,
 	  arg_1 = gimple_phi_arg_def (phi, 1);
 	}
 
+      gcc_checking_assert (bb == bb->loop_father->header
+			   || bb_postdominates_preds (bb));
+
       /* Build new RHS using selected condition and arguments.  */
       rhs = build3 (COND_EXPR, TREE_TYPE (res),
 		    unshare_expr (cond), arg_0, arg_1);
-- 
1.7.1


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