On Tue, Apr 24, 2012 at 08:05:35AM +0200, Richard Guenther wrote: > On Tue, Apr 24, 2012 at 1:01 AM, Jakub Jelinek <ja...@redhat.com> wrote: > I don't like using TYPE_MAX_VALUE in VRP - at least please use vrp_val_max. > For enums this can be not what you expect(?) > > Please consider adding a double_int_max_value (unsigned prec, bool sign) > and double_int_min_value.
So like this instead? 2012-04-24 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/53058 * double-int.h (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. --- gcc/double-int.h.jj 2012-04-19 11:09:13.000000000 +0200 +++ gcc/double-int.h 2012-04-24 08:42:42.655756406 +0200 @@ -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. @@ -280,6 +280,26 @@ double_int_equal_p (double_int cst1, dou return cst1.low == cst2.low && cst1.high == cst2.high; } +/* Returns a maximum value for signed or unsigned integer + of precision PREC. */ + +static inline 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. */ + +static inline 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); +} + /* Legacy interface with decomposed high/low parts. */ --- gcc/tree-vrp.c.jj 2012-04-23 11:11:21.000000000 +0200 +++ gcc/tree-vrp.c 2012-04-24 09:06:29.116624564 +0200 @@ -4565,6 +4565,7 @@ register_edge_assert_for_2 (tree name, e && 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, e 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); --- gcc/testsuite/gcc.c-torture/compile/pr53058.c.jj 2012-04-23 15:53:41.489982650 +0200 +++ gcc/testsuite/gcc.c-torture/compile/pr53058.c 2012-04-23 15:53:13.000000000 +0200 @@ -0,0 +1,12 @@ +/* PR tree-optimization/53058 */ + +int a, b, c; + +void +foo () +{ + c = b >> 16; + if (c > 32767) + c = 0; + a = b; +} Jakub