+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
(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)
&& (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)
(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)
+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
--- /dev/null
+// 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, [] {});
+}
+
--- /dev/null
+/* 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; }
--- /dev/null
+/* PR middle-end/78517 */
+/* { dg-do compile } */
+char a;
+int fn1() { return a == '[' ? a : 0; }