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
This commit is contained in:
parent
b54819879e
commit
e25350118c
|
@ -1,3 +1,11 @@
|
|||
2016-11-23 Bin Cheng <bin.cheng@arm.com>
|
||||
|
||||
* 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 <bin.cheng@arm.com>
|
||||
|
||||
* fold-const.c (fold_cond_expr_with_comparison): Move simplification
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
68
gcc/match.pd
68
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))
|
||||
if (code != EQ_EXPR)
|
||||
{
|
||||
/* 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;
|
||||
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. */
|
||||
|
|
Loading…
Reference in New Issue