aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKai Tietz <ktietz@redhat.com>2011-08-02 16:55:47 +0200
committerKai Tietz <ktietz@gcc.gnu.org>2011-08-02 16:55:47 +0200
commit9b80d091af4760e4c8869917790bd01465b7a59e (patch)
tree9ab01933186298e3c020529082506e008ea0077a
parent7b9db92637e1e8229f3ab026d4b9c5ef3072b7a5 (diff)
downloadgcc-9b80d091af4760e4c8869917790bd01465b7a59e.zip
gcc-9b80d091af4760e4c8869917790bd01465b7a59e.tar.gz
gcc-9b80d091af4760e4c8869917790bd01465b7a59e.tar.bz2
gimple.c (canonicalize_cond_expr_cond): Handle cast from boolean-type.
* gimple.c (canonicalize_cond_expr_cond): Handle cast from boolean-type. (ssa_forward_propagate_and_combine): Interprete result of forward_propagate_comparison. * gcc/gimple-fold.c (fold_gimple_assign): Add canonicalization for boolean-typed operands for comparisons. * gcc.dg/tree-ssa/forwprop-15.c: New testcase. From-SVN: r177170
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/gimple-fold.c41
-rw-r--r--gcc/gimple.c4
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/forwprop-15.c14
-rw-r--r--gcc/tree-ssa-forwprop.c5
6 files changed, 75 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f525c95..7493d23 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2011-08-02 Kai Tietz <ktietz@redhat.com>
+
+ * gimple.c (canonicalize_cond_expr_cond): Handle cast from
+ boolean-type.
+ (ssa_forward_propagate_and_combine): Interprete result of
+ forward_propagate_comparison.
+ * gcc/gimple-fold.c (fold_gimple_assign): Add canonicalization for
+ boolean-typed operands for comparisons.
+
2011-08-02 Georg-Johann Lay <avr@gjlay.de>
* config/avr/libgcc.S: Gather related function in the
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index cc89b2f..cd988b9 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -814,6 +814,47 @@ fold_gimple_assign (gimple_stmt_iterator *si)
gimple_assign_rhs1 (stmt),
gimple_assign_rhs2 (stmt));
}
+ /* Try to canonicalize for boolean-typed X the comparisons
+ X == 0, X == 1, X != 0, and X != 1. */
+ else if (gimple_assign_rhs_code (stmt) == EQ_EXPR
+ || gimple_assign_rhs_code (stmt) == NE_EXPR)
+ {
+ tree lhs = gimple_assign_lhs (stmt);
+ tree op1 = gimple_assign_rhs1 (stmt);
+ tree op2 = gimple_assign_rhs2 (stmt);
+ tree type = TREE_TYPE (op1);
+
+ /* Check whether the comparison operands are of the same boolean
+ type as the result type is.
+ Check that second operand is an integer-constant with value
+ one or zero. */
+ if (TREE_CODE (op2) == INTEGER_CST
+ && (integer_zerop (op2) || integer_onep (op2))
+ && useless_type_conversion_p (TREE_TYPE (lhs), type))
+ {
+ enum tree_code cmp_code = gimple_assign_rhs_code (stmt);
+ bool is_logical_not = false;
+
+ /* X == 0 and X != 1 is a logical-not.of X
+ X == 1 and X != 0 is X */
+ if ((cmp_code == EQ_EXPR && integer_zerop (op2))
+ || (cmp_code == NE_EXPR && integer_onep (op2)))
+ is_logical_not = true;
+
+ if (is_logical_not == false)
+ result = op1;
+ /* Only for one-bit precision typed X the transformation
+ !X -> ~X is valied. */
+ else if (TYPE_PRECISION (type) == 1)
+ result = build1_loc (gimple_location (stmt), BIT_NOT_EXPR,
+ type, op1);
+ /* Otherwise we use !X -> X ^ 1. */
+ else
+ result = build2_loc (gimple_location (stmt), BIT_XOR_EXPR,
+ type, op1, build_int_cst (type, 1));
+
+ }
+ }
if (!result)
result = fold_binary_loc (loc, subcode,
diff --git a/gcc/gimple.c b/gcc/gimple.c
index e3095d7..af23c6a 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -3160,7 +3160,9 @@ canonicalize_cond_expr_cond (tree t)
{
/* Strip conversions around boolean operations. */
if (CONVERT_EXPR_P (t)
- && truth_value_p (TREE_CODE (TREE_OPERAND (t, 0))))
+ && (truth_value_p (TREE_CODE (TREE_OPERAND (t, 0)))
+ || TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0)))
+ == BOOLEAN_TYPE))
t = TREE_OPERAND (t, 0);
/* For !x use x == 0. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 4ff8a10..103bf56 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2011-08-02 Kai Tietz <ktietz@redhat.com>
+
+ * gcc.dg/tree-ssa/forwprop-15.c: New testcase.
+
2011-08-01 Jason Merrill <jason@redhat.com>
PR c++/49932
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-15.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-15.c
new file mode 100644
index 0000000..43c6351
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-15.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-forwprop1" } */
+
+_Bool
+foo (_Bool a, _Bool b, _Bool c
+{
+ _Bool r1 = a == 0 & b != 0;
+ _Bool r2 = b != 0 & c == 0;
+ return (r1 == 0 & r2 == 0);
+}
+
+/* { dg-final { scan-tree-dump-times " == " 0 "forwprop1" } } */
+/* { dg-final { scan-tree-dump-times " != " 0 "forwprop1" } } */
+/* { dg-final { cleanup-tree-dump "forwprop1" } } */
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index 7cf420f..2a56b79 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -468,7 +468,9 @@ forward_propagate_into_comparison (gimple_stmt_iterator *gsi)
if (tmp)
{
gimple_assign_set_rhs_from_tree (gsi, tmp);
+ fold_stmt_inplace (stmt);
update_stmt (stmt);
+
if (TREE_CODE (rhs1) == SSA_NAME)
cfg_changed |= remove_prop_source_from_use (rhs1);
if (TREE_CODE (rhs2) == SSA_NAME)
@@ -2407,7 +2409,8 @@ ssa_forward_propagate_and_combine (void)
}
else if (TREE_CODE_CLASS (code) == tcc_comparison)
{
- forward_propagate_comparison (stmt);
+ if (forward_propagate_comparison (stmt))
+ cfg_changed = true;
gsi_next (&gsi);
}
else