Valgrind reports some memory safety problems in the 'gcc -O3' execution. regehr@home:~$ current-gcc -O2 small.c -o small regehr@home:~$ ./small g_6 = 0 regehr@home:~$ current-gcc -O3 small.c -o small regehr@home:~$ ./small g_6 = 134513352 regehr@home:~$ current-gcc -v Using built-in specs. COLLECT_GCC=current-gcc COLLECT_LTO_WRAPPER=/mnt/z/z/compiler-install/gcc-r168941-install/libexec/gcc/i686-pc-linux-gnu/4.6.0/lto-wrapper Target: i686-pc-linux-gnu Configured with: ../configure --with-libelf=/usr/local --enable-lto --prefix=/mnt/z/z/compiler-install/gcc-r168941-install --program-prefix=r168941- --enable-languages=c,c++ Thread model: posix gcc version 4.6.0 20110118 (experimental) (GCC) regehr@home:~$ cat small.c static unsigned int crc32_tab[256]; static unsigned int crc32_context = 0; static char g_4 = 0; static int g_6 = 0; static long long g_83 = 0; static int *g_102 = &g_6; int printf(const char *format, ...); int strcmp(const char *s1, const char *s2); static short div(long long p1, long long p2) { return p1 / p2; } static char sub(char p1, char p2) { return p1 - p2; } static int func_95(int p_96, int p_97) { *g_102 = (p_97 != (short)(p_97 * 3)); for (g_4 = 0; g_4 < 2; g_4++) { lbl_210: if (g_6) { if (g_83) { g_83 = 1; } else { return p_96; } } else { g_6 = 1; goto lbl_210; } g_102 = &g_6; } return p_96; } static void crc32(unsigned long long val, int flag) { if (!flag) { crc32_context = crc32_tab[crc32_context & 1]; crc32_context = crc32_tab[crc32_context & 1]; crc32_context = crc32_tab[(crc32_context ^ (val & 1)) & 1]; crc32_context = crc32_tab[(crc32_context ^ (val & 1)) & 1]; } } int main(int argc, char* argv[]) { int print_hash_value = 0; unsigned int crc = 0; int l_338[8]; int i, j; if (argc == 2 && strcmp(argv[1], "1") == 0) print_hash_value = 1; for (i = 0; i < 256; i++) { for (j = 8; j > 0; j--) { crc = 1; } crc32_tab[i] = crc; } for (i = 0; i < 8; i++) l_338[i] = 0; g_6 = sub(g_4, g_4); g_6 = func_95(g_4, 1 | div(l_338[0], 10)); crc32(g_6, print_hash_value); crc32(g_83, print_hash_value); printf("g_6 = %d\n", g_6); return 0; }
Confirmed, goes away with -fno-partial-inlining, happens only with -m32. From brief look at it it looks like a RTL DCE bug, it removes a __divdi3 call, but takes away with it also a needed unrelated store: (insn 203 105 204 6 (set (mem:SI (plus:SI (reg/f:SI 7 sp) (const_int 8 [0x8])) [0 S4 A32]) (const_int 10 [0xa])) pr47337.c:14 64 {*movsi_internal} (nil)) (insn 204 203 205 6 (set (mem:SI (plus:SI (reg/f:SI 7 sp) (const_int 12 [0xc])) [0 S4 A32]) (const_int 0 [0])) pr47337.c:14 64 {*movsi_internal} (nil)) (insn 205 204 206 6 (set (mem:SI (reg/f:SI 7 sp) [0 S4 A32]) (const_int 0 [0])) pr47337.c:14 64 {*movsi_internal} (nil)) (insn 206 205 190 6 (set (mem:SI (plus:SI (reg/f:SI 7 sp) (const_int 4 [0x4])) [0 S4 A32]) (const_int 0 [0])) pr47337.c:14 64 {*movsi_internal} (nil)) (insn 190 206 110 6 (set (mem/c:SI (plus:SI (reg/f:SI 7 sp) (const_int 28 [0x1c])) [5 S4 A32]) (reg:SI 2 cx)) pr47337.c:14 64 {*movsi_internal} (expr_list:REG_DEAD (reg:SI 2 cx) (nil))) (call_insn/u 110 190 179 6 (set (reg:DI 0 ax) (call (mem:QI (symbol_ref:SI ("__divdi3") [flags 0x41]) [0 S1 A8]) (const_int 16 [0x10]))) pr47337.c:14 927 {*call_value_0} (expr_list:REG_UNUSED (reg:DI 0 ax) (expr_list:REG_EH_REGION (const_int -2147483648 [0xffffffff80000000]) (nil))) (expr_list:REG_DEP_TRUE (use (mem:DI (reg/f:SI 7 sp) [0 S8 A8])) (expr_list:REG_DEP_TRUE (use (mem:DI (plus:SI (reg/f:SI 7 sp) (const_int 8 [0x8])) [0 S8 A8])) (nil)))) The sp+0x1c store shouldn't be deleted, but it is.
Created attachment 23016 [details] gcc46-pr47337.patch Untested fix. Thanks for the report.
Author: jakub Date: Wed Jan 19 15:13:01 2011 New Revision: 168997 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=168997 Log: PR rtl-optimization/47337 * dce.c (check_argument_store): New function. (find_call_stack_args): Ignore debug insns. Use check_argument_store. * gcc.c-torture/execute/pr47337.c: New test. Added: trunk/gcc/testsuite/gcc.c-torture/execute/pr47337.c Modified: trunk/gcc/ChangeLog trunk/gcc/dce.c trunk/gcc/testsuite/ChangeLog
Fixed.