[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: G++ optimization bug?
From: |
Larry Smith |
Subject: |
Re: G++ optimization bug? |
Date: |
Sat, 07 Apr 2007 00:37:07 GMT |
User-agent: |
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.2) Gecko/20061107 SUSE/1.1.1-0.1 SeaMonkey/1.1.1 |
valmosk@gmail.com wrote:
> I posted this in the gcc help forums, but I think it belongs in this
> one since its a g++ issue.
>
> Hi,
> I've encountered a problem that may be a compiler optimization bug
> (with branch prediction). So far, I can reproduce it on Linux64 with g
> +
> + 3.4.3:
>
> nagara:/home/vmoskovi>g++ --version
> g++ (GCC) 3.4.3 20050227 (Red Hat 3.4.3-22.1)
> Copyright (C) 2004 Free Software Foundation, Inc.
>
>
> Here is a simple program:
>
>
> #define COPYLONG(pDstAddr, pSrcAddr) \
> ((int *) (pDstAddr))[0] = ((int *)(pSrcAddr))[0]; \
> ((int *) (pDstAddr))[1] = ((int *)(pSrcAddr))[1];
>
>
> #include <iostream.h>
> #include <stdio.h>
>
>
> inline int test()
> {
> long long dataAddr = 5;
> long long dupAddr = 0;
> COPYLONG(&dupAddr, &dataAddr);
> if (dupAddr == 0)
> {
> printf("IF\n");
> }
> else
> {
> printf("ELSE\n");
> }
>
>
> return 0;
>
>
>
> }
>
>
> main()
> {
>
> test();
> return 0;
>
>
>
> }
>
>
> The expected output is ELSE since dupAddr should be set to 5. Here
> is
> the output:
>
> nagara:/home/vmoskovi>g++ -O1 jt.cpp
> In file included from /usr/lib/gcc/x86_64-redhat-linux/
> 3.4.3/../../../../include/c++/3.4.3/backward/iostream.h:31,
> from jt.cpp:7:
> /usr/lib/gcc/x86_64-redhat-linux/3.4.3/../../../../include/c++/3.4.3/
> backward/backward_warning.h:32:2: warning: #warning This file
> includes
> at least one deprecated or antiquated header. Please consider using
> one of the 32 headers found in section 17.4.1.2 of the C++ standard.
> Examples include substituting the <X> header for the <X.h> header for
> C
> ++ includes, or <iostream> instead of the deprecated header
> <iostream.h>. To disable this warning use -Wno-deprecated.
> nagara:/home/vmoskovi>a.out
> ELSE
> nagara:/home/vmoskovi>g++ -O2 jt.cpp
> In file included from /usr/lib/gcc/x86_64-redhat-linux/
> 3.4.3/../../../../include/c++/3.4.3/backward/iostream.h:31,
> from jt.cpp:7:
> /usr/lib/gcc/x86_64-redhat-linux/3.4.3/../../../../include/c++/3.4.3/
> backward/backward_warning.h:32:2: warning: #warning This file
> includes
> at least one deprecated or antiquated header. Please consider using
> one of the 32 headers found in section 17.4.1.2 of the C++ standard.
> Examples include substituting the <X> header for the <X.h> header for
> C
> ++ includes, or <iostream> instead of the deprecated header
> <iostream.h>. To disable this warning use -Wno-deprecated.
> nagara:/home/vmoskovi>a.out
> IF
>
>
> Using optimization level 01, the output is correct. However, using
> optimization level 02 it takes the wrong branch. I suspect that the
> optimizer doesn't realize that COPYLONG modifies dupAddr. Is this a
> known issue? Has anyone else encountered this problem?
>
The following corrected code produces "ELSE" with -O1 and -O2.
I don't have the old Redhat platform to test against, nor do I
the old compiler. Using g++ v4.1.2 with SUSE 10.2 on x86 and
x86_64 the result is always "ELSE".
#include <iostream>
#include <stdio.h>
#define COPYLONG(pDstAddr, pSrcAddr) \
((int *) (pDstAddr))[0] = ((int *)(pSrcAddr))[0]; \
((int *) (pDstAddr))[1] = ((int *)(pSrcAddr))[1];
inline int test()
{
// hmmm, pointers on 64 bit hdw are 'long',
// not 'long long'.
// int is 32 bits, long is 64 bits, ptr is
// 64 bits.
long long dataAddr = 5;
long long dupAddr = 0;
COPYLONG(&dupAddr, &dataAddr);
if (dupAddr == 0)
{
printf("IF\n");
}
else
{
printf("ELSE\n");
}
return 0;
}
main()
{
// print the size of some key data types...
printf("%u = sizeof int\n", sizeof(int) );
printf("%u = sizeof long\n", sizeof(long) );
printf("%u = sizeof ptr\n", sizeof(void *) );
printf("%u = sizeof long long\n", sizeof(long long) );
printf("result of test() = ");
test();
return 0;
}