From a5a96d9fbea25a9b83d2ea5075b7b73044ebaa7b Mon Sep 17 00:00:00 2001 From: amker Date: Fri, 25 Nov 2016 11:45:43 +0000 Subject: [PATCH] PR middle-end/78507 PR middle-end/78510 PR middle-end/78517 * match.pd ((cond (cmp (convert1? @1) @3) (convert2? @1) @2)): Use cmp directly, rather than cmp_code. Initialize code to ERROR_MARK and set it to result code if transformation is valid. Use code EQ directly in last simplification case. gcc/testsuite PR middle-end/78507 PR middle-end/78510 PR middle-end/78517 * g++.dg/torture/pr78507.C: New test. * gcc.dg/torture/pr78510.c: New test. * gcc.dg/torture/pr78517.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@242874 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 10 ++++++ gcc/match.pd | 30 +++++++++--------- gcc/testsuite/ChangeLog | 9 ++++++ gcc/testsuite/g++.dg/torture/pr78507.C | 57 ++++++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/torture/pr78510.c | 19 ++++++++++++ gcc/testsuite/gcc.dg/torture/pr78517.c | 4 +++ 6 files changed, 115 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/g++.dg/torture/pr78507.C create mode 100644 gcc/testsuite/gcc.dg/torture/pr78510.c create mode 100644 gcc/testsuite/gcc.dg/torture/pr78517.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0c0fce9b7d0..18d3b3fa8c1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2016-11-25 Bin Cheng + + PR middle-end/78507 + PR middle-end/78510 + PR middle-end/78517 + * match.pd ((cond (cmp (convert1? @1) @3) (convert2? @1) @2)): Use + cmp directly, rather than cmp_code. Initialize code to ERROR_MARK + and set it to result code if transformation is valid. Use code EQ + directly in last simplification case. + 2016-11-25 Richard Biener * gimple-fold.c (fold_stmt_1): Check may_propagate_copy diff --git a/gcc/match.pd b/gcc/match.pd index 3aa27fae746..2d4e0197c19 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -1971,14 +1971,15 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (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) + (cond (cmp (convert1? @1) INTEGER_CST@3) (convert2? @1) INTEGER_CST@2) (with { tree from_type = TREE_TYPE (@1); tree c1_type = TREE_TYPE (@3), c2_type = TREE_TYPE (@2); - enum tree_code code = TREE_CODE (@0), cmp_code = TREE_CODE (@0); + enum tree_code code = ERROR_MARK; - if (int_fits_type_p (@2, from_type) + if (INTEGRAL_TYPE_P (from_type) + && int_fits_type_p (@2, from_type) && (types_match (c1_type, from_type) || (TYPE_PRECISION (c1_type) > TYPE_PRECISION (from_type) && (TYPE_UNSIGNED (from_type) @@ -1988,37 +1989,38 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && (TYPE_UNSIGNED (from_type) || TYPE_SIGN (c2_type) == TYPE_SIGN (from_type))))) { - if (code != EQ_EXPR) + if (cmp != EQ_EXPR) { if (wi::to_widest (@3) == (wi::to_widest (@2) - 1)) { /* X <= Y - 1 equals to X < Y. */ - if (cmp_code == LE_EXPR) + if (cmp == LE_EXPR) code = LT_EXPR; /* X > Y - 1 equals to X >= Y. */ - if (cmp_code == GT_EXPR) + if (cmp == 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) + if (cmp == LT_EXPR) code = LE_EXPR; /* X >= Y + 1 equals to X > Y. */ - if (cmp_code == GE_EXPR) + if (cmp == GE_EXPR) code = GT_EXPR; } - if (code != cmp_code || wi::to_widest (@2) == wi::to_widest (@3)) + if (code != ERROR_MARK + || wi::to_widest (@2) == wi::to_widest (@3)) { - if (cmp_code == LT_EXPR || cmp_code == LE_EXPR) + if (cmp == LT_EXPR || cmp == LE_EXPR) code = MIN_EXPR; - if (cmp_code == GT_EXPR || cmp_code == GE_EXPR) + if (cmp == GT_EXPR || cmp == 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; + else if (int_fits_type_p (@3, from_type)) + code = EQ_EXPR; } } (if (code == MAX_EXPR) @@ -2026,7 +2028,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if (code == MIN_EXPR) (convert (min @1 (convert @2))) (if (code == EQ_EXPR) - (convert (cond (cmp @1 (convert @3)) + (convert (cond (eq @1 (convert @3)) (convert:from_type @3) (convert:from_type @2))))))))) (for cnd (cond vec_cond) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7072950f236..fe43b97635f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2016-11-25 Bin Cheng + + PR middle-end/78507 + PR middle-end/78510 + PR middle-end/78517 + * g++.dg/torture/pr78507.C: New test. + * gcc.dg/torture/pr78510.c: New test. + * gcc.dg/torture/pr78517.c: New test. + 2016-11-24 Richard Biener PR tree-optimization/78343 diff --git a/gcc/testsuite/g++.dg/torture/pr78507.C b/gcc/testsuite/g++.dg/torture/pr78507.C new file mode 100644 index 00000000000..9691cf9bd7a --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr78507.C @@ -0,0 +1,57 @@ +// PR middle-end/78507 +// { dg-do compile } +struct A { + template + int operator()(_Iterator1, _Iterator2); +}; +struct B { + template + static _BI2 __copy_move_b(_BI1 p1, _BI2 p2) { + _BI1 a; + long b = p1 - a; + for (; b > 0; --b) + *--p2 = *--p1; + } +}; +template +void __copy_move_backward_a(_BI1 p1, _BI2 p2) { + B::__copy_move_b(p1, p2); +} +template +void __copy_move_backward_a2(_BI1 p1, _BI2 p2) { + __copy_move_backward_a<0>(p1, p2); +} +template void move_backward(_BI1 p1, _BI2 p2) { + __copy_move_backward_a2<0>(p1, p2); +} +template +void __insertion_sort(_RandomAccessIterator, _Compare p2) { + for (_RandomAccessIterator c;; ++c) + if (p2(0, 0)) + move_backward(c, c + 1); +} +template +void __final_insertion_sort(_RandomAccessIterator, _Compare p2) { + _RandomAccessIterator d; + __insertion_sort(d, p2); +} +template +void __sort(_RandomAccessIterator p1, _Compare p2) { + __final_insertion_sort(p1, p2); +} +template +void sort(_RandomAccessIterator, _RandomAccessIterator p2, _Compare) { + A e; + __sort(p2, e); +} +struct C { + struct D { + int DwarfRegNum; + }; + int parseRegisterLiveOutMask() const; +}; +int C::parseRegisterLiveOutMask() const { + D f, g; + sort(&f, &g, [] {}); +} + diff --git a/gcc/testsuite/gcc.dg/torture/pr78510.c b/gcc/testsuite/gcc.dg/torture/pr78510.c new file mode 100644 index 00000000000..8d0ab5fa3e3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr78510.c @@ -0,0 +1,19 @@ +/* PR middle-end/78510 */ +/* { dg-do compile } */ +int a, b, c, e, f; +char d; +short g, h; +char fn1(int p1) { + for (;;) { + h = p1 << 2; + int i = h; + g = i > 32767 >> 13 ? i : i << 3; + f = a ?: c; + if (e) + return d; + } +} + +static int fn2() { fn1(0 || b); } + +int main() { fn2(); return 0; } diff --git a/gcc/testsuite/gcc.dg/torture/pr78517.c b/gcc/testsuite/gcc.dg/torture/pr78517.c new file mode 100644 index 00000000000..475bce7b979 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr78517.c @@ -0,0 +1,4 @@ +/* PR middle-end/78517 */ +/* { dg-do compile } */ +char a; +int fn1() { return a == '[' ? a : 0; } -- 2.11.4.GIT