diff mbox

Some wide-int review comments

Message ID 52895DB6.2050602@naturalbridge.com
State New
Headers show

Commit Message

Kenneth Zadeck Nov. 18, 2013, 12:22 a.m. UTC
On 11/08/2013 05:30 AM, Richard Sandiford wrote:
> Some comments from looking through the diff with the merge point,
> ignoring wide-int.h and wide-int.cc.  A few more to follow in the
> form of patchses.
>
> --------------------
>
> dwarf2out.c has:
>
> +    case CONST_WIDE_INT:
> +      if (mode == VOIDmode)
> +	mode = GET_MODE (rtl);
> +
> +      if (mode != VOIDmode && (dwarf_version >= 4 || !dwarf_strict))
> +	{
> +	  gcc_assert (mode == GET_MODE (rtl) || VOIDmode == GET_MODE (rtl));
> +
> +	  /* Note that a CONST_DOUBLE rtx could represent either an integer
> +	     or a floating-point constant.  A CONST_DOUBLE is used whenever
> +	     the constant requires more than one word in order to be
> +	     adequately represented.  We output CONST_DOUBLEs as blocks.  */
> +	  loc_result = new_loc_descr (DW_OP_implicit_value,
> +				      GET_MODE_SIZE (mode), 0);
> +	  loc_result->dw_loc_oprnd2.val_class = dw_val_class_wide_int;
> +	  loc_result->dw_loc_oprnd2.v.val_wide = ggc_alloc_cleared_wide_int ();
> +	  *loc_result->dw_loc_oprnd2.v.val_wide = std::make_pair (rtl, mode);
>
> The comment looks like a cut-&-paste.  The "mode == GET_MODE (rtl)"
> bit should never be true.
i removed the assertion completely.  it really is unnecessary.
> --------------------
>
>  From fold-const.c:
>
> @@ -13686,14 +13548,17 @@ fold_binary_loc (location_t loc,
>   		  break;
>   		}
>   
> -	    else if (TREE_INT_CST_HIGH (arg1) == signed_max_hi
> -		     && TREE_INT_CST_LOW (arg1) == signed_max_lo
> +	    else if (wi::eq_p (arg1, signed_max)
>   		     && TYPE_UNSIGNED (arg1_type)
> +		     /* KENNY QUESTIONS THE CHECKING OF THE BITSIZE
> +			HERE.  HE FEELS THAT THE PRECISION SHOULD BE
> +			CHECKED */
> +
>   		     /* We will flip the signedness of the comparison operator
>   			associated with the mode of arg1, so the sign bit is
>   			specified by this mode.  Check that arg1 is the signed
>   			max associated with this sign bit.  */
> -		     && width == GET_MODE_BITSIZE (TYPE_MODE (arg1_type))
> +		     && prec == GET_MODE_BITSIZE (TYPE_MODE (arg1_type))
>   		     /* signed_type does not work on pointer types.  */
>   		     && INTEGRAL_TYPE_P (arg1_type))
>   	      {
>
> Looks like it should be resolved one way or the other before the merge.
I have posted a patch to fix this on trunk.   the enclosed patch is 
consistent with that fix.

> --------------------
>
>  From gcse.c:
>
> --- wide-int-base/gcc/gcc/gcse.c	2013-11-05 13:09:32.148376180 +0000
> +++ wide-int/gcc/gcc/gcse.c	2013-11-05 13:07:28.431495118 +0000
> @@ -1997,6 +1997,13 @@ prune_insertions_deletions (int n_elems)
>   	bitmap_clear_bit (pre_delete_map[i], j);
>       }
>   
> +  if (dump_file)
> +    {
> +      dump_bitmap_vector (dump_file, "pre_insert_map", "", pre_insert_map, n_edges);
> +      dump_bitmap_vector (dump_file, "pre_delete_map", "", pre_delete_map,
> +			   last_basic_block);
> +    }
> +
>     sbitmap_free (prune_exprs);
>     free (insertions);
>     free (deletions);
>
> This doesn't look related.
removed
>
> --------------------
>
>  From lcm.c:
>
> diff -udpr '--exclude=.svn' '--exclude=.pc' '--exclude=patches' wide-int-base/gcc/gcc/lcm.c wide-int/gcc/gcc/lcm.c
> --- wide-int-base/gcc/gcc/lcm.c	2013-08-22 09:00:23.068716382 +0100
> +++ wide-int/gcc/gcc/lcm.c	2013-10-26 13:19:16.287277520 +0100
> @@ -64,6 +64,7 @@ along with GCC; see the file COPYING3.
>   #include "sbitmap.h"
>   #include "dumpfile.h"
>   
> +#define LCM_DEBUG_INFO 1
>   /* Edge based LCM routines.  */
>   static void compute_antinout_edge (sbitmap *, sbitmap *, sbitmap *, sbitmap *);
>   static void compute_earliest (struct edge_list *, int, sbitmap *, sbitmap *,
> @@ -106,6 +107,7 @@ compute_antinout_edge (sbitmap *antloc,
>     /* We want a maximal solution, so make an optimistic initialization of
>        ANTIN.  */
>     bitmap_vector_ones (antin, last_basic_block);
> +  bitmap_vector_clear (antout, last_basic_block);
>   
>     /* Put every block on the worklist; this is necessary because of the
>        optimistic initialization of ANTIN above.  */
> @@ -432,6 +434,7 @@ pre_edge_lcm (int n_exprs, sbitmap *tran
>   
>     /* Allocate an extra element for the exit block in the laterin vector.  */
>     laterin = sbitmap_vector_alloc (last_basic_block + 1, n_exprs);
> +  bitmap_vector_clear (laterin, last_basic_block);
>     compute_laterin (edge_list, earliest, antloc, later, laterin);
>   
>   #ifdef LCM_DEBUG_INFO
>
> Same here.
i removed this also.   this was done for the sanity of debugging. but i 
do not think that it is important enough for the trunk.   I assume that 
the code was done this way because it is faster to do this than 
explicitly clear the structures.
>
> --------------------
>
>  From real.c:
>
> @@ -2144,43 +2148,131 @@ real_from_string3 (REAL_VALUE_TYPE *r, c
>       real_convert (r, mode, r);
>   }
>   
> -/* Initialize R from the integer pair HIGH+LOW.  */
> +/* Initialize R from a HOST_WIDE_INT.  */
>   
>   void
>   real_from_integer (REAL_VALUE_TYPE *r, enum machine_mode mode,
> -		   unsigned HOST_WIDE_INT low, HOST_WIDE_INT high,
> -		   int unsigned_p)
> +		   HOST_WIDE_INT val,
> +		   signop sgn)
>   {
> -  if (low == 0 && high == 0)
> +  if (val == 0)
>       get_zero (r, 0);
>     else
>       {
>         memset (r, 0, sizeof (*r));
>         r->cl = rvc_normal;
> -      r->sign = high < 0 && !unsigned_p;
> -      SET_REAL_EXP (r, HOST_BITS_PER_DOUBLE_INT);
> +      r->sign = val < 0 && sgn == SIGNED;
> +      SET_REAL_EXP (r, HOST_BITS_PER_WIDE_INT);
>   
> +      /* TODO: This fails for -MAXHOSTWIDEINT, wide_int version would
> +	 have worked.  */
>         if (r->sign)
> +	val = -val;
>
> Given the TODO, is it really worth having this HOST_WIDE_INT version?
> Wouldn't it be better to have just the wide_int version?
i got rid of this version.    The patch also gets rid of 
REAL_VALUE_FOM_INT since it was a pretty thing interface and just made 
everyone call the wide int version.

> --------------------
>
>  From real.c:
>
> +/* Initialize R from the integer pair HIGH+LOW.  */
> +
> +void
> +real_from_integer (REAL_VALUE_TYPE *r, enum machine_mode mode,
> +		   const wide_int_ref &val_in, signop sgn)
> +{
> +  if (val_in == 0)
> +    get_zero (r, 0);
> +  else
> +    {
> +      unsigned int len = val_in.get_precision ();
> +      int i, j, e=0;
> +      int maxbitlen = MAX_BITSIZE_MODE_ANY_INT + HOST_BITS_PER_WIDE_INT;
>
> Why + HOST_BITS_PER_WIDE_INT?  AIUI you want + X so that you can negate
> the largest negative number, but 1 bit should be enough for that.
wide int works faster with precs that are multiples of hwi.
> In case the idea was to get a rounded bitlen, there's no guarantee that
> MAX_BITSIZE_MODE_ANY_INT itself is rounded.
>
> +	  HOST_WIDE_INT cnt_l_z;
> +	  cnt_l_z = wi::clz (val);
> +
> +	  if (maxbitlen - cnt_l_z > realmax)
> +	    {
> +	      e = maxbitlen - cnt_l_z - realmax;
> +
> +	      /* This value is too large, we must shift it right to
> +		 preserve all the bits we can, and then bump the
> +		 exponent up by that amount.  */
> +	      val = wi::lrshift (val, e);
>
> Don't we want a sticky bit for the shifted-out bits, in order to detect
> the 0.5 ULP case properly?
this is something for an fp expert.   what we do here is upwards 
compatible with what was there before. What you are suggesting would be 
more a change.
> --------------------
>
>  From recog.c:
>
> +int
> +const_scalar_int_operand (rtx op, enum machine_mode mode)
> +{
> +  if (!CONST_SCALAR_INT_P (op))
> +    return 0;
> +
> +  if (CONST_INT_P (op))
> +    return const_int_operand (op, mode);
> +
> +  if (mode != VOIDmode)
> +    {
> +      int prec = GET_MODE_PRECISION (mode);
> +      int bitsize = GET_MODE_BITSIZE (mode);
> +
> +      if (CONST_WIDE_INT_NUNITS (op) * HOST_BITS_PER_WIDE_INT > bitsize)
> +	return 0;
> +
> +      if (prec == bitsize)
> +	return 1;
> +      else
> +	{
> +	  /* Multiword partial int.  */
> +	  HOST_WIDE_INT x
> +	    = CONST_WIDE_INT_ELT (op, CONST_WIDE_INT_NUNITS (op) - 1);
> +	  return (sext_hwi (x, prec & (HOST_BITS_PER_WIDE_INT - 1)) == x);
> +	}
> +    }
> +  return 1;
> +}
>
> const_int_operand rejects cases where gen_int_mode (INTVAL (op), mode)
> would give something different from op.  We need to do the equivalent
> for CONST_WIDE_INT too.  (The current CONST_DOUBLE code doesn't bother
> because at the moment the only >HWI mode we support is a 2*HWI one.)
>
> It'd be nice to handle CONST_INT and CONST_WIDE_INT using the same code,
> without going to const_int_operand.
>
> +/* Returns 1 if OP is an operand that is a CONST_WIDE_INT of mode
> +   MODE.  This most likely is not as useful as
> +   const_scalar_int_operand since it does not accept CONST_INTs, but
> +   is here for consistancy.  */
> +int
> +const_wide_int_operand (rtx op, enum machine_mode mode)
> +{
> +  if (!CONST_WIDE_INT_P (op))
> +    return 0;
> +
> +  return const_scalar_int_operand (op, mode);
> +}
>
> Hmm, but have you found any use cases?  Like you say in the comment,
> it just seems wrong to require a CONST_WIDE_INT over a CONST_INT,
> since that's a host-dependent choice.  I think we should drop this
> from the initial merge.
its gone.
> --------------------
>
>  From rtl.c:
>
> +/* Write the wide constant X to OUTFILE.  */
> +
> +void
> +cwi_output_hex (FILE *outfile, const_rtx x)
> +{
> +  int i = CWI_GET_NUM_ELEM (x);
> +  gcc_assert (i > 0);
> +  if (CWI_ELT (x, i-1) == 0)
> +    fprintf (outfile, "0x");
> +  fprintf (outfile, HOST_WIDE_INT_PRINT_HEX, CWI_ELT (x, --i));
> +  while (--i >= 0)
> +    fprintf (outfile, HOST_WIDE_INT_PRINT_PADDED_HEX, CWI_ELT (x, i));
> +}
>
> Why only print "0x" if the top element is 0?  Probably deserves a comment.
it got one
> --------------------
>
>  From tree-cfg.c:
>
> @@ -2698,24 +2700,25 @@ verify_expr (tree *tp, int *walk_subtree
>   
>         if (TREE_CODE (t) == BIT_FIELD_REF)
>   	{
> -	  if (!host_integerp (TREE_OPERAND (t, 1), 1)
> -	      || !host_integerp (TREE_OPERAND (t, 2), 1))
> +	  if (!tree_fits_uhwi_p (TREE_OPERAND (t, 1))
> +	      || !tree_fits_uhwi_p (TREE_OPERAND (t, 2)))
>   	    {
>   	      error ("invalid position or size operand to BIT_FIELD_REF");
>   	      return t;
>   	    }
>   	  if (INTEGRAL_TYPE_P (TREE_TYPE (t))
>   	      && (TYPE_PRECISION (TREE_TYPE (t))
> -		  != TREE_INT_CST_LOW (TREE_OPERAND (t, 1))))
> +		  != tree_to_uhwi (TREE_OPERAND (t, 1))))
>   	    {
>   	      error ("integral result type precision does not match "
>   		     "field size of BIT_FIELD_REF");
>   	      return t;
>   	    }
>   	  else if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
> +		   && !AGGREGATE_TYPE_P (TREE_TYPE (t))
>   		   && TYPE_MODE (TREE_TYPE (t)) != BLKmode
>   		   && (GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (t)))
> -		       != TREE_INT_CST_LOW (TREE_OPERAND (t, 1))))
> +		       != tree_to_uhwi (TREE_OPERAND (t, 1))))
>   	    {
>   	      error ("mode precision of non-integral result does not "
>   		     "match field size of BIT_FIELD_REF");
>
> Why the extra !AGGREGATE_TYPE_P test?
this was a merge failure.    it has been removed.
> --------------------
>
>  From tree-vrp.c:
>
> @@ -1893,6 +1884,10 @@ vrp_int_const_binop (enum tree_code code
>       /* If the singed operation wraps then int_const_binop has done
>          everything we want.  */
>       ;
> +  /* Signed division of -1/0 overflows and by the time it gets here
> +     returns NULL_TREE.  */
> +  else if (!res)
> +    return NULL_TREE;
>     else if ((TREE_OVERFLOW (res)
>   	    && !TREE_OVERFLOW (val1)
>   	    && !TREE_OVERFLOW (val2))
>
> Why is this case different from trunk?  Or is it a bug-fix independent
> of wide-int?
this will be handled in a separate set of patches.   I am working on it.
> Thanks,
> Richard
ok to commit?  Bootstrapped and tested on x86-64.


kenny

Comments

Richard Sandiford Nov. 18, 2013, 9:29 a.m. UTC | #1
Thanks for the changes.

> @@ -8162,7 +8162,7 @@ fold_builtin_logarithm (location_t loc,
>  	    /* Prepare to do logN(exp10(exponent) -> exponent*logN(10).  */
>  	    {
>  	      REAL_VALUE_TYPE dconst10;
> -	      real_from_integer (&dconst10, VOIDmode, 10, SIGNED);
> +	      real_from_integer (&dconst10, VOIDmode, wi::shwi (10, 32), SIGNED);
>  	      x = build_real (type, dconst10);
>  	    }
>  	    exponent = CALL_EXPR_ARG (arg, 0);
> @@ -8315,7 +8315,7 @@ fold_builtin_pow (location_t loc, tree f
>  
>        /* Check for an integer exponent.  */
>        n = real_to_integer (&c);
> -      real_from_integer (&cint, VOIDmode, n, SIGNED);
> +      real_from_integer (&cint, VOIDmode, wi::shwi (n, HOST_BITS_PER_WIDE_INT), SIGNED);
>        if (real_identical (&c, &cint))
>  	{
>  	  /* Attempt to evaluate pow at compile-time, unless this should

Are these changes necessary?  The original calls ought to work as-is,
since the function takes a const wide_int_ref &.  Same for the rest of
the patch.

> Index: gcc/c/c-parser.c
> ===================================================================
> --- gcc/c/c-parser.c	(revision 204918)
> +++ gcc/c/c-parser.c	(working copy)
> @@ -13375,7 +13375,7 @@ c_parser_cilk_clause_vectorlength (c_par
>        || !TREE_CONSTANT (expr)
>        || !INTEGRAL_TYPE_P (TREE_TYPE (expr)))
>      error_at (loc, "vectorlength must be an integer constant");
> -  else if (exact_log2 (tree_to_hwi (expr)) == -1)
> +  else if (wi::eq_p (wi::exact_log2 (expr), -1))
>      error_at (loc, "vectorlength must be a power of 2");
>    else
>      {

FWIW:

  wi::exact_log2 (expr) == -1

should still work.

> Index: gcc/dwarf2out.c
> ===================================================================
> --- gcc/dwarf2out.c	(revision 204918)
> +++ gcc/dwarf2out.c	(working copy)
> @@ -13428,8 +13428,6 @@ loc_descriptor (rtx rtl, enum machine_mo
>  
>        if (mode != VOIDmode && (dwarf_version >= 4 || !dwarf_strict))
>  	{
> -	  gcc_assert (mode == GET_MODE (rtl) || VOIDmode == GET_MODE (rtl));
> -
>  	  /* Note that a CONST_DOUBLE rtx could represent either an integer
>  	     or a floating-point constant.  A CONST_DOUBLE is used whenever
>  	     the constant requires more than one word in order to be

The copy of the CONST_DOUBLE comment is still there though.
(This is handling CONST_WIDE_INT rather than CONST_DOUBLE.)

> Index: gcc/tree.c
> ===================================================================
> --- gcc/tree.c	(revision 204918)
> +++ gcc/tree.c	(working copy)
> @@ -8536,8 +8536,18 @@ retry:
>      return true;
>  
>    /* Third, unsigned integers with top bit set never fit signed types.  */
> -  if (!TYPE_UNSIGNED (type) && sgn_c == UNSIGNED && wi::neg_p (c))
> -    return false;
> +  if (!TYPE_UNSIGNED (type) && sgn_c == UNSIGNED)
> +    {
> +      int uprec = GET_MODE_PRECISION (TYPE_MODE TREE_TYPE (c));
> +      if (uprec < TYPE_PRECISION (TREE_TYPE (c)))
> +	{
> +	  wide_int x = wi::sext (c, uprec);
> +	  if (wi::neg_p (x) || wi::ne_p (x, c))
> +	    return false;
> +	}
> +      else if (wi::neg_p (c))
> +	return false;
> +    }
>  
>    /* If we haven't been able to decide at this point, there nothing more we
>       can check ourselves here.  Look at the base type if we have one and it

I don't really understand this change, but I suppose it's part of
the trunk patch.

Looks good to me otherwise FWIW.

Thanks,
Richard
Kenneth Zadeck Nov. 19, 2013, 5:24 p.m. UTC | #2
Committed with all your changes as revision 205049.

the only interesting change is the response to your last comment.

I changed the frag to:

    /* Third, unsigned integers with top bit set never fit signed types.  */
-  if (!TYPE_UNSIGNED (type) && sgn_c == UNSIGNED && wi::neg_p (c))
-    return false;
+  if (!TYPE_UNSIGNED (type) && sgn_c == UNSIGNED)
+    {
+      int uprec = GET_MODE_PRECISION (TYPE_MODE TREE_TYPE (c));
+      if (uprec < TYPE_PRECISION (TREE_TYPE (c)))
+    {
+      /* When a tree_cst is converted to a wide-int, the precision
+         is taken from the type.  However, if the precision of the
+         mode underneath the type is smaller than that, it is
+         possible that the value will not fit.  The test below
+         fails if any bit is set between the sign bit of the
+         underlying mode and the top bit of the type.  */
+      if (wi::ne_p (wi::zext (c, uprec - 1), c))
+        return false;
+    }
+      else if (wi::neg_p (c))
+    return false;
+    }


On 11/18/2013 04:29 AM, Richard Sandiford wrote:
> Thanks for the changes.
>
>> @@ -8162,7 +8162,7 @@ fold_builtin_logarithm (location_t loc,
>>   	    /* Prepare to do logN(exp10(exponent) -> exponent*logN(10).  */
>>   	    {
>>   	      REAL_VALUE_TYPE dconst10;
>> -	      real_from_integer (&dconst10, VOIDmode, 10, SIGNED);
>> +	      real_from_integer (&dconst10, VOIDmode, wi::shwi (10, 32), SIGNED);
>>   	      x = build_real (type, dconst10);
>>   	    }
>>   	    exponent = CALL_EXPR_ARG (arg, 0);
>> @@ -8315,7 +8315,7 @@ fold_builtin_pow (location_t loc, tree f
>>   
>>         /* Check for an integer exponent.  */
>>         n = real_to_integer (&c);
>> -      real_from_integer (&cint, VOIDmode, n, SIGNED);
>> +      real_from_integer (&cint, VOIDmode, wi::shwi (n, HOST_BITS_PER_WIDE_INT), SIGNED);
>>         if (real_identical (&c, &cint))
>>   	{
>>   	  /* Attempt to evaluate pow at compile-time, unless this should
> Are these changes necessary?  The original calls ought to work as-is,
> since the function takes a const wide_int_ref &.  Same for the rest of
> the patch.
>
>> Index: gcc/c/c-parser.c
>> ===================================================================
>> --- gcc/c/c-parser.c	(revision 204918)
>> +++ gcc/c/c-parser.c	(working copy)
>> @@ -13375,7 +13375,7 @@ c_parser_cilk_clause_vectorlength (c_par
>>         || !TREE_CONSTANT (expr)
>>         || !INTEGRAL_TYPE_P (TREE_TYPE (expr)))
>>       error_at (loc, "vectorlength must be an integer constant");
>> -  else if (exact_log2 (tree_to_hwi (expr)) == -1)
>> +  else if (wi::eq_p (wi::exact_log2 (expr), -1))
>>       error_at (loc, "vectorlength must be a power of 2");
>>     else
>>       {
> FWIW:
>
>    wi::exact_log2 (expr) == -1
>
> should still work.
>
>> Index: gcc/dwarf2out.c
>> ===================================================================
>> --- gcc/dwarf2out.c	(revision 204918)
>> +++ gcc/dwarf2out.c	(working copy)
>> @@ -13428,8 +13428,6 @@ loc_descriptor (rtx rtl, enum machine_mo
>>   
>>         if (mode != VOIDmode && (dwarf_version >= 4 || !dwarf_strict))
>>   	{
>> -	  gcc_assert (mode == GET_MODE (rtl) || VOIDmode == GET_MODE (rtl));
>> -
>>   	  /* Note that a CONST_DOUBLE rtx could represent either an integer
>>   	     or a floating-point constant.  A CONST_DOUBLE is used whenever
>>   	     the constant requires more than one word in order to be
> The copy of the CONST_DOUBLE comment is still there though.
> (This is handling CONST_WIDE_INT rather than CONST_DOUBLE.)
>
>> Index: gcc/tree.c
>> ===================================================================
>> --- gcc/tree.c	(revision 204918)
>> +++ gcc/tree.c	(working copy)
>> @@ -8536,8 +8536,18 @@ retry:
>>       return true;
>>   
>>     /* Third, unsigned integers with top bit set never fit signed types.  */
>> -  if (!TYPE_UNSIGNED (type) && sgn_c == UNSIGNED && wi::neg_p (c))
>> -    return false;
>> +  if (!TYPE_UNSIGNED (type) && sgn_c == UNSIGNED)
>> +    {
>> +      int uprec = GET_MODE_PRECISION (TYPE_MODE TREE_TYPE (c));
>> +      if (uprec < TYPE_PRECISION (TREE_TYPE (c)))
>> +	{
>> +	  wide_int x = wi::sext (c, uprec);
>> +	  if (wi::neg_p (x) || wi::ne_p (x, c))
>> +	    return false;
>> +	}
>> +      else if (wi::neg_p (c))
>> +	return false;
>> +    }
>>   
>>     /* If we haven't been able to decide at this point, there nothing more we
>>        can check ourselves here.  Look at the base type if we have one and it
> I don't really understand this change, but I suppose it's part of
> the trunk patch.
>
> Looks good to me otherwise FWIW.
>
> Thanks,
> Richard
diff mbox

Patch

Index: gcc/builtins.c
===================================================================
--- gcc/builtins.c	(revision 204918)
+++ gcc/builtins.c	(working copy)
@@ -8162,7 +8162,7 @@  fold_builtin_logarithm (location_t loc,
 	    /* Prepare to do logN(exp10(exponent) -> exponent*logN(10).  */
 	    {
 	      REAL_VALUE_TYPE dconst10;
-	      real_from_integer (&dconst10, VOIDmode, 10, SIGNED);
+	      real_from_integer (&dconst10, VOIDmode, wi::shwi (10, 32), SIGNED);
 	      x = build_real (type, dconst10);
 	    }
 	    exponent = CALL_EXPR_ARG (arg, 0);
@@ -8315,7 +8315,7 @@  fold_builtin_pow (location_t loc, tree f
 
       /* Check for an integer exponent.  */
       n = real_to_integer (&c);
-      real_from_integer (&cint, VOIDmode, n, SIGNED);
+      real_from_integer (&cint, VOIDmode, wi::shwi (n, HOST_BITS_PER_WIDE_INT), SIGNED);
       if (real_identical (&c, &cint))
 	{
 	  /* Attempt to evaluate pow at compile-time, unless this should
Index: gcc/c/c-parser.c
===================================================================
--- gcc/c/c-parser.c	(revision 204918)
+++ gcc/c/c-parser.c	(working copy)
@@ -13375,7 +13375,7 @@  c_parser_cilk_clause_vectorlength (c_par
       || !TREE_CONSTANT (expr)
       || !INTEGRAL_TYPE_P (TREE_TYPE (expr)))
     error_at (loc, "vectorlength must be an integer constant");
-  else if (exact_log2 (tree_to_hwi (expr)) == -1)
+  else if (wi::eq_p (wi::exact_log2 (expr), -1))
     error_at (loc, "vectorlength must be a power of 2");
   else
     {
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c	(revision 204918)
+++ gcc/config/i386/i386.c	(working copy)
@@ -38642,7 +38642,7 @@  void ix86_emit_swsqrtsf (rtx res, rtx a,
   e2 = gen_reg_rtx (mode);
   e3 = gen_reg_rtx (mode);
 
-  real_from_integer (&r, VOIDmode, -3, SIGNED);
+  real_from_integer (&r, VOIDmode, wi::shwi (-3, 32), SIGNED);
   mthree = CONST_DOUBLE_FROM_REAL_VALUE (r, SFmode);
 
   real_arithmetic (&r, NEGATE_EXPR, &dconsthalf, NULL);
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 204918)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -29412,7 +29412,7 @@  rs6000_emit_swrsqrt (rtx dst, rtx src)
   gcc_assert (code != CODE_FOR_nothing);
 
   /* Load up the constant 1.5 either as a scalar, or as a vector.  */
-  real_from_integer (&dconst3_2, VOIDmode, 3, SIGNED);
+  real_from_integer (&dconst3_2, VOIDmode, wi:shwi (3, 32), SIGNED);
   SET_REAL_EXP (&dconst3_2, REAL_EXP (&dconst3_2) - 1);
 
   halfthree = rs6000_load_constant_and_splat (mode, dconst3_2);
Index: gcc/config/vax/vax.c
===================================================================
--- gcc/config/vax/vax.c	(revision 204918)
+++ gcc/config/vax/vax.c	(working copy)
@@ -43,6 +43,7 @@  along with GCC; see the file COPYING3.
 #include "tm_p.h"
 #include "target.h"
 #include "target-def.h"
+#include "wide-int.h"
 
 static void vax_option_override (void);
 static bool vax_legitimate_address_p (enum machine_mode, rtx, bool);
@@ -643,7 +644,7 @@  vax_float_literal (rtx c)
     {
       int x = 1 << i;
       bool ok;
-      REAL_VALUE_FROM_INT (s, x, mode);
+      real_from_integer (&s, mode, wi::shwi (x, sizeof (int) * 8), SIGNED);
 
       if (REAL_VALUES_EQUAL (r, s))
 	return true;
Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi	(revision 204918)
+++ gcc/doc/tm.texi	(working copy)
@@ -9683,11 +9683,6 @@  Returns the negative of the floating poi
 Returns the absolute value of @var{x}.
 @end deftypefn
 
-@deftypefn Macro void REAL_VALUE_FROM_INT (REAL_VALUE_TYPE @var{x}, const wide_int_ref &@var{val}, enum machine_mode @var{mode})
-Converts integer @var{val} into a floating-point value which is then
-stored into @var{x}.  The value is truncated to fit in mode @var{mode}.
-@end deftypefn
-
 @node Mode Switching
 @section Mode Switching Instructions
 @cindex mode switching
Index: gcc/doc/tm.texi.in
===================================================================
--- gcc/doc/tm.texi.in	(revision 204918)
+++ gcc/doc/tm.texi.in	(working copy)
@@ -7345,11 +7345,6 @@  Returns the negative of the floating poi
 Returns the absolute value of @var{x}.
 @end deftypefn
 
-@deftypefn Macro void REAL_VALUE_FROM_INT (REAL_VALUE_TYPE @var{x}, const wide_int_ref &@var{val}, enum machine_mode @var{mode})
-Converts integer @var{val} into a floating-point value which is then
-stored into @var{x}.  The value is truncated to fit in mode @var{mode}.
-@end deftypefn
-
 @node Mode Switching
 @section Mode Switching Instructions
 @cindex mode switching
Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c	(revision 204918)
+++ gcc/dwarf2out.c	(working copy)
@@ -13428,8 +13428,6 @@  loc_descriptor (rtx rtl, enum machine_mo
 
       if (mode != VOIDmode && (dwarf_version >= 4 || !dwarf_strict))
 	{
-	  gcc_assert (mode == GET_MODE (rtl) || VOIDmode == GET_MODE (rtl));
-
 	  /* Note that a CONST_DOUBLE rtx could represent either an integer
 	     or a floating-point constant.  A CONST_DOUBLE is used whenever
 	     the constant requires more than one word in order to be
Index: gcc/emit-rtl.c
===================================================================
--- gcc/emit-rtl.c	(revision 204918)
+++ gcc/emit-rtl.c	(working copy)
@@ -5820,9 +5820,9 @@  init_emit_once (void)
   else
     const_true_rtx = gen_rtx_CONST_INT (VOIDmode, STORE_FLAG_VALUE);
 
-  REAL_VALUE_FROM_INT (dconst0,   0, double_mode);
-  REAL_VALUE_FROM_INT (dconst1,   1, double_mode);
-  REAL_VALUE_FROM_INT (dconst2,   2, double_mode);
+  real_from_integer (&dconst0, double_mode, wi::zero (32), SIGNED);
+  real_from_integer (&dconst1, double_mode, wi::one (32), SIGNED);
+  real_from_integer (&dconst2, double_mode, wi::two (32), SIGNED);
 
   dconstm1 = dconst1;
   dconstm1.sign = 1;
Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c	(revision 204918)
+++ gcc/fold-const.c	(working copy)
@@ -6527,7 +6527,7 @@  fold_single_bit_test_into_sign_test (loc
 	  /* This is only a win if casting to a signed type is cheap,
 	     i.e. when arg00's type is not a partial mode.  */
 	  && TYPE_PRECISION (TREE_TYPE (arg00))
-	     == GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (arg00))))
+	     == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (arg00))))
 	{
 	  tree stype = signed_type_for (TREE_TYPE (arg00));
 	  return fold_build2_loc (loc, code == EQ_EXPR ? GE_EXPR : LT_EXPR,
@@ -11960,7 +11960,7 @@  fold_binary_loc (location_t loc,
 	    zerobits = ((((unsigned HOST_WIDE_INT) 1) << shiftc) - 1);
 	  else if (TREE_CODE (arg0) == RSHIFT_EXPR
 		   && TYPE_PRECISION (TREE_TYPE (arg0))
-		      == GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (arg0))))
+		      == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (arg0))))
 	    {
 	      prec = TYPE_PRECISION (TREE_TYPE (arg0));
 	      tree arg00 = TREE_OPERAND (arg0, 0);
@@ -11971,7 +11971,7 @@  fold_binary_loc (location_t loc,
 		{
 		  tree inner_type = TREE_TYPE (TREE_OPERAND (arg00, 0));
 		  if (TYPE_PRECISION (inner_type)
-		      == GET_MODE_BITSIZE (TYPE_MODE (inner_type))
+		      == GET_MODE_PRECISION (TYPE_MODE (inner_type))
 		      && TYPE_PRECISION (inner_type) < prec)
 		    {
 		      prec = TYPE_PRECISION (inner_type);
@@ -13652,15 +13652,11 @@  fold_binary_loc (location_t loc,
 
 	    else if (wi::eq_p (arg1, signed_max)
 		     && TYPE_UNSIGNED (arg1_type)
-		     /* KENNY QUESTIONS THE CHECKING OF THE BITSIZE
-			HERE.  HE FEELS THAT THE PRECISION SHOULD BE
-			CHECKED */
-
 		     /* We will flip the signedness of the comparison operator
 			associated with the mode of arg1, so the sign bit is
 			specified by this mode.  Check that arg1 is the signed
 			max associated with this sign bit.  */
-		     && prec == GET_MODE_BITSIZE (TYPE_MODE (arg1_type))
+		     && prec == GET_MODE_PRECISION (TYPE_MODE (arg1_type))
 		     /* signed_type does not work on pointer types.  */
 		     && INTEGRAL_TYPE_P (arg1_type))
 	      {
@@ -15690,7 +15686,8 @@  tree_call_nonnegative_warnv_p (tree type
 	    if ((n & 1) == 0)
 	      {
 		REAL_VALUE_TYPE cint;
-		real_from_integer (&cint, VOIDmode, n, SIGNED);
+		real_from_integer (&cint, VOIDmode, 
+				   wi::shwi (n, HOST_BITS_PER_WIDE_INT), SIGNED);
 		if (real_identical (&c, &cint))
 		  return true;
 	      }
Index: gcc/gcse.c
===================================================================
--- gcc/gcse.c	(revision 204918)
+++ gcc/gcse.c	(working copy)
@@ -1997,13 +1997,6 @@  prune_insertions_deletions (int n_elems)
 	bitmap_clear_bit (pre_delete_map[i], j);
     }
 
-  if (dump_file)
-    {
-      dump_bitmap_vector (dump_file, "pre_insert_map", "", pre_insert_map, n_edges);
-      dump_bitmap_vector (dump_file, "pre_delete_map", "", pre_delete_map,
-			   last_basic_block);
-    }
-
   sbitmap_free (prune_exprs);
   free (insertions);
   free (deletions);
Index: gcc/gensupport.c
===================================================================
--- gcc/gensupport.c	(revision 204918)
+++ gcc/gensupport.c	(working copy)
@@ -2807,7 +2807,6 @@  static const struct std_pred_table std_p
   {"immediate_operand", false, true, {UNKNOWN}},
   {"const_int_operand", false, false, {CONST_INT}},
 #if TARGET_SUPPORTS_WIDE_INT
-  {"const_wide_int_operand", false, false, {CONST_WIDE_INT}},
   {"const_scalar_int_operand", false, false, {CONST_INT, CONST_WIDE_INT}},
   {"const_double_operand", false, false, {CONST_DOUBLE}},
 #else
Index: gcc/gimple-fold.c
===================================================================
--- gcc/gimple-fold.c	(revision 204918)
+++ gcc/gimple-fold.c	(working copy)
@@ -3319,7 +3319,8 @@  gimple_val_nonnegative_real_p (tree val)
 		  if ((n & 1) == 0)
 		    {
 		      REAL_VALUE_TYPE cint;
-		      real_from_integer (&cint, VOIDmode, n, SIGNED);
+		      real_from_integer (&cint, VOIDmode, 
+					 wi::shwi (n, HOST_BITS_PER_WIDE_INT), SIGNED);
 		      if (real_identical (&c, &cint))
 			return true;
 		    }
Index: gcc/java/expr.c
===================================================================
--- gcc/java/expr.c	(revision 204918)
+++ gcc/java/expr.c	(working copy)
@@ -1259,7 +1259,7 @@  expand_java_pushc (int ival, tree type)
   else if (type == float_type_node || type == double_type_node)
     {
       REAL_VALUE_TYPE x;
-      REAL_VALUE_FROM_INT (x, ival, TYPE_MODE (type));
+      real_from_integer (&x, TYPE_MODE (type), wi::shwi (ival, sizeof (int) * 8), SIGNED);
       value = build_real (type, x);
     }
   else
Index: gcc/lcm.c
===================================================================
--- gcc/lcm.c	(revision 204918)
+++ gcc/lcm.c	(working copy)
@@ -64,7 +64,6 @@  along with GCC; see the file COPYING3.
 #include "sbitmap.h"
 #include "dumpfile.h"
 
-#define LCM_DEBUG_INFO 1
 /* Edge based LCM routines.  */
 static void compute_antinout_edge (sbitmap *, sbitmap *, sbitmap *, sbitmap *);
 static void compute_earliest (struct edge_list *, int, sbitmap *, sbitmap *,
@@ -107,7 +106,6 @@  compute_antinout_edge (sbitmap *antloc,
   /* We want a maximal solution, so make an optimistic initialization of
      ANTIN.  */
   bitmap_vector_ones (antin, last_basic_block);
-  bitmap_vector_clear (antout, last_basic_block);
 
   /* Put every block on the worklist; this is necessary because of the
      optimistic initialization of ANTIN above.  */
@@ -434,7 +432,6 @@  pre_edge_lcm (int n_exprs, sbitmap *tran
 
   /* Allocate an extra element for the exit block in the laterin vector.  */
   laterin = sbitmap_vector_alloc (last_basic_block + 1, n_exprs);
-  bitmap_vector_clear (laterin, last_basic_block);
   compute_laterin (edge_list, earliest, antloc, later, laterin);
 
 #ifdef LCM_DEBUG_INFO
Index: gcc/real.c
===================================================================
--- gcc/real.c	(revision 204918)
+++ gcc/real.c	(working copy)
@@ -2147,45 +2147,7 @@  real_from_string3 (REAL_VALUE_TYPE *r, c
     real_convert (r, mode, r);
 }
 
-/* Initialize R from a HOST_WIDE_INT.  */
-
-void
-real_from_integer (REAL_VALUE_TYPE *r, enum machine_mode mode,
-		   HOST_WIDE_INT val, signop sgn)
-{
-  if (val == 0)
-    get_zero (r, 0);
-  else
-    {
-      memset (r, 0, sizeof (*r));
-      r->cl = rvc_normal;
-      r->sign = val < 0 && sgn == SIGNED;
-      SET_REAL_EXP (r, HOST_BITS_PER_WIDE_INT);
-
-      /* TODO: This fails for -MAXHOSTWIDEINT, wide_int version would
-	 have worked.  */
-      if (r->sign)
-	val = -val;
-
-      if (HOST_BITS_PER_LONG == HOST_BITS_PER_WIDE_INT)
-	r->sig[SIGSZ-1] = val;
-      else
-	{
-	  gcc_assert (HOST_BITS_PER_LONG*2 == HOST_BITS_PER_WIDE_INT);
-	  r->sig[SIGSZ-1] = val >> (HOST_BITS_PER_LONG - 1) >> 1;
-	  r->sig[SIGSZ-2] = val;
-	}
-
-      normalize (r);
-    }
-
-  if (DECIMAL_FLOAT_MODE_P (mode))
-    decimal_from_integer (r);
-  else if (mode != VOIDmode)
-    real_convert (r, mode, r);
-}
-
-/* Initialize R from the integer pair HIGH+LOW.  */
+/* Initialize R from the wide_int VAL_IN.  The MODE is not VOIDmode,*/
 
 void
 real_from_integer (REAL_VALUE_TYPE *r, enum machine_mode mode,
@@ -2356,7 +2318,8 @@  ten_to_ptwo (int n)
 	  for (i = 0; i < n; ++i)
 	    t *= t;
 
-	  real_from_integer (&tens[n], VOIDmode, t, UNSIGNED);
+	  real_from_integer (&tens[n], VOIDmode, 
+			     wi::shwi (t, HOST_BITS_PER_WIDE_INT), UNSIGNED);
 	}
       else
 	{
@@ -2395,7 +2358,7 @@  real_digit (int n)
   gcc_assert (n <= 9);
 
   if (n > 0 && num[n].cl == rvc_zero)
-    real_from_integer (&num[n], VOIDmode, n, UNSIGNED);
+    real_from_integer (&num[n], VOIDmode, wi::shwi (n, sizeof (int) * 8), UNSIGNED);
 
   return &num[n];
 }
Index: gcc/real.h
===================================================================
--- gcc/real.h	(revision 204918)
+++ gcc/real.h	(working copy)
@@ -277,10 +277,6 @@  extern int real_from_string (REAL_VALUE_
 /* Wrapper to allow different internal representation for decimal floats. */
 extern void real_from_string3 (REAL_VALUE_TYPE *, const char *, enum machine_mode);
 
-/* Initialize R from an integer.  */
-extern void real_from_integer (REAL_VALUE_TYPE *, enum machine_mode,
-			       HOST_WIDE_INT, signop);
-
 extern long real_to_target_fmt (long *, const REAL_VALUE_TYPE *,
 				const struct real_format *);
 extern long real_to_target (long *, const REAL_VALUE_TYPE *, enum machine_mode);
Index: gcc/recog.c
===================================================================
--- gcc/recog.c	(revision 204918)
+++ gcc/recog.c	(working copy)
@@ -1198,19 +1198,6 @@  const_scalar_int_operand (rtx op, enum m
   return 1;
 }
 
-/* Returns 1 if OP is an operand that is a CONST_WIDE_INT of mode
-   MODE.  This most likely is not as useful as
-   const_scalar_int_operand since it does not accept CONST_INTs, but
-   is here for consistancy.  */
-int
-const_wide_int_operand (rtx op, enum machine_mode mode)
-{
-  if (!CONST_WIDE_INT_P (op))
-    return 0;
-
-  return const_scalar_int_operand (op, mode);
-}
-
 /* Returns 1 if OP is an operand that is a constant integer or constant
    floating-point number of MODE.  */
 
Index: gcc/rtl.c
===================================================================
--- gcc/rtl.c	(revision 204918)
+++ gcc/rtl.c	(working copy)
@@ -233,6 +233,8 @@  cwi_output_hex (FILE *outfile, const_rtx
   int i = CWI_GET_NUM_ELEM (x);
   gcc_assert (i > 0);
   if (CWI_ELT (x, i-1) == 0)
+    /* The HOST_WIDE_INT_PRINT_HEX prepends a 0x only if the val is
+       non zero.  We want all numbers to have a 0x prefix.  */
     fprintf (outfile, "0x");
   fprintf (outfile, HOST_WIDE_INT_PRINT_HEX, CWI_ELT (x, --i));
   while (--i >= 0)
Index: gcc/tree-call-cdce.c
===================================================================
--- gcc/tree-call-cdce.c	(revision 204918)
+++ gcc/tree-call-cdce.c	(working copy)
@@ -199,7 +199,8 @@  check_pow (gimple pow_call)
         return false;
       if (REAL_VALUES_LESS (bcv, dconst1))
         return false;
-      real_from_integer (&mv, TYPE_MODE (TREE_TYPE (base)), 256, UNSIGNED);
+      real_from_integer (&mv, TYPE_MODE (TREE_TYPE (base)), 
+			 wi::shwi (256, 32), UNSIGNED);
       if (REAL_VALUES_LESS (mv, bcv))
         return false;
       return true;
@@ -416,7 +417,7 @@  gen_conditions_for_pow_cst_base (tree ba
   REAL_VALUE_TYPE bcv = TREE_REAL_CST (base);
   gcc_assert (!REAL_VALUES_EQUAL (bcv, dconst1)
               && !REAL_VALUES_LESS (bcv, dconst1));
-  real_from_integer (&mv, TYPE_MODE (TREE_TYPE (base)), 256, UNSIGNED);
+  real_from_integer (&mv, TYPE_MODE (TREE_TYPE (base)), wi::shwi (256, 32), UNSIGNED);
   gcc_assert (!REAL_VALUES_LESS (mv, bcv));
 
   exp_domain = get_domain (0, false, false,
Index: gcc/tree-cfg.c
===================================================================
--- gcc/tree-cfg.c	(revision 204918)
+++ gcc/tree-cfg.c	(working copy)
@@ -2718,7 +2718,6 @@  verify_expr (tree *tp, int *walk_subtree
 	      return t;
 	    }
 	  else if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
-		   && !AGGREGATE_TYPE_P (TREE_TYPE (t))
 		   && TYPE_MODE (TREE_TYPE (t)) != BLKmode
 		   && (GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (t)))
 		       != tree_to_uhwi (TREE_OPERAND (t, 1))))
Index: gcc/tree-ssa-math-opts.c
===================================================================
--- gcc/tree-ssa-math-opts.c	(revision 204918)
+++ gcc/tree-ssa-math-opts.c	(working copy)
@@ -1148,7 +1148,7 @@  gimple_expand_builtin_pow (gimple_stmt_i
      multiplication sequence when profitable.  */
   c = TREE_REAL_CST (arg1);
   n = real_to_integer (&c);
-  real_from_integer (&cint, VOIDmode, n, SIGNED);
+  real_from_integer (&cint, VOIDmode, wi::shwi (n, HOST_BITS_PER_WIDE_INT), SIGNED);
   c_is_int = real_identical (&c, &cint);
 
   if (c_is_int
@@ -1194,7 +1194,7 @@  gimple_expand_builtin_pow (gimple_stmt_i
   /* Optimize pow(x,0.75) = sqrt(x) * sqrt(sqrt(x)) unless we are
      optimizing for space.  Don't do this optimization if we don't have
      a hardware sqrt insn.  */
-  real_from_integer (&dconst3_4, VOIDmode, 3, SIGNED);
+  real_from_integer (&dconst3_4, VOIDmode, wi::shwi (3, 32), SIGNED);
   SET_REAL_EXP (&dconst3_4, REAL_EXP (&dconst3_4) - 2);
 
   if (flag_unsafe_math_optimizations
@@ -1258,7 +1258,7 @@  gimple_expand_builtin_pow (gimple_stmt_i
      Do not calculate the powi factor when n/2 = 0.  */
   real_arithmetic (&c2, MULT_EXPR, &c, &dconst2);
   n = real_to_integer (&c2);
-  real_from_integer (&cint, VOIDmode, n, SIGNED);
+  real_from_integer (&cint, VOIDmode, wi::shwi (n, HOST_BITS_PER_WIDE_INT), SIGNED);
   c2_is_int = real_identical (&c2, &cint);
 
   if (flag_unsafe_math_optimizations
@@ -1306,11 +1306,11 @@  gimple_expand_builtin_pow (gimple_stmt_i
      different from pow(x, 1./3.) due to rounding and behavior with
      negative x, we need to constrain this transformation to unsafe
      math and positive x or finite math.  */
-  real_from_integer (&dconst3, VOIDmode, 3, SIGNED);
+  real_from_integer (&dconst3, VOIDmode, wi::shwi (3, HOST_BITS_PER_WIDE_INT), SIGNED);
   real_arithmetic (&c2, MULT_EXPR, &c, &dconst3);
   real_round (&c2, mode, &c2);
   n = real_to_integer (&c2);
-  real_from_integer (&cint, VOIDmode, n, SIGNED);
+  real_from_integer (&cint, VOIDmode, wi::shwi (n, HOST_BITS_PER_WIDE_INT), SIGNED);
   real_arithmetic (&c2, RDIV_EXPR, &cint, &dconst3);
   real_convert (&c2, mode, &c2);
 
Index: gcc/tree-ssa-reassoc.c
===================================================================
--- gcc/tree-ssa-reassoc.c	(revision 204918)
+++ gcc/tree-ssa-reassoc.c	(working copy)
@@ -1048,7 +1048,7 @@  decrement_power (gimple stmt)
       arg1 = gimple_call_arg (stmt, 1);
       c = TREE_REAL_CST (arg1);
       power = real_to_integer (&c) - 1;
-      real_from_integer (&cint, VOIDmode, power, SIGNED);
+      real_from_integer (&cint, VOIDmode, wi::shwi (power, HOST_BITS_PER_WIDE_INT), SIGNED);
       gimple_call_set_arg (stmt, 1, build_real (TREE_TYPE (arg1), cint));
       return power;
 
@@ -3624,7 +3624,8 @@  acceptable_pow_call (gimple stmt, tree *
 	return false;
 
       *exponent = real_to_integer (&c);
-      real_from_integer (&cint, VOIDmode, *exponent, SIGNED);
+      real_from_integer (&cint, VOIDmode, 
+			 wi::shwi (*exponent, HOST_BITS_PER_WIDE_INT), SIGNED);
       if (!real_identical (&c, &cint))
 	return false;
 
Index: gcc/tree.c
===================================================================
--- gcc/tree.c	(revision 204918)
+++ gcc/tree.c	(working copy)
@@ -8536,8 +8536,18 @@  retry:
     return true;
 
   /* Third, unsigned integers with top bit set never fit signed types.  */
-  if (!TYPE_UNSIGNED (type) && sgn_c == UNSIGNED && wi::neg_p (c))
-    return false;
+  if (!TYPE_UNSIGNED (type) && sgn_c == UNSIGNED)
+    {
+      int uprec = GET_MODE_PRECISION (TYPE_MODE TREE_TYPE (c));
+      if (uprec < TYPE_PRECISION (TREE_TYPE (c)))
+	{
+	  wide_int x = wi::sext (c, uprec);
+	  if (wi::neg_p (x) || wi::ne_p (x, c))
+	    return false;
+	}
+      else if (wi::neg_p (c))
+	return false;
+    }
 
   /* If we haven't been able to decide at this point, there nothing more we
      can check ourselves here.  Look at the base type if we have one and it