diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-09-07 13:02:05 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-09-07 13:02:05 +0000 |
commit | 10a6edd69f6f6b33603c6b6808af2a0ca8d6b555 (patch) | |
tree | d7fdcaa9931bc56d88606ecb7ce549b79b8228e5 /gcc/tree-ssa-forwprop.c | |
parent | cd22a7968a89e465b934b7b2b9ff685a9652601b (diff) | |
download | gcc-10a6edd69f6f6b33603c6b6808af2a0ca8d6b555.tar.gz |
2011-09-07 Richard Guenther <rguenther@suse.de>
* tree-ssa-forwprop.c (forward_propagate_into_gimple_cond):
Canonicalize negated predicates by swapping edges.
(forward_propagate_into_cond): Likewise.
* gcc.dg/tree-ssa/forwprop-16.c: New testcase.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@178634 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-forwprop.c')
-rw-r--r-- | gcc/tree-ssa-forwprop.c | 42 |
1 files changed, 39 insertions, 3 deletions
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index ae37095d88e..6333ed6c148 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -534,6 +534,23 @@ forward_propagate_into_gimple_cond (gimple stmt) return (cfg_changed || is_gimple_min_invariant (tmp)) ? 2 : 1; } + /* Canonicalize _Bool == 0 and _Bool != 1 to _Bool != 0 by swapping edges. */ + if ((TREE_CODE (TREE_TYPE (rhs1)) == BOOLEAN_TYPE + || (INTEGRAL_TYPE_P (TREE_TYPE (rhs1)) + && TYPE_PRECISION (TREE_TYPE (rhs1)) == 1)) + && ((code == EQ_EXPR + && integer_zerop (rhs2)) + || (code == NE_EXPR + && integer_onep (rhs2)))) + { + basic_block bb = gimple_bb (stmt); + gimple_cond_set_code (stmt, NE_EXPR); + gimple_cond_set_rhs (stmt, build_zero_cst (TREE_TYPE (rhs1))); + EDGE_SUCC (bb, 0)->flags ^= (EDGE_TRUE_VALUE|EDGE_FALSE_VALUE); + EDGE_SUCC (bb, 1)->flags ^= (EDGE_TRUE_VALUE|EDGE_FALSE_VALUE); + return 1; + } + return 0; } @@ -548,6 +565,7 @@ forward_propagate_into_cond (gimple_stmt_iterator *gsi_p) gimple stmt = gsi_stmt (*gsi_p); tree tmp = NULL_TREE; tree cond = gimple_assign_rhs1 (stmt); + bool swap = false; /* We can do tree combining on SSA_NAME and comparison expressions. */ if (COMPARISON_CLASS_P (cond)) @@ -557,17 +575,27 @@ forward_propagate_into_cond (gimple_stmt_iterator *gsi_p) TREE_OPERAND (cond, 1)); else if (TREE_CODE (cond) == SSA_NAME) { + enum tree_code code; tree name = cond; gimple def_stmt = get_prop_source_stmt (name, true, NULL); if (!def_stmt || !can_propagate_from (def_stmt)) return 0; - if (TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt)) == tcc_comparison) + code = gimple_assign_rhs_code (def_stmt); + if (TREE_CODE_CLASS (code) == tcc_comparison) tmp = fold_build2_loc (gimple_location (def_stmt), - gimple_assign_rhs_code (def_stmt), + code, boolean_type_node, gimple_assign_rhs1 (def_stmt), gimple_assign_rhs2 (def_stmt)); + else if ((code == BIT_NOT_EXPR + && TYPE_PRECISION (TREE_TYPE (cond)) == 1) + || (code == BIT_XOR_EXPR + && integer_onep (gimple_assign_rhs2 (def_stmt)))) + { + tmp = gimple_assign_rhs1 (def_stmt); + swap = true; + } } if (tmp) @@ -586,7 +614,15 @@ forward_propagate_into_cond (gimple_stmt_iterator *gsi_p) else if (integer_zerop (tmp)) gimple_assign_set_rhs_from_tree (gsi_p, gimple_assign_rhs3 (stmt)); else - gimple_assign_set_rhs1 (stmt, unshare_expr (tmp)); + { + gimple_assign_set_rhs1 (stmt, unshare_expr (tmp)); + if (swap) + { + tree t = gimple_assign_rhs2 (stmt); + gimple_assign_set_rhs2 (stmt, gimple_assign_rhs3 (stmt)); + gimple_assign_set_rhs3 (stmt, t); + } + } stmt = gsi_stmt (*gsi_p); update_stmt (stmt); |