<html>
<head>
<base href="https://bugs.llvm.org/">
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW - Incorrect optimization while converting from FP to Integer"
href="https://bugs.llvm.org/show_bug.cgi?id=45155">45155</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>Incorrect optimization while converting from FP to Integer
</td>
</tr>
<tr>
<th>Product</th>
<td>clang
</td>
</tr>
<tr>
<th>Version</th>
<td>9.0
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>Linux
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>normal
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>C
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedclangbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>code.optimizer@gmail.com
</td>
</tr>
<tr>
<th>CC</th>
<td>blitzrakete@gmail.com, dgregor@apple.com, erik.pilkington@gmail.com, llvm-bugs@lists.llvm.org, richard-llvm@metafoo.co.uk
</td>
</tr></table>
<p>
<div>
<pre>Given the following example where there is logic to guard the possible
generation of a floating point error if the double argument is >= LONG_MAX (and
as the comments say, negative values are being ignored):
[dparks@build-lin64 tmp]$ cat uint64.c
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <inttypes.h>
#define _GNU_SOURCE 1
#include <fenv.h>
static void __attribute__ ((constructor))
trapfpe ()
{
/* Enable some exceptions. At startup all exceptions are masked. */
feenableexcept (FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW);
}
double d_out_of_range = LONG_MAX;
double d_still_in_range = LONG_MAX-(1024*1024);
uint64_t __attribute__((noinline))
dbl_2_u64(double d)
{
// ignore -ive values - that's not the point
return (d < LONG_MAX) ? d : 0x8000000000000000ull;
}
int
main()
{
uint64_t u64;
u64 = dbl_2_u64(d_still_in_range);
printf("d=%f u=%" PRId64 ", u=%#" PRIx64 "\n", d_still_in_range, u64, u64);
u64 = dbl_2_u64(d_out_of_range);
printf("d=%f u=%" PRId64 ", u=%#" PRIx64 "\n", d_out_of_range, u64, u64);
}
[dparks@build-lin64 tmp]$
If compiled with clang 9.0:
[dparks@build-lin64 tmp]$ clang --version
clang version 9.0.0 (/home/<DELETED>/git/official/llvm/tools/clang
45898f3be1d37727502cd6342b14c19e7c94bfae) (/home/<DELETED>/git/official/llvm
5364ee5faec778f1ddf86b6b4b8452df7db191c5)
Target: x86_64-unknown-linux-gnu
Thread model: posix
[dparks@build-lin64 tmp]$ clang uint64.c -march=core2 -O0 -lm
uint64.c:13:3: warning: implicit declaration of function 'feenableexcept' is
invalid in C99 [-Wimplicit-function-declaration]
feenableexcept (FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW);
^
1 warning generated.
[dparks@build-lin64 tmp]$ ./a.out
d=9223372036853727232.000000 u=9223372036853727232, u=0x7ffffffffff00000
Floating point exception
[dparks@build-lin64 tmp]$
At any optimization level (-O0..-O3) the program will abort with a Floating
point exception.
The exception is caused because does not recognize the guard (x < LONG_MAX) and
converts the double to uint64_t and *then* chooses which result to return, the
unsigned integer or 0x8000000000000000ull (code sequence from -O3):
.LCPI1_0:
.quad 4890909195324358656 # double 9.2233720368547758E+18
.text
.globl dbl_2_u64
.p2align 4, 0x90
.type dbl_2_u64,@function
dbl_2_u64: # @dbl_2_u64
.cfi_startproc
# %bb.0:
movsd .LCPI1_0(%rip), %xmm1 # xmm1 = mem[0],zero
minsd %xmm1, %xmm0
movapd %xmm0, %xmm2
subsd %xmm1, %xmm2
cvttsd2si %xmm2, %rax
movabsq $-9223372036854775808, %rcx # imm = 0x8000000000000000
xorq %rax, %rcx
cvttsd2si %xmm0, %rax
ucomisd %xmm1, %xmm0
cmovaeq %rcx, %rax
retq
While code sequences where jumps have been eliminated, the above does not work.
If the code is modified to take into account negative number "( fabs(d) <
LONG_MAX )", floating point errors are still generated.</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>