[LLVMdev] confused about float literals

Joe Armstrong joearms at gmail.com
Tue Apr 26 02:07:49 PDT 2011

I assumed that C floats are 32 bits and doubles 64 bits ... but

This code

int  main(){
  float f;
  double f1;
  f = 3.145;
  f1 = 3.145;

Compiles (via clang) to:

  ; ModuleID = 'test101.c'
  target datalayout =
  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

[as calculated by http://babbage.cs.qc.edu/IEEE-754/Decimal.html
 and my own independent program]

But the given literal is neither of these. Are floats 32 bits? and if so why is
the literal value represented in 64 bits and why are the low order
bits all zero?

What's going on here?

Secondly, I was smitten by the behavior of the llvm-as

This code:

  %f = alloca float, align 4
  store float 1.25, float* %f

Assembles correctly:

But a minor edit to this:

  %f = alloca float, align 4
  store float 1.251, float* %f

Does not - but gives the error message

     error: floating point constant invalid for type
     store float 1.251, float* %f

This violates the principle of least astonishment - and yes I know the
manual says it *should* do this - but it's not exactly helpful.

If I see a floating point literal in my C code (like 1.25) I'd rather
like to see the same floating point literal in the assembler, and
not a (mysterious) 64 bit hex literal.



More information about the llvm-dev mailing list