[llvm-commits] [llvm] r100233 - in /llvm/trunk: ./ include/llvm/Support/ lib/Target/ARM/ lib/Target/ARM/Disassembler/ test/MC/Disassembler/ utils/TableGen/

Jakob Stoklund Olesen stoklund at 2pi.dk
Sun Apr 4 21:30:12 PDT 2010


On Apr 4, 2010, at 9:09 PM, Chris Lattner wrote:

> On Apr 4, 2010, at 9:03 PM, Jakob Stoklund Olesen wrote:
>>>>> Shift left + shift right is more easily recognized by the code generator as a sext.
>>>> 
>>>> Sure, but if we're not building with -fwrapv, it overflows the int and
>>>> causes undefined behaviour.
>>> 
>>> Huh?  In what case?
>> 
>> If you left-shift a positive number until it goes negative, that's an
>> overflow. At least that's how I understand it.
> 
> You can shift left an N bit number between 0 and N-1 bits safely without overflow.

Only an unsigned number. From the C++0X working draft:

"The value of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are zero-filled. If E1 has an unsigned type, the value of the result is E1 × 2^E2, reduced modulo one more than the maximum value representable in the result type. Otherwise, if E1 has a signed type and non-negative value, and E1 × 2^E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined."

You would have to cast to unsigned, left-shift, cast to signed, and right-shift. That might work, but the right-shift is implementation-defined:

"The value of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type or if E1 has a signed type and a non-negative value, the value of the result is the integral part of the quotient of E1/2^E2. If E1 has a signed type and a negative value, the resulting value is implementation-defined."

I have never seen a compiler doing anything but an arithmetic right-shift for negative numbers, but I have seen saturation on overflow.





More information about the llvm-commits mailing list