re PR tree-optimization/47737 (wrong code with -funswitch-loops -fno-tree-dominator...
authorRichard Guenther <rguenther@suse.de>
Fri, 18 Feb 2011 13:22:17 +0000 (13:22 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 18 Feb 2011 13:22:17 +0000 (13:22 +0000)
2011-02-18  Richard Guenther  <rguenther@suse.de>

PR tree-optimization/47737
* tree-ssa-loop-im.c (extract_true_false_args_from_phi): Fix
edge dominance check.

From-SVN: r170272

gcc/ChangeLog
gcc/tree-ssa-loop-im.c

index 41c09ff5a61bc3706254bfe72e4517a3cc007ca8..724e6edcceb3ab1548a68daf39124a2fc34a188b 100644 (file)
@@ -1,3 +1,9 @@
+2011-02-18  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/47737
+       * tree-ssa-loop-im.c (extract_true_false_args_from_phi): Fix
+       edge dominance check.
+
 2011-02-18  Jakub Jelinek  <jakub@redhat.com>
 
        PR debug/47780
index 57f98978223348793fced8cecd6c1a2ce1c94439..4ec67cf1138eba56db012fbf4f9a77db5db3e2d9 100644 (file)
@@ -676,31 +676,38 @@ extract_true_false_args_from_phi (basic_block dom, gimple phi,
      by the true edge of the predicate block and the other edge
      dominated by the false edge.  This ensures that the PHI argument
      we are going to take is completely determined by the path we
-     take from the predicate block.  */
+     take from the predicate block.
+     We can only use BB dominance checks below if the destination of
+     the true/false edges are dominated by their edge, thus only
+     have a single predecessor.  */
   extract_true_false_edges_from_block (dom, &true_edge, &false_edge);
   tem = EDGE_PRED (bb, 0);
   if (tem == true_edge
-      || tem->src == true_edge->dest
-      || dominated_by_p (CDI_DOMINATORS,
-                        tem->src, true_edge->dest))
+      || (single_pred_p (true_edge->dest)
+         && (tem->src == true_edge->dest
+             || dominated_by_p (CDI_DOMINATORS,
+                                tem->src, true_edge->dest))))
     arg0 = PHI_ARG_DEF (phi, tem->dest_idx);
   else if (tem == false_edge
-          || tem->src == false_edge->dest
-          || dominated_by_p (CDI_DOMINATORS,
-                             tem->src, false_edge->dest))
+          || (single_pred_p (false_edge->dest)
+              && (tem->src == false_edge->dest
+                  || dominated_by_p (CDI_DOMINATORS,
+                                     tem->src, false_edge->dest))))
     arg1 = PHI_ARG_DEF (phi, tem->dest_idx);
   else
     return false;
   tem = EDGE_PRED (bb, 1);
   if (tem == true_edge
-      || tem->src == true_edge->dest
-      || dominated_by_p (CDI_DOMINATORS,
-                        tem->src, true_edge->dest))
+      || (single_pred_p (true_edge->dest)
+         && (tem->src == true_edge->dest
+             || dominated_by_p (CDI_DOMINATORS,
+                                tem->src, true_edge->dest))))
     arg0 = PHI_ARG_DEF (phi, tem->dest_idx);
   else if (tem == false_edge
-          || tem->src == false_edge->dest
-          || dominated_by_p (CDI_DOMINATORS,
-                             tem->src, false_edge->dest))
+          || (single_pred_p (false_edge->dest)
+              && (tem->src == false_edge->dest
+                  || dominated_by_p (CDI_DOMINATORS,
+                                     tem->src, false_edge->dest))))
     arg1 = PHI_ARG_DEF (phi, tem->dest_idx);
   else
     return false;