Use unsigned(-1) for lshift

Marc Glisse marc.glisse@inria.fr
Sat May 25 06:36:00 GMT 2013


On Sat, 25 May 2013, Segher Boessenkool wrote:

>> Index: tree-ssa-structalias.c
>> ===================================================================
>> --- tree-ssa-structalias.c	(revision 199289)
>> +++ tree-ssa-structalias.c	(working copy)
>> @@ -475,21 +475,21 @@ struct constraint_expr
>>
>>   /* Offset, in bits, of this constraint from the beginning of
>>      variables it ends up referring to.
>>
>>      IOW, in a deref constraint, we would deref, get the result set,
>>      then add OFFSET to each member.   */
>>   HOST_WIDE_INT offset;
>> };
>> 
>> /* Use 0x8000... as special unknown offset.  */
>> -#define UNKNOWN_OFFSET ((HOST_WIDE_INT)-1 << (HOST_BITS_PER_WIDE_INT-1))
>> +#define UNKNOWN_OFFSET ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT-1))
>
> This is still undefined behaviour (shifting a 1 into the sign bit)?

Not in C++ after DR1457, where it becomes implementation defined (depends 
on conversions from unsigned to signed, likely ok on all 2s complement 
platforms). But we should indeed use HOST_WIDE_INT_MIN instead (the 
definition of that one might also need fixing if we don't want to rely on 
implementation defined behavior, but it reduces the number of places to 
fix). Consider this part of the patch changed to:

 	* tree-ssa-structalias.c (UNKNOWN_OFFSET): Use HOST_WIDE_INT_MIN.

  /* Use 0x8000... as special unknown offset.  */
-#define UNKNOWN_OFFSET ((HOST_WIDE_INT)-1 << (HOST_BITS_PER_WIDE_INT-1))
+#define UNKNOWN_OFFSET HOST_WIDE_INT_MIN



(A way that still relies on 2s complement but not on conversions from 
unsigned to negative signed would be to define HOST_WIDE_INT_MAX as 
HOST_WIDE_INT_M1U/2 cast to signed and HOST_WIDE_INT_MIN as 
-HOST_WIDE_INT_MAX-1. Otherwise we'd have to include <limits.h>, or 
<limits> now we are doing C++, and rely on them giving safe values.)

-- 
Marc Glisse



More information about the Gcc-patches mailing list