From Bugzilla Helper: User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0; T312461) Description of problem: The snippet below returns the wrong value with gcc at all optimization levels on linux. It works OK with other compilers and on gcc *solaris* 2.95.2. Version-Release number of selected component (if applicable): How reproducible: Always Steps to Reproduce: // The code below will print BUG EXISTS on linux gcc only, not solaris or // non-gcc. Note that in the third print, I manually substituted the // result that GCC says is in a midterm into the equation, and I get the // right result! // $ uname -a // Linux 2.4.7-10smp #1 SMP Thu Sep 6 17:09:31 EDT 2001 i686 unknown // $ gcc --version // 2.96 // $ cat /etc/redhat-release // Red Hat Linux release 7.2 (Enigma) // $ gcc {SNIPPETBELOW.cpp} // $ a.out // ff9d6df9 exp fb76ebf7 // ***BUG EXISTS**** // fb36c396 exp fb36c396 // fb76ebf7 exp fb76ebf7 #ifdef __SOLARIS #include <sys/types.h> #else #include <stdint.h> // uint32_t #endif #include <stdio.h> #define VL_WORDSIZE 32 // Bits in a word #define VL_SIZEBITS (VL_WORDSIZE-1) // Bit mask for bits in a word #define VL_WORDS(nbits) (((nbits)+(VL_WORDSIZE-1))/VL_WORDSIZE) // Words this # bits needs (1 bit=1 word) #define VL_BITWORD(bit) ((bit)/VL_WORDSIZE) #define VL_BITBIT(bit) ((bit)&VL_SIZEBITS) static inline uint32_t VL_RANGE_IWII(uint32_t* lwp, uint32_t msb, uint32_t lsb) { int nbitsonright = 32-lsb; // bits that come from low word return ((lwp[VL_BITWORD(msb)]<<nbitsonright) |(lwp[VL_BITWORD(lsb)]>>VL_BITBIT(lsb))); } void main() { uint32_t W1065[2] = {0xffffffffU, 0x1FFFFFU}; uint32_t W1066; W1066 = 0x4c93c6a; uint32_t bugvalue = ((0x1a0469e1U | (0xf2626901U - VL_RANGE_IWII(W1065, 0x34, 0x15))) | (-(W1066))); printf("%x exp fb76ebf7\n", bugvalue); if (bugvalue != 0xfb76ebf7U) { printf ("***BUG EXISTS****\n"); } printf("%x exp fb36c396\n", (-(W1066))); printf("%x exp fb76ebf7\n", ((0x1a0469e1U | (0xf2626901U - VL_RANGE_IWII(W1065, 0x34, 0x15))) | 0xfb36c396U)); } Actual Results: ff9d6df9 exp fb76ebf7 ***BUG EXISTS**** Expected Results: fb76ebf7 exp fb76ebf7 Additional info: This was uncovered by a automatic compiler checker which is testing a program that generates C code. It took about 5 hours of continuous compiles to get this, so it's got to be something relatively obscure.
Same here, on my rawhide box (gcc-3.2-0.1).
Here is the shortest buggy testcase I could extract: /* --------------- cut here --------------- #include <stdint.h> #include <stdio.h> uint32_t f() { return 1u; } int main() { uint32_t n = 1u; uint32_t bugvalue, goodvalue; bugvalue = (0x1u | (0x2u - f())) | (-n); goodvalue = (0x1u | (0x2u - 1u)) | (-n); printf("bugvalue = %x\ngoodvalue = %x\n", bugvalue, goodvalue); return 0; } /* --------------- cut here --------------- */ $ gcc -Wall -o test test.c $ ./test bugvalue = 1 goodvalue = ffffffff
A little shorter. Outputs 1 instead of -1. #include <stdio.h> int main() { int n=1, m; m = (1 | (2 - n)) | (-n); printf("m=%d\n", m); return 0; }
Should be fixed in gcc-3.2-0.3 (and on gcc CVS trunk).