[LLVMdev] confused about float literals

Joe Armstrong joearms at gmail.com
Wed Apr 27 01:03:04 PDT 2011


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.

Why 28 bits? - 32 bits might be understandable but not 28.

If I manually edit the hex constant to the exact 64 bit representation
then I get an error. for example

 store float 0x400928F5C28F5C29, float* %f <= best possible representation
    llvm-as: bug2.s:11:15: error: floating point constant invalid for type

so the "as if they were doubles" bit seems wrong -

try clearing 24 bits

  store float 0x400928F5C2000000, float* %f <= low order 24 bits cleared	
    llvm-as: bug2.s:12:18: error: floating point constant invalid for type

clear 28 bits

   store float 0x400928F5C0000000, float* %f <= low order 28 bits cleared	
     no error

or 32 bits

   store float 0x400928F500000000, float* %f <= low order 32 bits cleared
     no error

So the Hex constant seems to be obtained by taking the 64 bit value
and clearing the
low order 28 bits this seems bit arbitrary to me - something smells a
bit fishy here

/Joe


>
> As for your other question, I don't know that there's a good reason
> that the parser isn't more accommodating.
>
> John.
>




More information about the llvm-dev mailing list