Floating point constants (bug?)

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Floating point constants (bug?)

Ben Chambers-4
>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.  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?  Am I running things
wrong to get these printed out in decimal?  I don't think I am because
the 1.33 for the addition is printed out correctly.

Thanks,
Ben Chambers
_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Floating point constants (bug?)

Reid Spencer-2
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
> [hidden email]         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Floating point constants (bug?)

Chris Lattner
In reply to this post by Ben Chambers-4
On Sun, 15 Jul 2007, Ben Chambers wrote:
> ...
>  store float 0x4016A3D700000000, float* %f
> ...
>
> Which is correct, but is a pain to have to parse.  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

The code is correct, please don't file a bug.  The number in question is
5.6599998474121094, not 5.66, which is the closest approximation to 5.66
you can get.

-Chris

--
http://nondot.org/sabre/
http://llvm.org/
_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Floating point constants (bug?)

Dale Johannesen

On Jul 15, 2007, at 5:09 PM, Chris Lattner wrote:

> On Sun, 15 Jul 2007, Ben Chambers wrote:
>> ...
>>  store float 0x4016A3D700000000, float* %f
>> ...
>>
>> Which is correct, but is a pain to have to parse.  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
>
> The code is correct, please don't file a bug.  The number in  
> question is
> 5.6599998474121094, not 5.66, which is the closest approximation to  
> 5.66
> you can get.

Yes.  However, every hex floating point number (barring NaNs and  
infinities)
does have an exact decimal representation, so we could use those  
consistently
if we wanted to.  Thus, 5.659999... as above instead of the original  
5.66.  These
can be thousands of digits long though.


_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev