[Bug c/40312] New: Compilings with and with O2 flag lead to different execution results

2009-05-30 Thread tlin at a10networks dot com
The following simplified standalone C code illustrates this bug.  If we compile
it with and without O2 flag, the executions are different.

The comments at the beginning of the following code has GCC information,
compiling commands, and execution outputs.

 Example C Code =

/*
GCC Version:

gcc -v
Using built-in specs.
Target: i686-pc-linux-gnu
Configured with: ../gcc-4.1.1/configure --prefix=/usr --libexecdir=/usr/lib
--enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-c99
--enable-long-long --enable-clocale=gnu --enable-languages=c,c++
--disable-multilib --disable-libstdcxx-pch
Thread model: posix
gcc version 4.1.1

Compile commands:

   gcc -o test  test.c; gcc -O2 -o O2_test test.c 

Execution outputs:

./test; ./O2_test 

Output:
./test: Bug[1] 2001:d::2/64 matches 2001:d::1.
 ./O2_test: Bug[0] 2001:c::1/64 matches 2001:d::1.
 */

#include 
#include 
#include 
#include 
#include 
#include 
#include 

typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;

static inline int __ipv6_prefix_equal(const u32 *a1, const u32 *a2,
  unsigned int prefixlen)
{
unsigned pdw, pbi;

pdw = prefixlen >> 5;
if (pdw && memcmp(a1, a2, pdw << 2))
return 0;

pbi = prefixlen & 0x1f;
if (pbi && ((a1[pdw] ^ a2[pdw]) & htonl((0x) << (32 - pbi
return 0;

return 1;
}

static inline int ipv6_prefix_equal(const struct in6_addr *a1,
const struct in6_addr *a2,
unsigned int prefixlen)
{
return __ipv6_prefix_equal(a1->s6_addr32, a2->s6_addr32,
   prefixlen);
}

static inline int ipv6_addr_any(const struct in6_addr *a)
{
return ((a->s6_addr32[0] | a->s6_addr32[1] |
 a->s6_addr32[2] | a->s6_addr32[3] ) == 0);
}

struct temp {
unsigned int ipv6_prefixlen;
struct in6_addr ipv6_addr;
struct in6_addr ipv6_lladdr;
} bug[2];

struct in6_addr target;


int find_bug (int link_local_nexthop)
{
int i;

for (i = 0 ; i <= 1; i++) {
if (ipv6_addr_any(&bug[i].ipv6_addr) && !link_local_nexthop)
continue;
if (ipv6_addr_any(&bug[i].ipv6_lladdr) && link_local_nexthop)
continue;
if (ipv6_prefix_equal(&bug[i].ipv6_addr, &target,
bug[i].ipv6_prefixlen)) {
return i;
}
}
return -1;
}


int main(int argc, char ** argv)
{
int i = -1;
char ipv6[3][256];

strcpy(ipv6[0], "2001:c::1");
strcpy(ipv6[1], "2001:d::2");
strcpy(ipv6[2], "2001:d::1");

inet_pton(AF_INET6, ipv6[0], &bug[0].ipv6_addr);
inet_pton(AF_INET6, "fe80:c::1", &bug[0].ipv6_lladdr);  
bug[0].ipv6_prefixlen = 64;

inet_pton(AF_INET6, ipv6[1], &bug[1].ipv6_addr);
inet_pton(AF_INET6, "fe80:2001::1", &bug[1].ipv6_lladdr);   
bug[1].ipv6_prefixlen = 64;

inet_pton(AF_INET6, ipv6[2], &target);  

i = find_bug(0);
if (i == -1)
printf("No match found.\n");
else
printf("%10s: Bug[%d] %s/%u matches %s.\n", argv[0], i,
ipv6[i], bug[i].ipv6_prefixlen, ipv6[2]);
return 0;
}


-- 
   Summary: Compilings with and with O2 flag lead to different
execution results
   Product: gcc
   Version: 4.1.1
    Status: UNCONFIRMED
  Severity: critical
  Priority: P3
 Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: tlin at a10networks dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40312



[Bug c/40312] Compiling with O2 flag lead to wrong binary code (X86 system 32bit)

2009-05-30 Thread tlin at a10networks dot com


--- Comment #1 from tlin at a10networks dot com  2009-05-30 23:08 ---
The one compiled with O2 has wrong binary code.

The problem occurs when GCC compiles the following lines with O2 flag.

"
if (pdw && memcmp(a1, a2, pdw << 2))
return 0;
"

In the binary code, pdw is not shifted left by 2, which leads to wrong result.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40312