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

Bug#412617: marked as done (gcc-4.1: -O2 optimises away necessary code with no warning)



Your message dated Tue, 27 Feb 2007 10:03:42 +0100
with message-id <87649ormz5.fsf@debian.org>
and subject line Bug#412617: gcc-4.1: -O2 optimises away necessary code with no warning
has caused the attached Bug report to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what I am
talking about this indicates a serious mail system misconfiguration
somewhere.  Please contact me immediately.)

Debian bug tracking system administrator
(administrator, Debian Bugs database)

--- Begin Message ---
Package: gcc-4.1
Version: 4.1.1-21
Severity: normal


The below code should return a random number between 0 and 1, but does
not do that when -O2 or higher is enabled. Uncomment the printf line
to make the code work properly.

Cheers,
//Anders


#include <stdlib.h>
#include <math.h>
#include <inttypes.h>
#include <stdio.h>

uint32_t rngi(uint32_t* ws)
{
  /* Dummy code in place of more advanced RNG */
  return rand() | ((rand() & 0x1)<<31);
}

static inline double rng(uint32_t* ws) 
{
  /* Create 53 bit random number */
  uint64_t r = 0ULL;
  void* rp = &r;
  ((uint32_t*)rp)[1] = rngi(ws) >> 5;
  ((uint32_t*)rp)[0] = rngi(ws);
  r >>= 6ULL;
  
  // Uncomment this line to make the proram work properly
  //printf("0x%08X%08X\n", ((uint32_t*)rp)[1], ((uint32_t*)rp)[0]);

  /* Create double precision floating point random number in the range [0,1) 
     The constant is generated as:
     uint64_t g  = 0x0020000000000000ULL;
     printf("%0.24g \n",1.0/(*((double*)(&g))));
  */  
  return *((double*)rp) * 2.24711641857789488466163e+307;
}

int main(void)
{
  static uint32_t* ws = NULL;
  double r = rng(ws);
  printf("%g\n",r);

  return 0;
}




-- System Information:
Debian Release: 4.0
  APT prefers testing
  APT policy: (500, 'testing')
Architecture: i386 (i686)
Shell:  /bin/sh linked to /bin/bash
Kernel: Linux 2.6.20
Locale: LANG=en_GB, LC_CTYPE=sv_SE (charmap=ANSI_X3.4-1968) (ignored: LC_ALL set to C)

Versions of packages gcc-4.1 depends on:
ii  binutils                    2.17-3       The GNU assembler, linker and bina
ii  cpp-4.1                     4.1.1-21     The GNU C preprocessor
ii  gcc-4.1-base                4.1.1-21     The GNU Compiler Collection (base 
ii  libc6                       2.3.6.ds1-11 GNU C Library: Shared libraries
ii  libgcc1                     1:4.1.1-21   GCC support library
ii  libssp0                     4.1.1-21     GCC stack smashing protection libr

Versions of packages gcc-4.1 recommends:
ii  libc6-dev                   2.3.6.ds1-11 GNU C Library: Development Librari
pn  libmudflap0-dev             <none>       (no description available)

-- no debconf information



--- End Message ---
--- Begin Message ---
Anders Johansson <ajh@ares.watri.org.au> writes:

> The below code should return a random number between 0 and 1, but does
> not do that when -O2 or higher is enabled. Uncomment the printf line
> to make the code work properly.
[...]
>   uint64_t r = 0ULL;
>   void* rp = &r;
>   ((uint32_t*)rp)[1] = rngi(ws) >> 5;

This code accesses a value of type uint64_t by an lvalue of type
uint32_t. This is not allowed by C's aliasing rules. So the behavior
is undefined, and this is not a bug in gcc. See the documentation of
-fno-strict-aliasing.

-- 
	Falk

--- End Message ---

Reply to: