<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>