Commit ae22bc5d by Bin Cheng Committed by Bin Cheng

re PR middle-end/78507 (ICE: tree check: expected integer_type or enumeral_type…

re PR middle-end/78507 (ICE: tree check: expected integer_type or enumeral_type or boolean_type or real_type or fixed_point_type, have pointer_type in int_fits_type_p, at tree.c:9153)

	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
parent 1af928db
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> 2016-11-25 Richard Biener <rguenther@suse.de>
* gimple-fold.c (fold_stmt_1): Check may_propagate_copy * gimple-fold.c (fold_stmt_1): Check may_propagate_copy
...@@ -1971,14 +1971,15 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) ...@@ -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). */ (cond (eq (convert1? x) c1) (convert2? x) c2) -> (cond (eq x c1) c1 c2). */
(for cmp (lt le gt ge eq) (for cmp (lt le gt ge eq)
(simplify (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 (with
{ {
tree from_type = TREE_TYPE (@1); tree from_type = TREE_TYPE (@1);
tree c1_type = TREE_TYPE (@3), c2_type = TREE_TYPE (@2); 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) && (types_match (c1_type, from_type)
|| (TYPE_PRECISION (c1_type) > TYPE_PRECISION (from_type) || (TYPE_PRECISION (c1_type) > TYPE_PRECISION (from_type)
&& (TYPE_UNSIGNED (from_type) && (TYPE_UNSIGNED (from_type)
...@@ -1988,37 +1989,38 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) ...@@ -1988,37 +1989,38 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
&& (TYPE_UNSIGNED (from_type) && (TYPE_UNSIGNED (from_type)
|| TYPE_SIGN (c2_type) == TYPE_SIGN (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)) if (wi::to_widest (@3) == (wi::to_widest (@2) - 1))
{ {
/* X <= Y - 1 equals to X < Y. */ /* X <= Y - 1 equals to X < Y. */
if (cmp_code == LE_EXPR) if (cmp == LE_EXPR)
code = LT_EXPR; code = LT_EXPR;
/* X > Y - 1 equals to X >= Y. */ /* X > Y - 1 equals to X >= Y. */
if (cmp_code == GT_EXPR) if (cmp == GT_EXPR)
code = GE_EXPR; code = GE_EXPR;
} }
if (wi::to_widest (@3) == (wi::to_widest (@2) + 1)) if (wi::to_widest (@3) == (wi::to_widest (@2) + 1))
{ {
/* X < Y + 1 equals to X <= Y. */ /* X < Y + 1 equals to X <= Y. */
if (cmp_code == LT_EXPR) if (cmp == LT_EXPR)
code = LE_EXPR; code = LE_EXPR;
/* X >= Y + 1 equals to X > Y. */ /* X >= Y + 1 equals to X > Y. */
if (cmp_code == GE_EXPR) if (cmp == GE_EXPR)
code = GT_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; code = MIN_EXPR;
if (cmp_code == GT_EXPR || cmp_code == GE_EXPR) if (cmp == GT_EXPR || cmp == GE_EXPR)
code = MAX_EXPR; code = MAX_EXPR;
} }
} }
/* Can do A == C1 ? A : C2 -> A == C1 ? C1 : C2? */ /* Can do A == C1 ? A : C2 -> A == C1 ? C1 : C2? */
else if (!int_fits_type_p (@3, from_type)) else if (int_fits_type_p (@3, from_type))
code = ERROR_MARK; code = EQ_EXPR;
} }
} }
(if (code == MAX_EXPR) (if (code == MAX_EXPR)
...@@ -2026,7 +2028,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) ...@@ -2026,7 +2028,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(if (code == MIN_EXPR) (if (code == MIN_EXPR)
(convert (min @1 (convert @2))) (convert (min @1 (convert @2)))
(if (code == EQ_EXPR) (if (code == EQ_EXPR)
(convert (cond (cmp @1 (convert @3)) (convert (cond (eq @1 (convert @3))
(convert:from_type @3) (convert:from_type @2))))))))) (convert:from_type @3) (convert:from_type @2)))))))))
(for cnd (cond vec_cond) (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> 2016-11-24 Richard Biener <rguenther@suse.de>
PR tree-optimization/78343 PR tree-optimization/78343
......
// 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, [] {});
}
/* 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; }
/* PR middle-end/78517 */
/* { dg-do compile } */
char a;
int fn1() { return a == '[' ? a : 0; }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment