This bug is present with at least gcc-2.95.3, gcc-3.3.2 and gcc-3.4. mhx@r2d2 ~ $ uname -a Linux r2d2.mhxnet.de 2.4.22-gentoo-r2 #2 Sun Dec 21 18:25:49 MET 2003 i686 Intel(R) Pentium(R) III Mobile CPU 1000MHz GenuineIntel GNU/Linux mhx@r2d2 ~ $ gcc-3.4 -v Reading specs from /home/mhx/gcc/gcc-3.4-20031217/lib/gcc/i686-pc-linux-gnu/3.4/specs Configured with: ./configure --prefix=/home/mhx/gcc/gcc-3.4-20031217 --enable-languages=c --program-suffix=-3.4 Thread model: posix gcc version 3.4 20031217 (experimental) mhx@r2d2 ~ $ gcc-3.3.2 -v Reading specs from /home/mhx/gcc/gcc-3.3.2/lib/gcc-lib/i686-pc-linux-gnu/3.3.2/specs Configured with: ./configure --prefix=/home/mhx/gcc/gcc-3.3.2 --program-suffix=-3.3.2 --enable-languages=c,c++ Thread model: posix gcc version 3.3.2 mhx@r2d2 ~ $ gcc-2.95.3 -v Reading specs from /home/mhx/gcc/gcc-2.95.3/lib/gcc-lib/i686-pc-linux-gnu/2.95.3/specs gcc version 2.95.3 20010315 (release) When casting a "long long" variable to "short" or "char" and storing the result back to the same "long long" variable, the value that is being stored is wrong. Casting to "int" or "long" works. Not storing to the same variable also works. Disabling optimizations (-O0) also makes it work. When optimizations are enables, it doesn't matter if -O1, -O2 or -O3 is given. The code that fails is e.g.: long long ll2s_1(long long x) { x = (short) x; return x; } However, this works correctly: long long ll2s_2(long long x) { return (short) x; } I'll try to attach the preprocessed code that causes the failure. The executable has been generated with: gcc-3.4 -save-temps -O1 -o test test.c The output of the executable on my machine is as follows: 0 12 0 12 0 0 0 10000001000 12 -24 12 -6168 1410066408 1410066408 20000002000 12 -48 12 -12336 -1474834480 -1474834480 30000003000 12 -72 12 -18504 -64768072 -64768072 40000004000 12 -96 12 -24672 1345298336 1345298336 50000005000 12 -120 12 -30840 -1539602552 -1539602552 60000006000 12 112 12 28528 -129536144 -129536144 70000007000 12 88 12 22360 1280530264 1280530264 80000008000 12 64 12 16192 -1604370624 -1604370624 90000009000 12 40 12 10024 -194304216 -194304216 Obviously, while columns 2/3 and 4/5 should be identical, they aren't. Disabling optimizations (turning -O1 into -O0) gives the expected result: 0 0 0 0 0 0 0 10000001000 -24 -24 -6168 -6168 1410066408 1410066408 20000002000 -48 -48 -12336 -12336 -1474834480 -1474834480 30000003000 -72 -72 -18504 -18504 -64768072 -64768072 40000004000 -96 -96 -24672 -24672 1345298336 1345298336 50000005000 -120 -120 -30840 -30840 -1539602552 -1539602552 60000006000 112 112 28528 28528 -129536144 -129536144 70000007000 88 88 22360 22360 1280530264 1280530264 80000008000 64 64 16192 16192 -1604370624 -1604370624 90000009000 40 40 10024 10024 -194304216 -194304216 Here's the source code (just in case attaching won't work, this is my first bug report here...): ----8<------------------------------------------------------------------- #include <stdio.h> long long ll2c_1(long long x) { x = (signed char) x; return x; } long long ll2c_2(long long x) { return (signed char) x; } long long ll2s_1(long long x) { x = (short) x; return x; } long long ll2s_2(long long x) { return (short) x; } long long ll2i_1(long long x) { x = (int) x; return x; } long long ll2i_2(long long x) { return (int) x; } int main(void) { long long a; for (a = 0LL; a < 100000000000LL; a += 10000001000LL) { printf("%12lld", a); printf("%12lld", ll2c_1(a)); printf("%12lld", ll2c_2(a)); printf("%12lld", ll2s_1(a)); printf("%12lld", ll2s_2(a)); printf("%12lld", ll2i_1(a)); printf("%12lld", ll2i_2(a)); printf("\n"); } return 0; }
Created attachment 5369 [details] Preprocessed source of code that causes the failure
FYI, I can also confirm the bug for a cygwin gcc-3.2 on the same machine. $ uname -a CYGWIN_NT-5.0 R2D2 1.5.3(0.90/3/2) 2003-09-01 13:15 i686 unknown unknown Cygwin $ gcc -v Reading specs from /usr/lib/gcc-lib/i686-pc-cygwin/3.2/specs Configured with: /netrel/src/gcc-3.2-3/configure --enable-languages=c,c++,f77,ja va --enable-libgcj --enable-threads=posix --with-system-zlib --enable-nls --with out-included-gettext --enable-interpreter --disable-sjlj-exceptions --disable-ve rsion-specific-runtime-libs --enable-shared --build=i686-pc-linux --host=i686-pc -cygwin --target=i686-pc-cygwin --enable-haifa --prefix=/usr --exec-prefix=/usr --sysconfdir=/etc --libdir=/usr/lib --includedir=/nonexistent/include --libexecd ir=/usr/sbin Thread model: posix gcc version 3.2 20020927 (prerelease)
I can confirm this and this is not a regression, even 2.91.6 causes this. Life analysis causes this problem, it removes the load from 4(%esp) which is the argument.
This is fixed in 3.5.0 (20040331) but it was not fixed for 3.4.0 (20040116) and I do not have a newer 3.4.0 to say if it was fixed there too. Could someone check?
*** This bug has been marked as a duplicate of 14235 ***
Subject: Bug 13488 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-3_3-rhl-branch Changes by: jakub@gcc.gnu.org 2004-04-13 20:36:16 Modified files: gcc : ChangeLog expr.c gcc/testsuite : ChangeLog Added files: gcc/testsuite/gcc.c-torture/compile: 20040304-1.c gcc/testsuite/gcc.c-torture/execute: 20040402-1.c Log message: 2004-03-04 Eric Botcazou <ebotcazou@libertysurf.fr> PR optimization/14235 * expr.c (convert_move): Copy the source to a new pseudo when converting from a sub-word source to a larger-than-word register which conflicts with the source. * gcc.c-torture/compile/20040304-1.c: New test. 2004-04-02 Jakub Jelinek <jakub@redhat.com> PR optimization/13488 * gcc/testsuite/gcc.c-torture/execute/20040402-1.c: New test. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_3-rhl-branch&r1=1.16114.2.523.2.104&r2=1.16114.2.523.2.105 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/expr.c.diff?cvsroot=gcc&only_with_tag=gcc-3_3-rhl-branch&r1=1.498.2.17.2.16&r2=1.498.2.17.2.17 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_3-rhl-branch&r1=1.2261.2.170.2.55&r2=1.2261.2.170.2.56 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.c-torture/compile/20040304-1.c.diff?cvsroot=gcc&only_with_tag=gcc-3_3-rhl-branch&r1=NONE&r2=1.1.20.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.c-torture/execute/20040402-1.c.diff?cvsroot=gcc&only_with_tag=gcc-3_3-rhl-branch&r1=NONE&r2=1.1.2.1
Subject: Bug 13488 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-3_4-rhl-branch Changes by: jakub@gcc.gnu.org 2004-04-22 17:50:29 Modified files: gcc/testsuite : ChangeLog Added files: gcc/testsuite/gcc.c-torture/execute: 20040402-1.c Log message: PR optimization/13488 * gcc/testsuite/gcc.c-torture/execute/20040402-1.c: New test. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_4-rhl-branch&r1=1.3389.2.170.2.2&r2=1.3389.2.170.2.3 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.c-torture/execute/20040402-1.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-rhl-branch&r1=NONE&r2=1.1.4.1