From e25350118c44492fed4ea9f168d0b8596d3d03fc Mon Sep 17 00:00:00 2001 From: Bin Cheng Date: Wed, 23 Nov 2016 12:47:31 +0000 Subject: [PATCH] fold-const.c (fold_cond_expr_with_comparison): Move simplification for A == C1 ? A : C2 to below. * fold-const.c (fold_cond_expr_with_comparison): Move simplification for A == C1 ? A : C2 to below. * match.pd: Move from above to here: (cond (eq (convert1? x) c1) (convert2? x) c2) -> (cond (eq x c1) c1 c2). From-SVN: r242751 --- gcc/ChangeLog | 8 ++++++ gcc/fold-const.c | 13 --------- gcc/match.pd | 68 +++++++++++++++++++++++++++++------------------- 3 files changed, 49 insertions(+), 40 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a330d7a51a4..61af4e2a066 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2016-11-23 Bin Cheng + + * fold-const.c (fold_cond_expr_with_comparison): Move simplification + for A == C1 ? A : C2 to below. + * match.pd: Move from above to here: + (cond (eq (convert1? x) c1) (convert2? x) c2) + -> (cond (eq x c1) c1 c2). + 2016-11-23 Bin Cheng * fold-const.c (fold_cond_expr_with_comparison): Move simplification diff --git a/gcc/fold-const.c b/gcc/fold-const.c index cbfbc24222c..6517188c4c6 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -5210,19 +5210,6 @@ fold_cond_expr_with_comparison (location_t loc, tree type, } } - /* If this is A == C1 ? A : C2 with C1 and C2 constant integers, - we simplify it into A == C1 ? C1 : C2. */ - - if (comp_code == EQ_EXPR - && INTEGRAL_TYPE_P (type) - && TREE_CODE (arg01) == INTEGER_CST - && TREE_CODE (arg1) != INTEGER_CST - && TREE_CODE (arg2) == INTEGER_CST) - { - arg1 = fold_convert_loc (loc, type, arg01); - return fold_build3_loc (loc, COND_EXPR, type, arg0, arg1, arg2); - } - return NULL_TREE; } diff --git a/gcc/match.pd b/gcc/match.pd index 2599d27c528..e3f85140e1e 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -1955,15 +1955,21 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* Simplification moved from fold_cond_expr_with_comparison. It may also be extended. */ -/* (cond (cmp (convert1? x) c1) (convert2? x) c2) -> (minmax (x c)) if: +/* This pattern implements two kinds simplification: + + Case 1) + (cond (cmp (convert1? x) c1) (convert2? x) c2) -> (minmax (x c)) if: 1) Conversions are type widening from smaller type. 2) Const c1 equals to c2 after canonicalizing comparison. 3) Comparison has tree code LT, LE, GT or GE. This specific pattern is needed when (cmp (convert x) c) may not be simplified by comparison patterns because of multiple uses of x. It also makes sense here because simplifying across multiple - referred var is always benefitial for complicated cases. */ -(for cmp (lt le gt ge) + referred var is always benefitial for complicated cases. + + Case 2) + (cond (eq (convert1? x) c1) (convert2? x) c2) -> (cond (eq x c1) c1 c2). */ +(for cmp (lt le gt ge eq) (simplify (cond (cmp@0 (convert1? @1) INTEGER_CST@3) (convert2? @1) INTEGER_CST@2) (with @@ -1982,37 +1988,45 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && (TYPE_UNSIGNED (from_type) || TYPE_SIGN (c2_type) == TYPE_SIGN (from_type))))) { - if (wi::to_widest (@3) == (wi::to_widest (@2) - 1)) - { - /* X <= Y - 1 equals to X < Y. */ - if (cmp_code == LE_EXPR) - code = LT_EXPR; - /* X > Y - 1 equals to X >= Y. */ - if (cmp_code == GT_EXPR) - code = GE_EXPR; - } - if (wi::to_widest (@3) == (wi::to_widest (@2) + 1)) - { - /* X < Y + 1 equals to X <= Y. */ - if (cmp_code == LT_EXPR) - code = LE_EXPR; - /* X >= Y + 1 equals to X > Y. */ - if (cmp_code == GE_EXPR) - code = GT_EXPR; - } - if (code != cmp_code || wi::to_widest (@2) == wi::to_widest (@3)) + if (code != EQ_EXPR) { - if (cmp_code == LT_EXPR || cmp_code == LE_EXPR) - code = MIN_EXPR; - if (cmp_code == GT_EXPR || cmp_code == GE_EXPR) - code = MAX_EXPR; + if (wi::to_widest (@3) == (wi::to_widest (@2) - 1)) + { + /* X <= Y - 1 equals to X < Y. */ + if (cmp_code == LE_EXPR) + code = LT_EXPR; + /* X > Y - 1 equals to X >= Y. */ + if (cmp_code == GT_EXPR) + code = GE_EXPR; + } + if (wi::to_widest (@3) == (wi::to_widest (@2) + 1)) + { + /* X < Y + 1 equals to X <= Y. */ + if (cmp_code == LT_EXPR) + code = LE_EXPR; + /* X >= Y + 1 equals to X > Y. */ + if (cmp_code == GE_EXPR) + code = GT_EXPR; + } + if (code != cmp_code || wi::to_widest (@2) == wi::to_widest (@3)) + { + if (cmp_code == LT_EXPR || cmp_code == LE_EXPR) + code = MIN_EXPR; + if (cmp_code == GT_EXPR || cmp_code == GE_EXPR) + code = MAX_EXPR; + } } + /* Can do A == C1 ? A : C2 -> A == C1 ? C1 : C2? */ + else if (!int_fits_type_p (@3, from_type)) + code = ERROR_MARK; } } (if (code == MAX_EXPR) (convert (max @1 (convert:from_type @2))) (if (code == MIN_EXPR) - (convert (min @1 (convert:from_type @2)))))))) + (convert (min @1 (convert:from_type @2))) + (if (code == EQ_EXPR) + (cond (cmp @1 (convert:from_type @3)) (convert:from_type @3) @2))))))) (for cnd (cond vec_cond) /* A ? B : (A ? X : C) -> A ? B : C. */ -- 2.30.2