aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-forwprop.c
diff options
context:
space:
mode:
authorAndrew Pinski <apinski@cavium.com>2012-04-23 19:37:59 +0000
committerAndrew Pinski <pinskia@gcc.gnu.org>2012-04-23 12:37:59 -0700
commit24fc7360e5be54d73e677e6fe59339f58035e67a (patch)
treef95470c063ed8bc959cfc119b6f675da1143b815 /gcc/tree-ssa-forwprop.c
parente9d68de9c1f93c680f15be0589025f1828dd2996 (diff)
downloadgcc-24fc7360e5be54d73e677e6fe59339f58035e67a.zip
gcc-24fc7360e5be54d73e677e6fe59339f58035e67a.tar.gz
gcc-24fc7360e5be54d73e677e6fe59339f58035e67a.tar.bz2
tree-ssa-forwprop.c (simplify_bitwise_binary): Simplify (A & B) OP0 (C & B) to (A OP0) & B.
2012-04-23 Andrew Pinski <apinski@cavium.com> * tree-ssa-forwprop.c (simplify_bitwise_binary): Simplify (A & B) OP0 (C & B) to (A OP0) & B. 2012-04-23 Andrew Pinski <apinski@cavium.com> * gcc.dg/tree-ssa/forwprop-17.c: New testcase. From-SVN: r186721
Diffstat (limited to 'gcc/tree-ssa-forwprop.c')
-rw-r--r--gcc/tree-ssa-forwprop.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index 965f441..349272d 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -1886,6 +1886,54 @@ simplify_bitwise_binary (gimple_stmt_iterator *gsi)
return true;
}
+
+ /* Simplify (A & B) OP0 (C & B) to (A OP0 C) & B. */
+ if (def1_code == def2_code
+ && def1_code == BIT_AND_EXPR
+ && operand_equal_for_phi_arg_p (gimple_assign_rhs2 (def1),
+ gimple_assign_rhs2 (def2)))
+ {
+ tree b = gimple_assign_rhs2 (def1);
+ tree a = def1_arg1;
+ tree c = def2_arg1;
+ tree inner = fold_build2 (code, TREE_TYPE (arg2), a, c);
+ /* If A OP0 C (this usually means C is the same as A) is 0
+ then fold it down correctly. */
+ if (integer_zerop (inner))
+ {
+ gimple_assign_set_rhs_from_tree (gsi, inner);
+ update_stmt (stmt);
+ return true;
+ }
+ /* If A OP0 C (this usually means C is the same as A) is a ssa_name
+ then fold it down correctly. */
+ else if (TREE_CODE (inner) == SSA_NAME)
+ {
+ tree outer = fold_build2 (def1_code, TREE_TYPE (inner),
+ inner, b);
+ gimple_assign_set_rhs_from_tree (gsi, outer);
+ update_stmt (stmt);
+ return true;
+ }
+ else
+ {
+ gimple newop;
+ tree tem;
+ tem = create_tmp_reg (TREE_TYPE (arg2), NULL);
+ newop = gimple_build_assign_with_ops (code, tem, a, c);
+ tem = make_ssa_name (tem, newop);
+ gimple_assign_set_lhs (newop, tem);
+ gimple_set_location (newop, gimple_location (stmt));
+ /* Make sure to re-process the new stmt as it's walking upwards. */
+ gsi_insert_before (gsi, newop, GSI_NEW_STMT);
+ gimple_assign_set_rhs1 (stmt, tem);
+ gimple_assign_set_rhs2 (stmt, b);
+ gimple_assign_set_rhs_code (stmt, def1_code);
+ update_stmt (stmt);
+ return true;
+ }
+ }
+
/* (a | CST1) & CST2 -> (a & CST2) | (CST1 & CST2). */
if (code == BIT_AND_EXPR
&& def1_code == BIT_IOR_EXPR