[LLVMdev] Floating point constants (bug?)

Reid Spencer rspencer at reidspencer.com
Sun Jul 15 15:58:17 PDT 2007


Hi Ben,

This seems like a bug to me. The code that is doing this is in
AsmWriter.cpp:

   std::string StrVal = ftostr(CFP->getValue());

    // Check to make sure that the stringized number is not some string
like
    // "Inf" or NaN, that atof will accept, but the lexer will not.
Check that
    // the string matches the "[-+]?[0-9]" regex.
    //
    if ((StrVal[0] >= '0' && StrVal[0] <= '9') ||
        ((StrVal[0] == '-' || StrVal[0] == '+') &&
         (StrVal[1] >= '0' && StrVal[1] <= '9')))
      // Reparse stringized version!
      if (atof(StrVal.c_str()) == CFP->getValue()) {
        Out << StrVal;
        return;
      }

    // Otherwise we could not reparse it to exactly the same value, so
we must
    // output the string in hexadecimal format!
    assert(sizeof(double) == sizeof(uint64_t) &&
           "assuming that double is 64 bits!");
    Out << "0x" << utohexstr(DoubleToBits(CFP->getValue()));

This seems correct to me. It is saying if we can't convert binary to
text and back again then put it out in hex notation. But, there could be
something wrong with this logic.

So ..

On Sun, 2007-07-15 at 17:48 -0400, Ben Chambers wrote:
> >From the language guide:
> 
> "The one non-intuitive notation for constants is the optional
> hexadecimal form of floating point constants. For example, the form
> 'double 0x432ff973cafa8000' is equivalent to (but harder to read than)
> 'double 4.5e+15'. The only time hexadecimal floating point constants
> are required (and the only time that they are generated by the
> disassembler) is when a floating point constant must be emitted but it
> cannot be represented as a decimal floating point number. For example,
> NaN's, infinities, and other special values are represented in their
> IEEE hexadecimal format so that assembly and disassembly do not cause
> any bits to change in the constants."
> 
> When I compile the following simple program with llvm-gcc -O0 -c
> --emit-llvm, run it through opt --raiseallocs --lowerconstexps and
> llvm-dis, I get a floating point number in hexadecimal that is not one
> of the above mentioned special forms.
> 
> #include <stdlib.h>
> #include <stdio.h>
> 
> int main() {
>    float f = 5.66;
>    return (int)(f + 1.33);
> }
> 
> It will emit:
> 
> ...
>   store float 0x4016A3D700000000, float* %f
> ...
> 
> Which is correct, but is a pain to have to parse.  

I reproduced this on an old environment I had, but not with head. FYI,
the optimization passes don't matter. You can directly disassemble the
output of llvm-gcc and you'll get the same result.

> Ideally, floating
> point would be printed like it says in the language guide, only using
> the hexadecimal representation when decimal representation is
> impossible.  In this case, however, 5.66e+00 seems pretty reasonable
> (and easier to write down/read).  Is this a bug?  

Seems so :(

> Am I running things
> wrong to get these printed out in decimal?  

No.

> I don't think I am because
> the 1.33 for the addition is printed out correctly.

Okay.

Could you please file a bug for this at http://llvm.org/bugs ?

That way it'll get tracked and we're more likely to fix it.

Thanks, Ben.

Reid.
> 
> Thanks,
> Ben Chambers
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev




More information about the llvm-dev mailing list