On Tue, Apr 24, 2012 at 10:33:58AM +0200, Richard Guenther wrote: > > So like this instead? > > Yes!
Unfortunately that didn't bootstrap, apparently double-int.h is included in gen* which aren't linked with double-int.o, and the inlines stay at -O0 or with -fkeep-inline-functions. Even guarding with #ifndef GENERATOR_FILE doesn't work, because gengtype is apparently built both with that and without. So this new version instead just prototypes them in double-int.h and defines in double-int.c. Still ok? 2012-04-25 Jakub Jelinek <ja...@redhat.com> 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. --- gcc/double-int.h.jj 2012-03-29 12:01:31.623648408 +0200 +++ gcc/double-int.h 2012-04-24 17:54:37.798945484 +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. @@ -242,6 +242,9 @@ double_int double_int_sext (double_int, 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 --- gcc/double-int.c.jj 2012-04-02 21:40:10.000000000 +0200 +++ gcc/double-int.c 2012-04-24 17:55:44.745723956 +0200 @@ -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. --- gcc/tree-vrp.c.jj 2012-04-24 07:59:58.142773712 +0200 +++ gcc/tree-vrp.c 2012-04-24 17:41:10.473562899 +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-24 17:41:10.475662886 +0200 +++ gcc/testsuite/gcc.c-torture/compile/pr53058.c 2012-04-24 17:41:10.475662886 +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