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:
Bin Cheng 2016-11-23 12:47:31 +00:00 committed by Bin Cheng
parent b54819879e
commit e25350118c
3 changed files with 49 additions and 40 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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. */