aboutsummaryrefslogtreecommitdiff
path: root/gcc/match.pd
diff options
context:
space:
mode:
authorBin Cheng <bin.cheng@arm.com>2016-11-23 12:47:31 +0000
committerBin Cheng <amker@gcc.gnu.org>2016-11-23 12:47:31 +0000
commite25350118c44492fed4ea9f168d0b8596d3d03fc (patch)
treed12ecd7ecb082a700239231e770351f33b176773 /gcc/match.pd
parentb54819879e0518b3f1acc5242f9c1d86dd1b9e3c (diff)
downloadgcc-e25350118c44492fed4ea9f168d0b8596d3d03fc.zip
gcc-e25350118c44492fed4ea9f168d0b8596d3d03fc.tar.gz
gcc-e25350118c44492fed4ea9f168d0b8596d3d03fc.tar.bz2
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
Diffstat (limited to 'gcc/match.pd')
-rw-r--r--gcc/match.pd68
1 files changed, 41 insertions, 27 deletions
diff --git a/gcc/match.pd b/gcc/match.pd
index 2599d27..e3f8514 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. */