bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: icc bug on test-frexp-nolibm


From: Eric Blake
Subject: Re: icc bug on test-frexp-nolibm
Date: Thu, 04 Nov 2010 11:43:57 -0600
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.12) Gecko/20101027 Fedora/3.1.6-1.fc14 Mnenhy/0.8.3 Thunderbird/3.1.6

On 11/03/2010 05:10 PM, Eric Blake wrote:
> I'm running out of time today to get to the bottom of this, so if anyone
> else wants to help out, great.  If not, I'll see if I can resume testing
> tomorrow and get a minimal test case that exposes the compiler bug, as
> well as try and isolate ways to work around it.
> 
> I'm on a Linux x86_64 machine with icc (ICC) 10.0 20070426.
> 
> I hate it when a heisenbug disappears because of the mere act of adding
> debugging hooks. :(

I've reduced it to a minimal testcase:

$ cat foo.c
#define _GNU_SOURCE 1
#include <assert.h>
#include <math.h>
double zero;
double bar (void) { return -zero; }
int main (void)
{
  assert (!signbit (zero));
  assert (signbit (bar ()));
  return 0;
}
$ icc -g -o foo foo.c
$ ./foo
$ icc    -o foo foo.c
$ ./foo
foo: foo.c:9: main: Assertion `(( sizeof( bar () ) > sizeof( double )) ?
__signbitl( (long double)(bar ()) ) : (( sizeof( bar () ) == sizeof(
float )) ? __signbitf( (float)(bar ()) ) : __signbit( (double)(bar ())
)))' failed.
Aborted (core dumped)
$

Looks like icc with debugging computes -0.0 correctly, but without -g it
makes a mistaken optimization.  Comparing the assembly, I see:

with -g:
Dump of assembler code for function bar:
   0x00000000004005f8 <+0>:     push   %rbp
   0x00000000004005f9 <+1>:     mov    %rsp,%rbp
   0x00000000004005fc <+4>:     sub    $0x10,%rsp
   0x0000000000400600 <+8>:     fldl   0x20087a(%rip)        # 0x600e80 <zero>
   0x0000000000400606 <+14>:    fchs
   0x0000000000400608 <+16>:    fstpl  -0x10(%rbp)
   0x000000000040060b <+19>:    movsd  -0x10(%rbp),%xmm0
   0x0000000000400610 <+24>:    leaveq
   0x0000000000400611 <+25>:    retq

without -g:
Dump of assembler code for function bar:
   0x0000000000400b3a <+0>:     pxor   %xmm0,%xmm0
   0x0000000000400b3e <+4>:     subsd  0x203542(%rip),%xmm0        #
0x604088 <zero>
   0x0000000000400b46 <+12>:    retq
   0x0000000000400b47 <+13>:    nop


Gnulib's testsuite already has several workarounds for computing -0.0 in
spite of buggy compilers, so I think it's just a matter of making all
the tests uniformly use those same workarounds.

In particular, I tested that this works for icc regardless of whether
CFLAGS includes -g (borrowing from test-ceill.c's workarounds for -0.0L
as my starting point):

#if defined __hpux || defined __sgi || defined __ICC
static double
compute_minus_zero (void)
{
  return -DBL_MIN * DBL_MIN;
}
# define minus_zero compute_minus_zero ()
#else
double minus_zero = -0.0;
#endif

-- 
Eric Blake   address@hidden    +1-801-349-2682
Libvirt virtualization library http://libvirt.org

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]