From 819ec64c36cc83cf76a2820774b2baf0d73f45a2 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 30 Jul 2015 13:11:41 +0000 Subject: [PATCH] gimple-fold.c (fold_gimple_assign): Only fold !tcc_comparison binaries. 2015-07-30 Richard Biener * gimple-fold.c (fold_gimple_assign): Only fold !tcc_comparison binaries. Move X == 0, X == 1, X != 0, and X != 1 canonicalization ... (fold_stmt_1): ... here and work on GIMPLE directly. Remove redundant operand canonicalization. From-SVN: r226404 --- gcc/ChangeLog | 7 +++ gcc/gimple-fold.c | 118 +++++++++++++++++++++------------------------- 2 files changed, 60 insertions(+), 65 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 49983dc9cb9..be3a66e0500 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2015-07-30 Richard Biener + + * gimple-fold.c (fold_gimple_assign): Only fold !tcc_comparison + binaries. Move X == 0, X == 1, X != 0, and X != 1 canonicalization ... + (fold_stmt_1): ... here and work on GIMPLE directly. Remove + redundant operand canonicalization. + 2015-07-30 David Sherwood * config/aarch64/aarch64-simd.md (aarch64_ext): Replace call to diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index 789fd227d13..94a59676778 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -413,60 +413,20 @@ fold_gimple_assign (gimple_stmt_iterator *si) break; case GIMPLE_BINARY_RHS: - /* Try to canonicalize for boolean-typed X the comparisons - X == 0, X == 1, X != 0, and X != 1. */ - 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); + if (TREE_CODE_CLASS (subcode) != tcc_comparison) + { + result = fold_binary_loc (loc, subcode, + TREE_TYPE (gimple_assign_lhs (stmt)), + gimple_assign_rhs1 (stmt), + gimple_assign_rhs2 (stmt)); - /* 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)) + if (result) { - 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)); - + STRIP_USELESS_TYPE_CONVERSION (result); + if (valid_gimple_rhs_p (result)) + return result; } } - - if (!result) - result = fold_binary_loc (loc, subcode, - TREE_TYPE (gimple_assign_lhs (stmt)), - gimple_assign_rhs1 (stmt), - gimple_assign_rhs2 (stmt)); - - if (result) - { - STRIP_USELESS_TYPE_CONVERSION (result); - if (valid_gimple_rhs_p (result)) - return result; - } break; case GIMPLE_TERNARY_RHS: @@ -3653,23 +3613,51 @@ fold_stmt_1 (gimple_stmt_iterator *gsi, bool inplace, tree (*valueize) (tree)) { case GIMPLE_ASSIGN: { - unsigned old_num_ops = gimple_num_ops (stmt); - enum tree_code subcode = gimple_assign_rhs_code (stmt); - tree lhs = gimple_assign_lhs (stmt); - tree new_rhs; - /* First canonicalize operand order. This avoids building new - trees if this is the only thing fold would later do. */ - if ((commutative_tree_code (subcode) - || commutative_ternary_tree_code (subcode)) - && tree_swap_operands_p (gimple_assign_rhs1 (stmt), - gimple_assign_rhs2 (stmt), false)) + /* Try to canonicalize for boolean-typed X the comparisons + X == 0, X == 1, X != 0, and X != 1. */ + if (gimple_assign_rhs_code (stmt) == EQ_EXPR + || gimple_assign_rhs_code (stmt) == NE_EXPR) { - tree tem = gimple_assign_rhs1 (stmt); - gimple_assign_set_rhs1 (stmt, gimple_assign_rhs2 (stmt)); - gimple_assign_set_rhs2 (stmt, tem); - changed = true; + 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) + gimple_assign_set_rhs_with_ops (gsi, TREE_CODE (op1), op1); + /* Only for one-bit precision typed X the transformation + !X -> ~X is valied. */ + else if (TYPE_PRECISION (type) == 1) + gimple_assign_set_rhs_with_ops (gsi, BIT_NOT_EXPR, op1); + /* Otherwise we use !X -> X ^ 1. */ + else + gimple_assign_set_rhs_with_ops (gsi, BIT_XOR_EXPR, op1, + build_int_cst (type, 1)); + changed = true; + break; + } } - new_rhs = fold_gimple_assign (gsi); + + unsigned old_num_ops = gimple_num_ops (stmt); + tree lhs = gimple_assign_lhs (stmt); + tree new_rhs = fold_gimple_assign (gsi); if (new_rhs && !useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (new_rhs)))