[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
http://llvm.org/bugs/show_bug.cgi?id=4410
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:
LL:
define float @convert(i64 %a) nounwind {
entry:
%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
convert:
cvtsi2ssq %rdi, %xmm0
testq %rdi, %rdi
sets %al
movzbl %al, %eax
addss .LCPI1_0(,%rax,4), %xmm0
ret
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
0x1.fffffep+63.
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