[PATCH] Fix problematic folding

Joseph S. Myers joseph@codesourcery.com
Thu Jul 31 21:18:00 GMT 2008


On Thu, 31 Jul 2008, Eric Botcazou wrote:

> Hi,
> 
> the recent conversion of GNAT to boolean_type_node for Standard.Boolean has 
> uncovered a problem in the constant folder, namely fold_binary:
> 
>       /* A - B -> A + (-B) if B is easily negatable.  */
>       if (negate_expr_p (arg1)
> 	  && ((FLOAT_TYPE_P (type)
>                /* Avoid this transformation if B is a positive REAL_CST.  */
> 	       && (TREE_CODE (arg1) != REAL_CST
> 		   ||  REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg1))))
> 	      || INTEGRAL_TYPE_P (type)))
> 	return fold_build2 (PLUS_EXPR, type,
> 			    fold_convert (type, arg0),
> 			    fold_convert (type, negate_expr (arg1)));
> 
> Suppose that the type is unsigned integral with precision 1 (and QImode), then 
> A-1 is turned into A+1 by this transformation, which changes the final code 
> since A+1 doesn't wrap around in QImode (255 would have been needed).

The target-independent semantics of integer arithmetic on trees or tuples 
should be based on the precision not the mode; A+1 *should* wrap around.  
reduce_to_bit_field_precision is meant to ensure this when we expand to 
RTL; you could always lower (to arithmetic based only on types natively 
supported by the machine) at some other time if that were in some way 
beneficial, but if such types are present in the trees then their 
semantics should depend on the precision.

I think your bug must be somewhere other than the folder.

-- 
Joseph S. Myers
joseph@codesourcery.com



More information about the Gcc-patches mailing list