From 0ea62d936f1915759660b1a4e6ed124f73ac37ee Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 25 Apr 2012 13:35:38 +0200 Subject: [PATCH] re PR tree-optimization/53058 (Another ice in remove_range_assertions) PR tree-optimization/53058 * double-int.h (double_int_max_value, double_int_min_value): New prototypes. * double-int.c (double_int_max_value, double_int_min_value): New functions. * tree-vrp.c (register_edge_assert_for_2): Compare mask for LE_EXPR or GT_EXPR with double_int_max_value instead of double_int_mask. * gcc.c-torture/compile/pr53058.c: New test. From-SVN: r186816 --- gcc/ChangeLog | 11 +++++++++++ gcc/double-int.c | 22 +++++++++++++++++++++- gcc/double-int.h | 5 ++++- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.c-torture/compile/pr53058.c | 12 ++++++++++++ gcc/tree-vrp.c | 5 ++++- 6 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr53058.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3770d39..9edaf93 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2012-04-25 Jakub Jelinek + + PR tree-optimization/53058 + * double-int.h (double_int_max_value, double_int_min_value): New + prototypes. + * double-int.c (double_int_max_value, double_int_min_value): New + functions. + * tree-vrp.c (register_edge_assert_for_2): Compare mask + for LE_EXPR or GT_EXPR with double_int_max_value + instead of double_int_mask. + 2012-04-25 Richard Guenther * tree-vectorizer.h (vect_loop_versioning): Adjust prototype. diff --git a/gcc/double-int.c b/gcc/double-int.c index d0fde0e..3a51bd3 100644 --- a/gcc/double-int.c +++ b/gcc/double-int.c @@ -1,5 +1,5 @@ /* Operations with long integers. - Copyright (C) 2006, 2007, 2009, 2010 Free Software Foundation, Inc. + Copyright (C) 2006, 2007, 2009, 2010, 2012 Free Software Foundation, Inc. This file is part of GCC. @@ -616,6 +616,26 @@ double_int_mask (unsigned prec) return mask; } +/* Returns a maximum value for signed or unsigned integer + of precision PREC. */ + +double_int +double_int_max_value (unsigned int prec, bool uns) +{ + return double_int_mask (prec - (uns ? 0 : 1)); +} + +/* Returns a minimum value for signed or unsigned integer + of precision PREC. */ + +double_int +double_int_min_value (unsigned int prec, bool uns) +{ + if (uns) + return double_int_zero; + return double_int_lshift (double_int_one, prec - 1, prec, false); +} + /* Clears the bits of CST over the precision PREC. If UNS is false, the bits outside of the precision are set to the sign bit (i.e., the PREC-th one), otherwise they are set to zero. diff --git a/gcc/double-int.h b/gcc/double-int.h index 408ed92..78191cc 100644 --- a/gcc/double-int.h +++ b/gcc/double-int.h @@ -1,5 +1,5 @@ /* Operations with long integers. - Copyright (C) 2006, 2007, 2008, 2010 Free Software Foundation, Inc. + Copyright (C) 2006, 2007, 2008, 2010, 2012 Free Software Foundation, Inc. This file is part of GCC. @@ -242,6 +242,9 @@ double_int double_int_sext (double_int, unsigned); double_int double_int_zext (double_int, unsigned); double_int double_int_mask (unsigned); +double_int double_int_max_value (unsigned int, bool); +double_int double_int_min_value (unsigned int, bool); + #define ALL_ONES (~((unsigned HOST_WIDE_INT) 0)) /* The operands of the following comparison functions must be processed diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d72f93c..313015f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-04-25 Jakub Jelinek + + PR tree-optimization/53058 + * gcc.c-torture/compile/pr53058.c: New test. + 2012-04-25 Jan Hubicka PR middle-end/53088 diff --git a/gcc/testsuite/gcc.c-torture/compile/pr53058.c b/gcc/testsuite/gcc.c-torture/compile/pr53058.c new file mode 100644 index 0000000..90063c5 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr53058.c @@ -0,0 +1,12 @@ +/* PR tree-optimization/53058 */ + +int a, b, c; + +void +foo () +{ + c = b >> 16; + if (c > 32767) + c = 0; + a = b; +} diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 73b3bb4..9066096 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -4565,6 +4565,7 @@ register_edge_assert_for_2 (tree name, edge e, gimple_stmt_iterator bsi, && INTEGRAL_TYPE_P (TREE_TYPE (name2)) && IN_RANGE (tree_low_cst (cst2, 1), 1, prec - 1) && prec <= 2 * HOST_BITS_PER_WIDE_INT + && prec == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (val))) && live_on_edge (e, name2) && !has_single_use (name2)) { @@ -4598,8 +4599,10 @@ register_edge_assert_for_2 (tree name, edge e, gimple_stmt_iterator bsi, new_val = val2; else { + double_int maxval + = double_int_max_value (prec, TYPE_UNSIGNED (TREE_TYPE (val))); mask = double_int_ior (tree_to_double_int (val2), mask); - if (double_int_minus_one_p (double_int_sext (mask, prec))) + if (double_int_equal_p (mask, maxval)) new_val = NULL_TREE; else new_val = double_int_to_tree (TREE_TYPE (val2), mask); -- 2.7.4