[PATCH] Fix problem in fold_binary

Eric Botcazou ebotcazou@adacore.com
Sun Nov 5 10:34:00 GMT 2006


Hi,

I ran into a problem in fold_binary with a 3.4-based Ada compiler and, while I 
didn't manage to reproduce the wrong code bug with the mainline compiler, I 
think the problem is latent there too.

The failure mode is as follows: fold_binary is invoked on (64 > 127) where 64 
and 127 have the same unsigned QImode 7-bit precision integral type.  Then

       /* Comparisons with the highest or lowest possible integer of
	 the specified size will have known values.  */
       {
	int width = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (arg1)));

 	if (TREE_CODE (arg1) == INTEGER_CST
 	    && ! TREE_CONSTANT_OVERFLOW (arg1)
 	    && width <= 2 * HOST_BITS_PER_WIDE_INT
	    && (INTEGRAL_TYPE_P (TREE_TYPE (arg1))
		|| POINTER_TYPE_P (TREE_TYPE (arg1))))

Note that the size of the mode of the type is used, not its precision.  As a 
consequence, the whole logic to compute the highest or lowest possible 
integer is fooled and the natural folding is not triggered.  However, upon 
reaching

 	    else if (!in_gimple_form
 		     && TREE_INT_CST_HIGH (arg1) == signed_max_hi
 		     && TREE_INT_CST_LOW (arg1) == signed_max_lo
		     && TYPE_UNSIGNED (TREE_TYPE (arg1))
 		     /* signed_type does not work on pointer types.  */
		     && INTEGRAL_TYPE_P (TREE_TYPE (arg1)))
 	      {
 		/* The following case also applies to X < signed_max+1
 		   and X >= signed_max+1 because previous transformations.  */

127 happens to be the signed_max of any 8-bit unsigned type so the lines

		/* The following case also applies to X < signed_max+1
		   and X >= signed_max+1 because previous transformations.  */
		if (code == LE_EXPR || code == GT_EXPR)
		  {
		    tree st0, st1;
		    st0 = lang_hooks.types.signed_type (TREE_TYPE (arg0));
		    st1 = lang_hooks.types.signed_type (TREE_TYPE (arg1));
		    return fold_build2 (code == LE_EXPR ? GE_EXPR: LT_EXPR,
			       		type, fold_convert (st0, arg0),
			       	
are executed and yield

  -64 (overflow) < 0

which evaluates to true.


Proposed fix attached, tested on x86_64-suse-linux.  OK for mainline?


2006-11-05  Eric Botcazou  <ebotcazou@adacore.com>

	* fold-const.c (fold_binary) <LT_EXPR>: Use the precision of the
	type instead of the size of its mode to compute the highest and
	lowest possible values.  Still check the size of the mode before
	flipping the signedness of the comparison.


:ADDPATCH middle-end:

-- 
Eric Botcazou
-------------- next part --------------
A non-text attachment was scrubbed...
Name: fa17-017-2_fsf.diff
Type: text/x-diff
Size: 2150 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20061105/dd95e1ce/attachment.bin>


More information about the Gcc-patches mailing list