[EMAIL PROTECTED] 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; } _______________________________________________ help-gplusplus mailing list help-gplusplus@gnu.org http://lists.gnu.org/mailman/listinfo/help-gplusplus