See below. The output at -O0 looks good. At -O3 the wrong result is printed and valgrind reports a read of uninitialized memory.
reg...@john-home:~/volatile/tmp160$ current-gcc -O0 -Wall small.c -o small reg...@john-home:~/volatile/tmp160$ valgrind ./small ==26152== Memcheck, a memory error detector. ==26152== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al. ==26152== Using LibVEX rev 1804, a library for dynamic binary translation. ==26152== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP. ==26152== Using valgrind-3.3.0, a dynamic binary instrumentation framework. ==26152== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al. ==26152== For more details, rerun with: -v ==26152== checksum = 0 ==26152== ==26152== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 11 from 1) ==26152== malloc/free: in use at exit: 0 bytes in 0 blocks. ==26152== malloc/free: 0 allocs, 0 frees, 0 bytes allocated. ==26152== For counts of detected errors, rerun with: -v ==26152== All heap blocks were freed -- no leaks are possible. reg...@john-home:~/volatile/tmp160$ current-gcc -O3 -Wall small.c -o small reg...@john-home:~/volatile/tmp160$ valgrind ./small ==26158== Memcheck, a memory error detector. ==26158== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al. ==26158== Using LibVEX rev 1804, a library for dynamic binary translation. ==26158== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP. ==26158== Using valgrind-3.3.0, a dynamic binary instrumentation framework. ==26158== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al. ==26158== For more details, rerun with: -v ==26158== ==26158== Use of uninitialised value of size 4 ==26158== at 0x8048553: main (in /home/regehr/volatile/tmp160/small) checksum = E9 ==26158== ==26158== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 11 from 1) ==26158== malloc/free: in use at exit: 0 bytes in 0 blocks. ==26158== malloc/free: 0 allocs, 0 frees, 0 bytes allocated. ==26158== For counts of detected errors, rerun with: -v ==26158== All heap blocks were freed -- no leaks are possible. reg...@john-home:~/volatile/tmp160$ current-gcc -v Using built-in specs. Target: i686-pc-linux-gnu Configured with: ../configure --prefix=/home/regehr/z/tmp/gcc-r147052-install --program-prefix=r147052- --enable-languages=c,c++ Thread model: posix gcc version 4.5.0 20090502 (experimental) (GCC) reg...@john-home:~/volatile/tmp160$ cat small.c #include <stdint.h> #include <stdio.h> uint8_t crc32_tab[256]; uint32_t crc32_context; #define safe_mod_macro_int16_t_s_s(si1,si2) \ (((((int16_t)(si2)) == ((int16_t)0)) || ((((int16_t)(si1)) == (INT16_MIN)) && (((int16_t)(si2)) == ((int16_t)-1)))) \ ? ((int16_t)(si1)) \ : (((int16_t)(si1)) % ((int16_t)(si2)))) static int16_t safe_mod_func_int16_t_s_s (int16_t _si1, int16_t _si2) { return safe_mod_macro_int16_t_s_s(_si1,_si2); } #define safe_mod_macro_int64_t_s_s(si1,si2) \ (((((int64_t)(si2)) == ((int64_t)0)) || ((((int64_t)(si1)) == (INT64_MIN)) && (((int64_t)(si2)) == ((int64_t)-1)))) \ ? ((int64_t)(si1)) \ : (((int64_t)(si1)) % ((int64_t)(si2)))) static int64_t safe_mod_func_int64_t_s_s (int64_t _si1, int64_t _si2) { return safe_mod_macro_int64_t_s_s(_si1,_si2); } static void crc32_gentab (void) { uint32_t crc; const uint32_t poly = 0xEDB88320UL; int i, j; for (i = 0; i < 256; i++) { crc = i; for (j = 8; j > 0; j--) { if (crc & 1) { crc = (crc >> 1) ^ poly; } else { crc >>= 1; } } crc32_tab[i] = crc; } } static void crc32_byte (uint8_t b) { crc32_context = ((crc32_context >> 8) & 0x00FFFFFF) ^ crc32_tab[(crc32_context ^ b) & 0xFF]; } static void crc32_8bytes (uint64_t val) { crc32_byte ((val>>0) & 0xff); crc32_byte ((val>>8) & 0xff); crc32_byte ((val>>16) & 0xff); crc32_byte ((val>>24) & 0xff); crc32_byte ((val>>32) & 0xff); crc32_byte ((val>>40) & 0xff); crc32_byte ((val>>48) & 0xff); crc32_byte ((val>>56) & 0xff); } static inline void platform_main_end(uint32_t crc) { printf ("checksum = %X\n", crc); } int8_t g_3 = 1; volatile uint8_t g_98; uint8_t g_99; int32_t func_10 (int32_t p_11); int32_t func_10 (int32_t p_11) { return g_99; } int64_t func_4 (void); int64_t func_4 (void) { if (safe_mod_func_int16_t_s_s (((safe_mod_func_int64_t_s_s (1, g_3)) == g_3), func_10 (1))) g_98; else return g_98; return 1; } int main (void) { crc32_gentab (); func_4 (); crc32_8bytes (g_99); platform_main_end (crc32_context); return 0; } -- Summary: apparent spurious uninitialized read from r147052 on integer code Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: regehr at cs dot utah dot edu GCC build triplet: i686-pc-linux-gnu GCC host triplet: i686-pc-linux-gnu GCC target triplet: i686-pc-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40003