From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 28508 invoked by alias); 11 Apr 2011 11:17:55 -0000 Received: (qmail 28491 invoked by uid 22791); 11 Apr 2011 11:17:53 -0000 X-SWARE-Spam-Status: No, hits=-3.3 required=5.0 tests=AWL,BAYES_00,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from cantor2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 11 Apr 2011 11:17:44 +0000 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.221.2]) by mx2.suse.de (Postfix) with ESMTP id 954E3867E2 for ; Mon, 11 Apr 2011 13:17:42 +0200 (CEST) Date: Mon, 11 Apr 2011 11:17:00 -0000 From: Richard Guenther To: gcc-patches@gcc.gnu.org Subject: [PATCH] Remove VRPs use of TYPE_MIN/MAX_VALUE Message-ID: User-Agent: Alpine 2.00 (LNX 1167 2008-08-23) MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2011-04/txt/msg00741.txt.bz2 The middle-end treats conversions between integral types that differ in TYPE_MIN/MAX_VALUE but not in TYPE_PRECISION or signedness as useless. This is inconsistent with VRP extracting range information from such types (and it is not clear how NOP conversions behave here anyway). The following patch thus simply removes VRPs looking at TYPE_MIN/MAX_VALUE in favor of using a canonical min/max value based on signedness and precision. This exposes a latent bug in upper_bound_in_type and lower_bound_in_type which do not properly sign-extend sizetype constants. This makes PR33738 and its testcase moot, thus the patch removes it. Bootstrapped and tested on x86_64-unknown-linux-gnu. Richard. 2011-04-11 Richard Guenther * tree.c (upper_bound_in_type): Properly create canonicalized constants. (lower_bound_in_type): Likewise. * tree-vrp.c (vrp_val_max): Use upper_bound_in_type. (vrp_val_min): Use lower_bound_in_type. (set_value_range_to_nonnegative): Use vrp_val_min and vrp_val_max where appropriate. (extract_range_from_assert): Likewise. (vrp_int_const_binop): Likewise. (extract_range_from_unary_expr): Likewise. (adjust_range_with_scev): Likewise. (extract_code_and_val_from_cond_with_ops): Likewise. (vrp_visit_phi_node): Likewise. (test_for_singularity): Likewise. * g++.dg/warn/pr33738.C: Remove. Index: gcc/tree-vrp.c =================================================================== *** gcc/tree-vrp.c (revision 172252) --- gcc/tree-vrp.c (working copy) *************** static VEC (switch_update, heap) *to_upd *** 161,170 **** static inline tree vrp_val_max (const_tree type) { ! if (!INTEGRAL_TYPE_P (type)) ! return NULL_TREE; ! return TYPE_MAX_VALUE (type); } /* Return the minimum value for TYPE. */ --- 161,170 ---- static inline tree vrp_val_max (const_tree type) { ! if (INTEGRAL_TYPE_P (type)) ! return upper_bound_in_type (CONST_CAST_TREE (type), CONST_CAST_TREE (type)); ! return NULL_TREE; } /* Return the minimum value for TYPE. */ *************** vrp_val_max (const_tree type) *** 172,181 **** static inline tree vrp_val_min (const_tree type) { ! if (!INTEGRAL_TYPE_P (type)) ! return NULL_TREE; ! return TYPE_MIN_VALUE (type); } /* Return whether VAL is equal to the maximum value of its type. This --- 172,181 ---- static inline tree vrp_val_min (const_tree type) { ! if (INTEGRAL_TYPE_P (type)) ! return lower_bound_in_type (CONST_CAST_TREE (type), CONST_CAST_TREE (type)); ! return NULL_TREE; } /* Return whether VAL is equal to the maximum value of its type. This *************** set_value_range_to_nonnegative (value_ra *** 565,571 **** set_value_range (vr, VR_RANGE, zero, (overflow_infinity ? positive_overflow_infinity (type) ! : TYPE_MAX_VALUE (type)), vr->equiv); } --- 565,571 ---- set_value_range (vr, VR_RANGE, zero, (overflow_infinity ? positive_overflow_infinity (type) ! : vrp_val_max (type)), vr->equiv); } *************** extract_range_from_assert (value_range_t *** 1627,1633 **** } else if (cond_code == LE_EXPR || cond_code == LT_EXPR) { ! min = TYPE_MIN_VALUE (type); if (limit_vr == NULL || limit_vr->type == VR_ANTI_RANGE) max = limit; --- 1627,1633 ---- } else if (cond_code == LE_EXPR || cond_code == LT_EXPR) { ! min = vrp_val_min (type); if (limit_vr == NULL || limit_vr->type == VR_ANTI_RANGE) max = limit; *************** extract_range_from_assert (value_range_t *** 1662,1668 **** } else if (cond_code == GE_EXPR || cond_code == GT_EXPR) { ! max = TYPE_MAX_VALUE (type); if (limit_vr == NULL || limit_vr->type == VR_ANTI_RANGE) min = limit; --- 1662,1668 ---- } else if (cond_code == GE_EXPR || cond_code == GT_EXPR) { ! max = vrp_val_max (type); if (limit_vr == NULL || limit_vr->type == VR_ANTI_RANGE) min = limit; *************** vrp_int_const_binop (enum tree_code code *** 2079,2089 **** || code == ROUND_DIV_EXPR) return (needs_overflow_infinity (TREE_TYPE (res)) ? positive_overflow_infinity (TREE_TYPE (res)) ! : TYPE_MAX_VALUE (TREE_TYPE (res))); else return (needs_overflow_infinity (TREE_TYPE (res)) ? negative_overflow_infinity (TREE_TYPE (res)) ! : TYPE_MIN_VALUE (TREE_TYPE (res))); } return res; --- 2079,2089 ---- || code == ROUND_DIV_EXPR) return (needs_overflow_infinity (TREE_TYPE (res)) ? positive_overflow_infinity (TREE_TYPE (res)) ! : vrp_val_max (TREE_TYPE (res))); else return (needs_overflow_infinity (TREE_TYPE (res)) ? negative_overflow_infinity (TREE_TYPE (res)) ! : vrp_val_min (TREE_TYPE (res))); } return res; *************** extract_range_from_unary_expr (value_ran *** 2878,2885 **** && TYPE_PRECISION (inner_type) < TYPE_PRECISION (outer_type)) { vr0.type = VR_RANGE; ! vr0.min = TYPE_MIN_VALUE (inner_type); ! vr0.max = TYPE_MAX_VALUE (inner_type); } /* If VR0 is a constant range or anti-range and the conversion is --- 2878,2885 ---- && TYPE_PRECISION (inner_type) < TYPE_PRECISION (outer_type)) { vr0.type = VR_RANGE; ! vr0.min = vrp_val_min (inner_type); ! vr0.max = vrp_val_max (inner_type); } /* If VR0 is a constant range or anti-range and the conversion is *************** extract_range_from_unary_expr (value_ran *** 2964,2970 **** } } else ! min = TYPE_MIN_VALUE (type); if (is_positive_overflow_infinity (vr0.min)) max = negative_overflow_infinity (type); --- 2964,2970 ---- } } else ! min = vrp_val_min (type); if (is_positive_overflow_infinity (vr0.min)) max = negative_overflow_infinity (type); *************** extract_range_from_unary_expr (value_ran *** 2983,2989 **** } } else ! max = TYPE_MIN_VALUE (type); } else if (code == NEGATE_EXPR && TYPE_UNSIGNED (type)) --- 2983,2989 ---- } } else ! max = vrp_val_min (type); } else if (code == NEGATE_EXPR && TYPE_UNSIGNED (type)) *************** extract_range_from_unary_expr (value_ran *** 3025,3031 **** else if (!vrp_val_is_min (vr0.min)) min = fold_unary_to_constant (code, type, vr0.min); else if (!needs_overflow_infinity (type)) ! min = TYPE_MAX_VALUE (type); else if (supports_overflow_infinity (type)) min = positive_overflow_infinity (type); else --- 3025,3031 ---- else if (!vrp_val_is_min (vr0.min)) min = fold_unary_to_constant (code, type, vr0.min); else if (!needs_overflow_infinity (type)) ! min = vrp_val_max (type); else if (supports_overflow_infinity (type)) min = positive_overflow_infinity (type); else *************** extract_range_from_unary_expr (value_ran *** 3039,3045 **** else if (!vrp_val_is_min (vr0.max)) max = fold_unary_to_constant (code, type, vr0.max); else if (!needs_overflow_infinity (type)) ! max = TYPE_MAX_VALUE (type); else if (supports_overflow_infinity (type) /* We shouldn't generate [+INF, +INF] as set_value_range doesn't like this and ICEs. */ --- 3039,3045 ---- else if (!vrp_val_is_min (vr0.max)) max = fold_unary_to_constant (code, type, vr0.max); else if (!needs_overflow_infinity (type)) ! max = vrp_val_max (type); else if (supports_overflow_infinity (type) /* We shouldn't generate [+INF, +INF] as set_value_range doesn't like this and ICEs. */ *************** extract_range_from_unary_expr (value_ran *** 3069,3075 **** TYPE_MIN_VALUE, remember -TYPE_MIN_VALUE = TYPE_MIN_VALUE. */ if (TYPE_OVERFLOW_WRAPS (type)) { ! tree type_min_value = TYPE_MIN_VALUE (type); min = (vr0.min != type_min_value ? int_const_binop (PLUS_EXPR, type_min_value, --- 3069,3075 ---- TYPE_MIN_VALUE, remember -TYPE_MIN_VALUE = TYPE_MIN_VALUE. */ if (TYPE_OVERFLOW_WRAPS (type)) { ! tree type_min_value = vrp_val_min (type); min = (vr0.min != type_min_value ? int_const_binop (PLUS_EXPR, type_min_value, *************** extract_range_from_unary_expr (value_ran *** 3081,3087 **** if (overflow_infinity_range_p (&vr0)) min = negative_overflow_infinity (type); else ! min = TYPE_MIN_VALUE (type); } } else --- 3081,3087 ---- if (overflow_infinity_range_p (&vr0)) min = negative_overflow_infinity (type); else ! min = vrp_val_min (type); } } else *************** extract_range_from_unary_expr (value_ran *** 3102,3108 **** } } else ! max = TYPE_MAX_VALUE (type); } } --- 3102,3108 ---- } } else ! max = vrp_val_max (type); } } *************** adjust_range_with_scev (value_range_t *v *** 3386,3396 **** if (POINTER_TYPE_P (type) || !TYPE_MIN_VALUE (type)) tmin = lower_bound_in_type (type, type); else ! tmin = TYPE_MIN_VALUE (type); if (POINTER_TYPE_P (type) || !TYPE_MAX_VALUE (type)) tmax = upper_bound_in_type (type, type); else ! tmax = TYPE_MAX_VALUE (type); /* Try to use estimated number of iterations for the loop to constrain the final value in the evolution. --- 3386,3396 ---- if (POINTER_TYPE_P (type) || !TYPE_MIN_VALUE (type)) tmin = lower_bound_in_type (type, type); else ! tmin = vrp_val_min (type); if (POINTER_TYPE_P (type) || !TYPE_MAX_VALUE (type)) tmax = upper_bound_in_type (type, type); else ! tmax = vrp_val_max (type); /* Try to use estimated number of iterations for the loop to constrain the final value in the evolution. *************** extract_code_and_val_from_cond_with_ops *** 4304,4311 **** if ((comp_code == GT_EXPR || comp_code == LT_EXPR) && INTEGRAL_TYPE_P (TREE_TYPE (val))) { ! tree min = TYPE_MIN_VALUE (TREE_TYPE (val)); ! tree max = TYPE_MAX_VALUE (TREE_TYPE (val)); if (comp_code == GT_EXPR && (!max --- 4304,4311 ---- if ((comp_code == GT_EXPR || comp_code == LT_EXPR) && INTEGRAL_TYPE_P (TREE_TYPE (val))) { ! tree min = vrp_val_min (TREE_TYPE (val)); ! tree max = vrp_val_max (TREE_TYPE (val)); if (comp_code == GT_EXPR && (!max *************** vrp_visit_phi_node (gimple phi) *** 6661,6667 **** { if (!needs_overflow_infinity (TREE_TYPE (vr_result.min)) || !vrp_var_may_overflow (lhs, phi)) ! vr_result.min = TYPE_MIN_VALUE (TREE_TYPE (vr_result.min)); else if (supports_overflow_infinity (TREE_TYPE (vr_result.min))) vr_result.min = negative_overflow_infinity (TREE_TYPE (vr_result.min)); --- 6661,6667 ---- { if (!needs_overflow_infinity (TREE_TYPE (vr_result.min)) || !vrp_var_may_overflow (lhs, phi)) ! vr_result.min = vrp_val_min (TREE_TYPE (vr_result.min)); else if (supports_overflow_infinity (TREE_TYPE (vr_result.min))) vr_result.min = negative_overflow_infinity (TREE_TYPE (vr_result.min)); *************** vrp_visit_phi_node (gimple phi) *** 6673,6679 **** { if (!needs_overflow_infinity (TREE_TYPE (vr_result.max)) || !vrp_var_may_overflow (lhs, phi)) ! vr_result.max = TYPE_MAX_VALUE (TREE_TYPE (vr_result.max)); else if (supports_overflow_infinity (TREE_TYPE (vr_result.max))) vr_result.max = positive_overflow_infinity (TREE_TYPE (vr_result.max)); --- 6673,6679 ---- { if (!needs_overflow_infinity (TREE_TYPE (vr_result.max)) || !vrp_var_may_overflow (lhs, phi)) ! vr_result.max = vrp_val_max (TREE_TYPE (vr_result.max)); else if (supports_overflow_infinity (TREE_TYPE (vr_result.max))) vr_result.max = positive_overflow_infinity (TREE_TYPE (vr_result.max)); *************** test_for_singularity (enum tree_code con *** 7095,7101 **** { /* This should not be negative infinity; there is no overflow here. */ ! min = TYPE_MIN_VALUE (TREE_TYPE (op0)); max = op1; if (cond_code == LT_EXPR && !is_overflow_infinity (max)) --- 7095,7101 ---- { /* This should not be negative infinity; there is no overflow here. */ ! min = vrp_val_min (TREE_TYPE (op0)); max = op1; if (cond_code == LT_EXPR && !is_overflow_infinity (max)) *************** test_for_singularity (enum tree_code con *** 7110,7116 **** { /* This should not be positive infinity; there is no overflow here. */ ! max = TYPE_MAX_VALUE (TREE_TYPE (op0)); min = op1; if (cond_code == GT_EXPR && !is_overflow_infinity (min)) --- 7110,7116 ---- { /* This should not be positive infinity; there is no overflow here. */ ! max = vrp_val_max (TREE_TYPE (op0)); min = op1; if (cond_code == GT_EXPR && !is_overflow_infinity (min)) Index: gcc/tree.c =================================================================== *** gcc/tree.c (revision 172252) --- gcc/tree.c (working copy) *************** signed_type_for (tree type) *** 10008,10014 **** tree upper_bound_in_type (tree outer, tree inner) { ! unsigned HOST_WIDE_INT lo, hi; unsigned int det = 0; unsigned oprec = TYPE_PRECISION (outer); unsigned iprec = TYPE_PRECISION (inner); --- 10008,10014 ---- tree upper_bound_in_type (tree outer, tree inner) { ! double_int high; unsigned int det = 0; unsigned oprec = TYPE_PRECISION (outer); unsigned iprec = TYPE_PRECISION (inner); *************** upper_bound_in_type (tree outer, tree in *** 10055,10072 **** /* Compute 2^^prec - 1. */ if (prec <= HOST_BITS_PER_WIDE_INT) { ! hi = 0; ! lo = ((~(unsigned HOST_WIDE_INT) 0) >> (HOST_BITS_PER_WIDE_INT - prec)); } else { ! hi = ((~(unsigned HOST_WIDE_INT) 0) >> (2 * HOST_BITS_PER_WIDE_INT - prec)); ! lo = ~(unsigned HOST_WIDE_INT) 0; } ! return build_int_cst_wide (outer, lo, hi); } /* Returns the smallest value obtainable by casting something in INNER type to --- 10055,10072 ---- /* Compute 2^^prec - 1. */ if (prec <= HOST_BITS_PER_WIDE_INT) { ! high.high = 0; ! high.low = ((~(unsigned HOST_WIDE_INT) 0) >> (HOST_BITS_PER_WIDE_INT - prec)); } else { ! high.high = ((~(unsigned HOST_WIDE_INT) 0) >> (2 * HOST_BITS_PER_WIDE_INT - prec)); ! high.low = ~(unsigned HOST_WIDE_INT) 0; } ! return double_int_to_tree (outer, high); } /* Returns the smallest value obtainable by casting something in INNER type to *************** upper_bound_in_type (tree outer, tree in *** 10075,10081 **** tree lower_bound_in_type (tree outer, tree inner) { ! unsigned HOST_WIDE_INT lo, hi; unsigned oprec = TYPE_PRECISION (outer); unsigned iprec = TYPE_PRECISION (inner); --- 10075,10081 ---- tree lower_bound_in_type (tree outer, tree inner) { ! double_int low; unsigned oprec = TYPE_PRECISION (outer); unsigned iprec = TYPE_PRECISION (inner); *************** lower_bound_in_type (tree outer, tree in *** 10086,10092 **** contains all values of INNER type. In particular, both INNER and OUTER types have zero in common. */ || (oprec > iprec && TYPE_UNSIGNED (inner))) ! lo = hi = 0; else { /* If we are widening a signed type to another signed type, we --- 10086,10092 ---- contains all values of INNER type. In particular, both INNER and OUTER types have zero in common. */ || (oprec > iprec && TYPE_UNSIGNED (inner))) ! low.low = low.high = 0; else { /* If we are widening a signed type to another signed type, we *************** lower_bound_in_type (tree outer, tree in *** 10097,10114 **** if (prec <= HOST_BITS_PER_WIDE_INT) { ! hi = ~(unsigned HOST_WIDE_INT) 0; ! lo = (~(unsigned HOST_WIDE_INT) 0) << (prec - 1); } else { ! hi = ((~(unsigned HOST_WIDE_INT) 0) << (prec - HOST_BITS_PER_WIDE_INT - 1)); ! lo = 0; } } ! return build_int_cst_wide (outer, lo, hi); } /* Return nonzero if two operands that are suitable for PHI nodes are --- 10097,10114 ---- if (prec <= HOST_BITS_PER_WIDE_INT) { ! low.high = ~(unsigned HOST_WIDE_INT) 0; ! low.low = (~(unsigned HOST_WIDE_INT) 0) << (prec - 1); } else { ! low.high = ((~(unsigned HOST_WIDE_INT) 0) << (prec - HOST_BITS_PER_WIDE_INT - 1)); ! low.low = 0; } } ! return double_int_to_tree (outer, low); } /* Return nonzero if two operands that are suitable for PHI nodes are