From 59c20dc74df24fa8e14ade6aecbfd4a1c6bbe30c Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 4 Aug 2015 13:51:50 +0000 Subject: [PATCH] gimple-fold.c (gimple_fold_stmt_to_constant_1): Canonicalize bool compares on RHS. 2015-08-04 Richard Biener * gimple-fold.c (gimple_fold_stmt_to_constant_1): Canonicalize bool compares on RHS. * match.pd: Add X ==/!= !X is false/true pattern. * gcc.dg/tree-ssa/ssa-ccp-38.c: New testcase. From-SVN: r226576 --- gcc/ChangeLog | 6 ++++ gcc/gimple-fold.c | 34 ++++++++++++++++++++-- gcc/match.pd | 5 ++++ gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-38.c | 13 +++++++++ 5 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-38.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cd017f47eb6..3706b6729a9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2015-08-04 Richard Biener + + * gimple-fold.c (gimple_fold_stmt_to_constant_1): Canonicalize + bool compares on RHS. + * match.pd: Add X ==/!= !X is false/true pattern. + 2015-08-04 Pawel Kupidura * config/aarch64/aarch64.c: Change inner loop statement cost diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index 6c53bac027b..1a70d8ff722 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -5012,10 +5012,8 @@ gimple_fold_stmt_to_constant_1 (gimple stmt, tree (*valueize) (tree), further propagation. */ if (subcode == POINTER_PLUS_EXPR) { - /* Handle binary operators that can appear in GIMPLE form. */ tree op0 = (*valueize) (gimple_assign_rhs1 (stmt)); tree op1 = (*valueize) (gimple_assign_rhs2 (stmt)); - if (TREE_CODE (op0) == ADDR_EXPR && TREE_CODE (op1) == INTEGER_CST) { @@ -5027,6 +5025,38 @@ gimple_fold_stmt_to_constant_1 (gimple stmt, tree (*valueize) (tree), unshare_expr (op0), off)); } } + /* Canonicalize bool != 0 and bool == 0 appearing after + valueization. While gimple_simplify handles this + it can get confused by the ~X == 1 -> X == 0 transform + which we cant reduce to a SSA name or a constant + (and we have no way to tell gimple_simplify to not + consider those transforms in the first place). */ + else if (subcode == EQ_EXPR + || subcode == NE_EXPR) + { + tree lhs = gimple_assign_lhs (stmt); + tree op0 = gimple_assign_rhs1 (stmt); + if (useless_type_conversion_p (TREE_TYPE (lhs), + TREE_TYPE (op0))) + { + tree op1 = (*valueize) (gimple_assign_rhs2 (stmt)); + op0 = (*valueize) (op0); + if (subcode == NE_EXPR) + { + if (integer_zerop (op1)) + return op0; + else if (integer_zerop (op0)) + return op1; + } + else + { + if (integer_onep (op1)) + return op0; + else if (integer_onep (op0)) + return op1; + } + } + } return NULL_TREE; case GIMPLE_TERNARY_RHS: diff --git a/gcc/match.pd b/gcc/match.pd index 913a1493b5d..3e9100e81f0 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -618,6 +618,11 @@ along with GCC; see the file COPYING3. If not see (simplify (op:c truth_valued_p@0 (logical_inverted_value @0)) { constant_boolean_node (true, type); })) +/* X ==/!= !X is false/true. */ +(for op (eq ne) + (simplify + (op:c truth_valued_p@0 (logical_inverted_value @0)) + { constant_boolean_node (op == NE_EXPR ? true : false, type); })) /* If arg1 and arg2 are booleans (or any single bit type) then try to simplify: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 69b511a849f..dc1262fdfbe 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2015-08-04 Richard Biener + + * gcc.dg/tree-ssa/ssa-ccp-38.c: New testcase. + 2015-08-04 H.J. Lu PR target/67110 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-38.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-38.c new file mode 100644 index 00000000000..e5fb813c5ff --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-38.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-ccp1" } */ + +int foo (_Bool x) +{ + _Bool t = 1; + _Bool xx = !x; + _Bool y = xx == t; + _Bool z = y == x; + return z ? 1 : 0; +} + +/* { dg-final { scan-tree-dump "return 0;" "ccp1" } } */