[PATCH, rtl-optimization]: Fix PR37997: ICE shifting byte to the right with constant > 7FFFFFFF

Joseph S. Myers joseph@codesourcery.com
Wed Sep 9 12:26:00 GMT 2009


On Wed, 9 Sep 2009, Eric Botcazou wrote:

> > 0x7fffffff is signed, 0x80000000 unsigned; other than that, no.
> 
> OK, the (int) v1 >> 0x80000000 is shortened to "char" in build_binary_op:
> 
> 	  if (TYPE_PRECISION (TREE_TYPE (arg0)) < TYPE_PRECISION (result_type)
> 	      /* We can shorten only if the shift count is less than the
> 		 number of bits in the smaller type size.  */
> 	      && compare_tree_int (op1, TYPE_PRECISION (TREE_TYPE (arg0))) < 0
> 	      /* We cannot drop an unsigned shift after sign-extension.  */
> 	      && (!TYPE_UNSIGNED (final_type) || unsigned_arg))
> 	    {
> 	      /* Do an unsigned shift if the operand was zero-extended.  */
> 	      result_type
> 		= c_common_signed_or_unsigned_type (unsigned_arg,
> 						    TREE_TYPE (arg0));
> 	      /* Convert value-to-be-shifted to that type.  */
> 	      if (TREE_TYPE (op0) != result_type)
> 		op0 = convert (result_type, op0);
> 	      converted = 1;
> 	    }
> 
> because
> 
>   compare_tree_int (op1, TYPE_PRECISION (TREE_TYPE (arg0))) < 0
> 
> return true since op1 is -2147483648.
> 
> It seems to me that the problem should be fixed there.

I fail to see any problem.  build_binary_op earlier converted all shift 
counts to type int, but there is no problem with that since it will only 
change the value in cases of undefined behavior and you need to handle 
shifts by INT_MIN anyway.  There is no indication I can see in anything 
you have posted in this dicussion that the front end is generating any 
invalid trees or GIMPLE; it's for the expanders to handle arbitrary 
constant or nonconstant shift counts whose type may be unrelated to the 
type of the expression being shifted (where if it is known that the count 
is negative or >= width of type, the result is arbitrary).

-- 
Joseph S. Myers
joseph@codesourcery.com



More information about the Gcc-patches mailing list