Patchwork Fix PR50319, if-conversion behaving weirdly

login
register
mail settings
Submitter Richard Guenther
Date Sept. 7, 2011, 1:07 p.m.
Message ID <alpine.LNX.2.00.1109071505140.2130@zhemvz.fhfr.qr>
Download mbox | patch
Permalink /patch/113761/
State New
Headers show

Comments

Richard Guenther - Sept. 7, 2011, 1:07 p.m.
This fixes if-conversion to properly track inversion in its
(topmost) predicate.  Spurious gimplification made this code
never work (it doesn't work at least on the 4.6 branch either).

Bootstrap and regtest ongoing on x86_64-unknown-linux-gnu.

Richard.

2011-09-07  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/50319
	* tree-if-conv.c (set_bb_predicate): Assert we only set
	canonical predicates.
	(add_to_predicate_list): Simplify.  Allow TRUTH_NOT_EXPR
	around canonical predicates.
	(predicate_bbs): Do not re-gimplify already canonical
	predicates.  Properly unshare them though.
	(find_phi_replacement_condition): Simplify.

Patch

Index: gcc/tree-if-conv.c
===================================================================
--- gcc/tree-if-conv.c	(revision 178633)
+++ gcc/tree-if-conv.c	(working copy)
@@ -137,6 +137,9 @@  bb_predicate (basic_block bb)
 static inline void
 set_bb_predicate (basic_block bb, tree cond)
 {
+  gcc_assert ((TREE_CODE (cond) == TRUTH_NOT_EXPR
+	       && is_gimple_condexpr (TREE_OPERAND (cond, 0)))
+	      || is_gimple_condexpr (cond));
   ((bb_predicate_p) bb->aux)->predicate = cond;
 }
 
@@ -328,7 +331,7 @@  fold_or_predicates (location_t loc, tree
 static inline void
 add_to_predicate_list (basic_block bb, tree nc)
 {
-  tree bc;
+  tree bc, *tp;
 
   if (is_true_predicate (nc))
     return;
@@ -339,19 +342,25 @@  add_to_predicate_list (basic_block bb, t
     {
       bc = bb_predicate (bb);
       bc = fold_or_predicates (EXPR_LOCATION (bc), nc, bc);
+      if (is_true_predicate (bc))
+	{
+	  reset_bb_predicate (bb);
+	  return;
+	}
     }
 
-  if (!is_gimple_condexpr (bc))
+  /* Allow a TRUTH_NOT_EXPR around the main predicate.  */
+  if (TREE_CODE (bc) == TRUTH_NOT_EXPR)
+    tp = &TREE_OPERAND (bc, 0);
+  else
+    tp = &bc;
+  if (!is_gimple_condexpr (*tp))
     {
       gimple_seq stmts;
-      bc = force_gimple_operand (bc, &stmts, true, NULL_TREE);
+      *tp = force_gimple_operand_1 (*tp, &stmts, is_gimple_condexpr, NULL_TREE);
       add_bb_predicate_gimplified_stmts (bb, stmts);
     }
-
-  if (is_true_predicate (bc))
-    reset_bb_predicate (bb);
-  else
-    set_bb_predicate (bb, bc);
+  set_bb_predicate (bb, bc);
 }
 
 /* Add the condition COND to the previous condition PREV_COND, and add
@@ -944,14 +953,6 @@  predicate_bbs (loop_p loop)
 	}
 
       cond = bb_predicate (bb);
-      if (cond
-	  && bb != loop->header)
-	{
-	  gimple_seq stmts;
-
-	  cond = force_gimple_operand (cond, &stmts, true, NULL_TREE);
-	  add_bb_predicate_gimplified_stmts (bb, stmts);
-	}
 
       for (itr = gsi_start_bb (bb); !gsi_end_p (itr); gsi_next (&itr))
 	{
@@ -980,14 +981,17 @@  predicate_bbs (loop_p loop)
 						     &true_edge, &false_edge);
 
 		/* If C is true, then TRUE_EDGE is taken.  */
-		add_to_dst_predicate_list (loop, true_edge, cond, unshare_expr (c));
+		add_to_dst_predicate_list (loop, true_edge,
+					   unshare_expr (cond),
+					   unshare_expr (c));
 
 		/* If C is false, then FALSE_EDGE is taken.  */
 		c2 = invert_truthvalue_loc (loc, unshare_expr (c));
 		tem = canonicalize_cond_expr_cond (c2);
 		if (tem)
 		  c2 = tem;
-		add_to_dst_predicate_list (loop, false_edge, cond, c2);
+		add_to_dst_predicate_list (loop, false_edge,
+					   unshare_expr (cond), c2);
 
 		cond = NULL_TREE;
 		break;
@@ -1237,7 +1241,7 @@  find_phi_replacement_condition (struct l
       *cond = bb_predicate (second_edge->src);
 
       if (TREE_CODE (*cond) == TRUTH_NOT_EXPR)
-	*cond = invert_truthvalue (*cond);
+	*cond = TREE_OPERAND (*cond, 0);
       else
 	/* Select non loop header bb.  */
 	first_edge = second_edge;
@@ -1245,18 +1249,10 @@  find_phi_replacement_condition (struct l
   else
     *cond = bb_predicate (first_edge->src);
 
-  /* Gimplify the condition: the vectorizer prefers to have gimple
-     values as conditions.  Various targets use different means to
-     communicate conditions in vector compare operations.  Using a
-     gimple value allows the compiler to emit vector compare and
-     select RTL without exposing compare's result.  */
-  *cond = force_gimple_operand_gsi (gsi, unshare_expr (*cond),
-				    false, NULL_TREE,
-				    true, GSI_SAME_STMT);
-  if (!is_gimple_reg (*cond) && !is_gimple_condexpr (*cond))
-    *cond = ifc_temp_var (TREE_TYPE (*cond), unshare_expr (*cond), gsi);
-
-  gcc_assert (*cond);
+  /* Gimplify the condition to a valid cond-expr conditonal operand.  */
+  *cond = force_gimple_operand_gsi_1 (gsi, unshare_expr (*cond),
+				      is_gimple_condexpr, NULL_TREE,
+				      true, GSI_SAME_STMT);
 
   return first_edge->src;
 }