diff options
author | Bin Cheng <bin.cheng@arm.com> | 2016-11-23 12:44:08 +0000 |
---|---|---|
committer | Bin Cheng <amker@gcc.gnu.org> | 2016-11-23 12:44:08 +0000 |
commit | b54819879e0518b3f1acc5242f9c1d86dd1b9e3c (patch) | |
tree | db5d291195258e1f26c23a15aa79a6d86dbc1de4 /gcc/fold-const.c | |
parent | b8d89b03db5f212919e4571671ebb4f5f8b1e19d (diff) | |
download | gcc-b54819879e0518b3f1acc5242f9c1d86dd1b9e3c.zip gcc-b54819879e0518b3f1acc5242f9c1d86dd1b9e3c.tar.gz gcc-b54819879e0518b3f1acc5242f9c1d86dd1b9e3c.tar.bz2 |
fold-const.c (fold_cond_expr_with_comparison): Move simplification for A cmp C1 ? A : C2 to below, also simplify remaining code.
* fold-const.c (fold_cond_expr_with_comparison): Move simplification
for A cmp C1 ? A : C2 to below, also simplify remaining code.
* match.pd: Move and extend simplification from above to here:
(cond (cmp (convert1? x) c1) (convert2? x) c2) -> (minmax (x c)).
* tree-if-conv.c (ifcvt_follow_ssa_use_edges): New func.
(predicate_scalar_phi): Call fold_stmt using the new valueize func.
gcc/testsuite
* gcc.dg/fold-cond_expr-1.c: New test.
* gcc.dg/fold-condcmpconv-1.c: New test.
* gcc.dg/fold-condcmpconv-2.c: New test.
From-SVN: r242750
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r-- | gcc/fold-const.c | 95 |
1 files changed, 9 insertions, 86 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index a0055c4..cbfbc24 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -5210,95 +5210,18 @@ fold_cond_expr_with_comparison (location_t loc, tree type, } } - /* If this is A op C1 ? A : C2 with C1 and C2 constant integers, - we might still be able to simplify this. For example, - if C1 is one less or one more than C2, this might have started - out as a MIN or MAX and been transformed by this function. - Only good for INTEGER_TYPEs, because we need TYPE_MAX_VALUE. */ + /* If this is A == C1 ? A : C2 with C1 and C2 constant integers, + we simplify it into A == C1 ? C1 : C2. */ - if (INTEGRAL_TYPE_P (type) + if (comp_code == EQ_EXPR + && INTEGRAL_TYPE_P (type) && TREE_CODE (arg01) == INTEGER_CST + && TREE_CODE (arg1) != INTEGER_CST && TREE_CODE (arg2) == INTEGER_CST) - switch (comp_code) - { - case EQ_EXPR: - if (TREE_CODE (arg1) == INTEGER_CST) - break; - /* We can replace A with C1 in this case. */ - arg1 = fold_convert_loc (loc, type, arg01); - return fold_build3_loc (loc, COND_EXPR, type, arg0, arg1, arg2); - - case LT_EXPR: - /* If C1 is C2 + 1, this is min(A, C2), but use ARG00's type for - MIN_EXPR, to preserve the signedness of the comparison. */ - if (! operand_equal_p (arg2, TYPE_MAX_VALUE (type), - OEP_ONLY_CONST) - && operand_equal_p (arg01, - const_binop (PLUS_EXPR, arg2, - build_int_cst (type, 1)), - OEP_ONLY_CONST)) - { - tem = fold_build2_loc (loc, MIN_EXPR, TREE_TYPE (arg00), arg00, - fold_convert_loc (loc, TREE_TYPE (arg00), - arg2)); - return fold_convert_loc (loc, type, tem); - } - break; - - case LE_EXPR: - /* If C1 is C2 - 1, this is min(A, C2), with the same care - as above. */ - if (! operand_equal_p (arg2, TYPE_MIN_VALUE (type), - OEP_ONLY_CONST) - && operand_equal_p (arg01, - const_binop (MINUS_EXPR, arg2, - build_int_cst (type, 1)), - OEP_ONLY_CONST)) - { - tem = fold_build2_loc (loc, MIN_EXPR, TREE_TYPE (arg00), arg00, - fold_convert_loc (loc, TREE_TYPE (arg00), - arg2)); - return fold_convert_loc (loc, type, tem); - } - break; - - case GT_EXPR: - /* If C1 is C2 - 1, this is max(A, C2), but use ARG00's type for - MAX_EXPR, to preserve the signedness of the comparison. */ - if (! operand_equal_p (arg2, TYPE_MIN_VALUE (type), - OEP_ONLY_CONST) - && operand_equal_p (arg01, - const_binop (MINUS_EXPR, arg2, - build_int_cst (type, 1)), - OEP_ONLY_CONST)) - { - tem = fold_build2_loc (loc, MAX_EXPR, TREE_TYPE (arg00), arg00, - fold_convert_loc (loc, TREE_TYPE (arg00), - arg2)); - return fold_convert_loc (loc, type, tem); - } - break; - - case GE_EXPR: - /* If C1 is C2 + 1, this is max(A, C2), with the same care as above. */ - if (! operand_equal_p (arg2, TYPE_MAX_VALUE (type), - OEP_ONLY_CONST) - && operand_equal_p (arg01, - const_binop (PLUS_EXPR, arg2, - build_int_cst (type, 1)), - OEP_ONLY_CONST)) - { - tem = fold_build2_loc (loc, MAX_EXPR, TREE_TYPE (arg00), arg00, - fold_convert_loc (loc, TREE_TYPE (arg00), - arg2)); - return fold_convert_loc (loc, type, tem); - } - break; - case NE_EXPR: - break; - default: - gcc_unreachable (); - } + { + arg1 = fold_convert_loc (loc, type, arg01); + return fold_build3_loc (loc, COND_EXPR, type, arg0, arg1, arg2); + } return NULL_TREE; } |