[llvm-bugs] [Bug 45155] New: Incorrect optimization while converting from FP to Integer

via llvm-bugs llvm-bugs at lists.llvm.org
Mon Mar 9 09:59:07 PDT 2020


https://bugs.llvm.org/show_bug.cgi?id=45155

            Bug ID: 45155
           Summary: Incorrect optimization while converting from FP to
                    Integer
           Product: clang
           Version: 9.0
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: C
          Assignee: unassignedclangbugs at nondot.org
          Reporter: code.optimizer at gmail.com
                CC: blitzrakete at gmail.com, dgregor at apple.com,
                    erik.pilkington at gmail.com, llvm-bugs at lists.llvm.org,
                    richard-llvm at metafoo.co.uk

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 at 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 at build-lin64 tmp]$


If compiled with clang 9.0:
[dparks at 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 at 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 at build-lin64 tmp]$ ./a.out
d=9223372036853727232.000000 u=9223372036853727232, u=0x7ffffffffff00000
Floating point exception
[dparks at 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, at 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.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20200309/46c5b947/attachment.html>


More information about the llvm-bugs mailing list