[LLVMbugs] [Bug 4410] New: incorrect expansion for uint_to_fp

bugzilla-daemon at cs.uiuc.edu bugzilla-daemon at cs.uiuc.edu
Wed Jun 17 18:55:20 PDT 2009


           Summary: incorrect expansion for uint_to_fp
           Product: libraries
           Version: trunk
          Platform: PC
        OS/Version: Windows NT
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Common Code Generator Code
        AssignedTo: unassignedbugs at nondot.org
        ReportedBy: benedict.gaster at amd.com
                CC: llvmbugs at cs.uiuc.edu

Consider the following C code:

float convert(uint64_t u)
    return (float)u;

which as LLVM IR is:

define float @convert(i64 %a) nounwind {
        %tmp12 = uitofp i64 %a to float         ; <float> [#uses=1]
        ret float %tmp12

Compiling this with llc -march=x86-64 gives:

ASM (amd64):
.LCPI1_0:                                       # i64
        .quad   6881500230622117888
        cvtsi2ssq       %rdi, %xmm0
        testq   %rdi, %rdi
        sets    %al
        movzbl  %al, %eax
        addss   .LCPI1_0(,%rax,4), %xmm0

The ā€œCā€ equivalent code is:

float convert(uint64_t u)
    static float fudge[] = { 0.0f, 0x1.0p64f };
    float f = (float)(int64_t)u;
    f += fudge[msb(u)];
    return f;

The adjustment by 2^64 to counteract the effect of converting treating ā€˜uā€™
as a signed value does not address rounding properly.
For example, in rounding to the nearest even mode, converting
0xffffff7fffffffffull with this code returns 0x1p+64 instead of the expected

To produce the correct values in all rounding modes, the following expansion
should be used instead:

float convert(uint64_t u)
    if (msb(u)) {
        return 2.0f * (float)(int64_t)((u >> 1) | (u & 1));
    else {
        return (float)(int64_t)f;

Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.

More information about the llvm-bugs mailing list