re PR middle-end/78507 (ICE: tree check: expected integer_type or enumeral_type or...
authorBin Cheng <bin.cheng@arm.com>
Fri, 25 Nov 2016 11:45:43 +0000 (11:45 +0000)
committerBin Cheng <amker@gcc.gnu.org>
Fri, 25 Nov 2016 11:45:43 +0000 (11:45 +0000)
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.

From-SVN: r242874

gcc/ChangeLog
gcc/match.pd
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr78507.C [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr78510.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr78517.c [new file with mode: 0644]

index 0c0fce9..18d3b3f 100644 (file)
@@ -1,3 +1,13 @@
+2016-11-25  Bin Cheng  <bin.cheng@arm.com>
+
+       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  <rguenther@suse.de>
 
        * gimple-fold.c (fold_stmt_1): Check may_propagate_copy
index 3aa27fa..2d4e019 100644 (file)
@@ -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)
index 7072950..fe43b97 100644 (file)
@@ -1,3 +1,12 @@
+2016-11-25  Bin Cheng  <bin.cheng@arm.com>
+
+       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  <rguenther@suse.de>
 
        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 (file)
index 0000000..9691cf9
--- /dev/null
@@ -0,0 +1,57 @@
+// PR middle-end/78507
+// { dg-do compile }
+struct A {
+  template <typename _Iterator1, typename _Iterator2>
+  int operator()(_Iterator1, _Iterator2);
+};
+struct B {
+  template <typename _BI1, typename _BI2>
+  static _BI2 __copy_move_b(_BI1 p1, _BI2 p2) {
+    _BI1 a;
+    long b = p1 - a;
+    for (; b > 0; --b)
+      *--p2 = *--p1;
+  }
+};
+template <int, typename _BI1, typename _BI2>
+void __copy_move_backward_a(_BI1 p1, _BI2 p2) {
+  B::__copy_move_b(p1, p2);
+}
+template <int, typename _BI1, typename _BI2>
+void __copy_move_backward_a2(_BI1 p1, _BI2 p2) {
+  __copy_move_backward_a<0>(p1, p2);
+}
+template <typename _BI1, typename _BI2> void move_backward(_BI1 p1, _BI2 p2) {
+  __copy_move_backward_a2<0>(p1, p2);
+}
+template <typename _RandomAccessIterator, typename _Compare>
+void __insertion_sort(_RandomAccessIterator, _Compare p2) {
+  for (_RandomAccessIterator c;; ++c)
+    if (p2(0, 0))
+      move_backward(c, c + 1);
+}
+template <typename _RandomAccessIterator, typename _Compare>
+void __final_insertion_sort(_RandomAccessIterator, _Compare p2) {
+  _RandomAccessIterator d;
+  __insertion_sort(d, p2);
+}
+template <typename _RandomAccessIterator, typename _Compare>
+void __sort(_RandomAccessIterator p1, _Compare p2) {
+  __final_insertion_sort(p1, p2);
+}
+template <typename _RandomAccessIterator, typename _Compare>
+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 (file)
index 0000000..8d0ab5f
--- /dev/null
@@ -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 (file)
index 0000000..475bce7
--- /dev/null
@@ -0,0 +1,4 @@
+/* PR middle-end/78517 */
+/* { dg-do compile } */
+char a;
+int fn1() { return a == '[' ? a : 0; }