[LLVMdev] confused about float literals

John McCall rjmccall at apple.com
Wed Apr 27 08:28:37 PDT 2011


On Apr 27, 2011, at 1:03 AM, Joe Armstrong wrote:
> On Wed, Apr 27, 2011 at 12:51 AM, John McCall <rjmccall at apple.com> wrote:
>> On Apr 26, 2011, at 2:07 AM, Joe Armstrong wrote:
>>> Compiles (via clang) to:
>>> 
>>>  ; ModuleID = 'test101.c'
>>>  target datalayout =
>>> "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
>>>  target triple = "i386-pc-linux-gnu"
>>> 
>>> define i32 @main() nounwind {
>>>  %1 = alloca i32, align 4                        ; <i32*> [#uses=3]
>>>  %f = alloca float, align 4                      ; <float*> [#uses=1]
>>>  %f1 = alloca double, align 8                    ; <double*> [#uses=1]
>>>  store i32 0, i32* %1
>>>  store float 0x400928F5C0000000, float* %f
>>>  store double 3.145000e+00, double* %f1
>>>  store i32 0, i32* %1
>>>  %2 = load i32* %1                               ; <i32> [#uses=1]
>>>  ret i32 %2
>>> }
>>> 
>>> This is very strange - what is 0x400928F5C0000000 ???
>>> the 32 bit hex representation of 3.145 is 0x404947ae, and,
>>> the 64 bit hex representation of 3.145 is 0x400928f5c28f5c29
>> 
>> For murky historical reasons, float literals are represented as
>> if they were doubles, but with the precision of a float.  It does
>> not change their semantics.
> 
> But what is 0x400928F5C0000000? it is NOT the 64 bit representation
> with the low order
> 32 bits zeroed - it is the 62 bit representation with the low order 28
> bits zeroed.

The exact bit representation of the float is laid out with the
corresponding bitwise representation of a double:  the sign
bit is copied over, the exponent is encoded in the larger width,
and the 23 bits of significand fills in the top 23 bits of significand
in the double.  A double has 52 bits of significand, so this means
that the last 29 bits of significand will always be ignored.  As an
error-detection measure, the IR parser requires them to be zero.

I don't think this is a great representation, and I think we'd be
open to someone changing the IR to at least use 32-bit hex
float literals.  There are a lot of tests which would have
to be updated, but that could be done with a perl script.

John.



More information about the llvm-dev mailing list