This patch convers some gcc_asserts to gcc_checking_asserts. I think the first two in particular should be checking-only, since we ignore the bits above the target precision anyway.
Also we have: /* This is a little hokie, but if the prec is smaller than what is necessary to hold INTEGER_SHARE_LIMIT, then the obvious test will not get the correct answer. */ if (prec < HOST_BITS_PER_WIDE_INT) { if (cst.to_uhwi () < (unsigned HOST_WIDE_INT) INTEGER_SHARE_LIMIT) ix = cst.to_uhwi (); } else if (wi::ltu_p (cst, INTEGER_SHARE_LIMIT)) ix = cst.to_uhwi (); But this case only occurs for single-HWI integers. We later check for that and extract the HWI value, so it seems simpler to postpone the index check until then. Tested on x86_64-linux-gnu. OK to install? Thanks, Richard Index: gcc/tree.c =================================================================== *** gcc/tree.c 2013-11-28 11:27:32.043124135 +0000 --- gcc/tree.c 2013-11-28 11:45:39.957427563 +0000 *************** wide_int_to_tree (tree type, const wide_ *** 1205,1295 **** if (l > 1) { if (pcst.elt (l - 1) == 0) ! gcc_assert (pcst.elt (l - 2) < 0); if (pcst.elt (l - 1) == (HOST_WIDE_INT) -1) ! gcc_assert (pcst.elt (l - 2) >= 0); } wide_int cst = wide_int::from (pcst, prec, sgn); unsigned int ext_len = get_int_cst_ext_nunits (type, cst); ! switch (TREE_CODE (type)) { ! case NULLPTR_TYPE: ! gcc_assert (cst == 0); ! /* Fallthru. */ ! ! case POINTER_TYPE: ! case REFERENCE_TYPE: ! case POINTER_BOUNDS_TYPE: ! /* Cache NULL pointer and zero bounds. */ ! if (cst == 0) ! { ! limit = 1; ! ix = 0; ! } ! break; ! case BOOLEAN_TYPE: ! /* Cache false or true. */ ! limit = 2; ! if (wi::leu_p (cst, 1)) ! ix = cst.to_uhwi (); ! break; ! ! case INTEGER_TYPE: ! case OFFSET_TYPE: ! if (TYPE_SIGN (type) == UNSIGNED) { ! /* Cache 0..N */ ! limit = INTEGER_SHARE_LIMIT; ! ! /* This is a little hokie, but if the prec is smaller than ! what is necessary to hold INTEGER_SHARE_LIMIT, then the ! obvious test will not get the correct answer. */ ! if (prec < HOST_BITS_PER_WIDE_INT) { ! if (cst.to_uhwi () < (unsigned HOST_WIDE_INT) INTEGER_SHARE_LIMIT) ! ix = cst.to_uhwi (); } ! else if (wi::ltu_p (cst, INTEGER_SHARE_LIMIT)) ! ix = cst.to_uhwi (); ! } ! else ! { ! /* Cache -1..N */ ! limit = INTEGER_SHARE_LIMIT + 1; ! if (cst == -1) ! ix = 0; ! else if (!wi::neg_p (cst)) { ! if (prec < HOST_BITS_PER_WIDE_INT) ! { ! if (cst.to_shwi () < INTEGER_SHARE_LIMIT) ! ix = cst.to_shwi () + 1; ! } ! else if (wi::lts_p (cst, INTEGER_SHARE_LIMIT)) ! ix = cst.to_shwi () + 1; } ! } ! break; ! case ENUMERAL_TYPE: ! break; ! default: ! gcc_unreachable (); ! } - if (ext_len == 1) - { - /* We just need to store a single HOST_WIDE_INT. */ - HOST_WIDE_INT hwi; - if (TYPE_UNSIGNED (type)) - hwi = cst.to_uhwi (); - else - hwi = cst.to_shwi (); if (ix >= 0) { /* Look for it in the type's vector of small shared ints. */ --- 1205,1276 ---- if (l > 1) { if (pcst.elt (l - 1) == 0) ! gcc_checking_assert (pcst.elt (l - 2) < 0); if (pcst.elt (l - 1) == (HOST_WIDE_INT) -1) ! gcc_checking_assert (pcst.elt (l - 2) >= 0); } wide_int cst = wide_int::from (pcst, prec, sgn); unsigned int ext_len = get_int_cst_ext_nunits (type, cst); ! if (ext_len == 1) { ! /* We just need to store a single HOST_WIDE_INT. */ ! HOST_WIDE_INT hwi; ! if (TYPE_UNSIGNED (type)) ! hwi = cst.to_uhwi (); ! else ! hwi = cst.to_shwi (); ! switch (TREE_CODE (type)) { ! case NULLPTR_TYPE: ! gcc_assert (hwi == 0); ! /* Fallthru. */ ! ! case POINTER_TYPE: ! case REFERENCE_TYPE: ! case POINTER_BOUNDS_TYPE: ! /* Cache NULL pointer and zero bounds. */ ! if (hwi == 0) { ! limit = 1; ! ix = 0; } ! break; ! case BOOLEAN_TYPE: ! /* Cache false or true. */ ! limit = 2; ! if (hwi < 2) ! ix = hwi; ! break; ! ! case INTEGER_TYPE: ! case OFFSET_TYPE: ! if (TYPE_SIGN (type) == UNSIGNED) { ! /* Cache [0, N). */ ! limit = INTEGER_SHARE_LIMIT; ! if (IN_RANGE (hwi, 0, INTEGER_SHARE_LIMIT - 1)) ! ix = hwi; } ! else ! { ! /* Cache [-1, N). */ ! limit = INTEGER_SHARE_LIMIT + 1; ! if (IN_RANGE (hwi, -1, INTEGER_SHARE_LIMIT - 1)) ! ix = hwi + 1; ! } ! break; ! case ENUMERAL_TYPE: ! break; ! default: ! gcc_unreachable (); ! } if (ix >= 0) { /* Look for it in the type's vector of small shared ints. */ *************** wide_int_to_tree (tree type, const wide_ *** 1302,1311 **** t = TREE_VEC_ELT (TYPE_CACHED_VALUES (type), ix); if (t) /* Make sure no one is clobbering the shared constant. */ ! gcc_assert (TREE_TYPE (t) == type ! && TREE_INT_CST_NUNITS (t) == 1 ! && TREE_INT_CST_EXT_NUNITS (t) == 1 ! && TREE_INT_CST_ELT (t, 0) == hwi); else { /* Create a new shared int. */ --- 1283,1292 ---- t = TREE_VEC_ELT (TYPE_CACHED_VALUES (type), ix); if (t) /* Make sure no one is clobbering the shared constant. */ ! gcc_checking_assert (TREE_TYPE (t) == type ! && TREE_INT_CST_NUNITS (t) == 1 ! && TREE_INT_CST_EXT_NUNITS (t) == 1 ! && TREE_INT_CST_ELT (t, 0) == hwi); else { /* Create a new shared int. */