diff mbox

Fix PR46036: if-conversion problem

Message ID AANLkTikCuceMdFXX7LG2Jp6E2F6-MXSvOim72NSaq3hE@mail.gmail.com
State New
Headers show

Commit Message

Sebastian Pop Nov. 8, 2010, 9:31 p.m. UTC
Hi,

While working on PR46036, I remarked that there are some OR
expressions that do not fold correctly into "true".  The attached
patch does improve the situation a bit, and there is still a missing
case a bit more difficult to handle where parse_predicate returns
two SSA_NAMEs, then we would need to fold "a || b".

The attached patch passed bootstrap and test on amd64-linux.
Would this kind of patch be ok for trunk?  Should I send out a
patch addressing the remaining missing case?

Thanks,
Sebastian

Comments

Richard Biener Nov. 9, 2010, 10:21 a.m. UTC | #1
On Mon, 8 Nov 2010, Sebastian Pop wrote:

> Hi,
> 
> While working on PR46036, I remarked that there are some OR
> expressions that do not fold correctly into "true".  The attached
> patch does improve the situation a bit, and there is still a missing
> case a bit more difficult to handle where parse_predicate returns
> two SSA_NAMEs, then we would need to fold "a || b".
> 
> The attached patch passed bootstrap and test on amd64-linux.
> Would this kind of patch be ok for trunk?  Should I send out a
> patch addressing the remaining missing case?

Ok, yes please.

Thanks,
Richard.
diff mbox

Patch

From 554bc66748971f79e81dfb89536db7fd4b80d452 Mon Sep 17 00:00:00 2001
From: Sebastian Pop <sebpop@gmail.com>
Date: Thu, 4 Nov 2010 17:13:09 -0500
Subject: [PATCH 1/2] improve parse_predicate

---
 gcc/gimple-fold.c  |    5 +----
 gcc/gimple.h       |    3 ++-
 gcc/tree-if-conv.c |   28 +++++++++++++++++++++-------
 3 files changed, 24 insertions(+), 12 deletions(-)

diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index e561a63..63725c3 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -1864,9 +1864,6 @@  static tree
 or_comparisons_1 (enum tree_code code1, tree op1a, tree op1b,
 		  enum tree_code code2, tree op2a, tree op2b);
 static tree
-or_var_with_comparison (tree var, bool invert,
-			enum tree_code code2, tree op2a, tree op2b);
-static tree
 or_var_with_comparison_1 (gimple stmt, 
 			  enum tree_code code2, tree op2a, tree op2b);
 
@@ -2323,7 +2320,7 @@  maybe_fold_and_comparisons (enum tree_code code1, tree op1a, tree op1b,
    If INVERT is true, invert the value of VAR before doing the OR.
    Return NULL_EXPR if we can't simplify this to a single expression.  */
 
-static tree
+tree
 or_var_with_comparison (tree var, bool invert,
 			enum tree_code code2, tree op2a, tree op2b)
 {
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 150b836..623cd51 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -4879,9 +4879,10 @@  tree maybe_fold_stmt_addition (location_t, tree, tree, tree);
 tree get_symbol_constant_value (tree);
 tree canonicalize_constructor_val (tree);
 bool may_propagate_address_into_dereference (tree, tree);
-extern tree maybe_fold_and_comparisons (enum tree_code, tree, tree, 
+extern tree maybe_fold_and_comparisons (enum tree_code, tree, tree,
 					enum tree_code, tree, tree);
 extern tree maybe_fold_or_comparisons (enum tree_code, tree, tree,
 				       enum tree_code, tree, tree);
+extern tree or_var_with_comparison (tree, bool, enum tree_code, tree, tree);
 
 #endif  /* GCC_GIMPLE_H */
diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c
index 642dbda..2c334d9 100644
--- a/gcc/tree-if-conv.c
+++ b/gcc/tree-if-conv.c
@@ -273,14 +273,16 @@  parse_predicate (tree cond, tree *op0, tree *op1)
   if (TREE_CODE (cond) == SSA_NAME
       && is_gimple_assign (s = SSA_NAME_DEF_STMT (cond)))
     {
-      if (TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison)
+      enum tree_code outer_code = gimple_assign_rhs_code (s);
+
+      if (TREE_CODE_CLASS (outer_code) == tcc_comparison)
 	{
 	  *op0 = gimple_assign_rhs1 (s);
 	  *op1 = gimple_assign_rhs2 (s);
-	  return gimple_assign_rhs_code (s);
+	  return outer_code;
 	}
 
-      else if (gimple_assign_rhs_code (s) == TRUTH_NOT_EXPR)
+      if (outer_code == TRUTH_NOT_EXPR)
 	{
 	  tree op = gimple_assign_rhs1 (s);
 	  tree type = TREE_TYPE (op);
@@ -290,6 +292,9 @@  parse_predicate (tree cond, tree *op0, tree *op1)
 	    : invert_tree_comparison (code, HONOR_NANS (TYPE_MODE (type)));
 	}
 
+      if (gimple_assign_cast_p (s))
+	return parse_predicate (gimple_assign_rhs1 (s), op0, op1);
+
       return ERROR_MARK;
     }
 
@@ -308,15 +313,24 @@  parse_predicate (tree cond, tree *op0, tree *op1)
 static tree
 fold_or_predicates (location_t loc, tree c1, tree c2)
 {
-  tree op1a, op1b, op2a, op2b;
+  tree op1a, op1b, op2a, op2b, t;
   enum tree_code code1 = parse_predicate (c1, &op1a, &op1b);
   enum tree_code code2 = parse_predicate (c2, &op2a, &op2b);
 
   if (code1 != ERROR_MARK && code2 != ERROR_MARK)
     {
-      tree t = maybe_fold_or_comparisons (code1, op1a, op1b,
-					  code2, op2a, op2b);
-      if (t)
+      if ((t = maybe_fold_or_comparisons (code1, op1a, op1b,
+					  code2, op2a, op2b)))
+	return t;
+    }
+  else if (code2 != ERROR_MARK)
+    {
+      if ((t = or_var_with_comparison (c1, false, code2, op2a, op2b)))
+	return t;
+    }
+  else if (code1 != ERROR_MARK)
+    {
+      if ((t = or_var_with_comparison (c2, false, code1, op1a, op1b)))
 	return t;
     }
 
-- 
1.7.0.4