hi - The current gcc in the 4.1 branch (svn rev 107578) miscompiles the following source with -O3 -fno-strict-aliasing: --------------------------------------------------------------------------- // g++ -O3 -g -fno-strict-aliasing -o x x.cc inline void* operator new(unsigned, void* __p) throw() { return __p; } extern "C" int printf (...); struct _Deque_base { _Deque_base() { _M_impl._M_start_cur = new int; _M_impl._M_finish_cur = _M_impl._M_start_cur; printf (""); } ~_Deque_base() { printf ("", _M_impl._M_start_node); } struct _Deque_impl { int* _M_start_cur; int _M_start_node; int* _M_finish_cur; }; _Deque_impl _M_impl; }; struct deque : public _Deque_base {}; struct ClusterContainerStandard { deque _clusters; virtual void add_cluster() { } }; int main( ) { { ClusterContainerStandard box; } printf ("aaa\n"); { deque clusters; if (clusters._M_impl._M_start_cur) { ::new(static_cast<void*>(clusters._M_impl._M_finish_cur)) int(0); ++clusters._M_impl._M_finish_cur; } printf ("%p %p\n", clusters._M_impl._M_start_cur, clusters._M_impl._M_finish_cur); } return 0; } --------------------------------------------------------------------------- I expect the two pointer values printed by this program to differ by 4. Instead, they are identical: $ g++ -o x -O3 -fno-strict-aliasing x.cc $ ./x aaa 0x804a018 0x804a018 $ Here is the relevant excerpt from the generated code, starting just after the printf("aaa\n") call: movl $4, (%esp) call _Znwj ; new int movl %eax, -24(%ebp) ; assign to start_cur movl %eax, -16(%ebp) ; assign to finish_cur movl $.LC0, (%esp) call printf ; empty printf .LEHE0: movl -24(%ebp), %eax ; test start_cur testl %eax, %eax je .L12 movl -16(%ebp), %eax ; test finish_cur --- part of the new() testl %eax, %eax je .L6 movl $0, (%eax) ; *finish_cur = 0 movl -16(%ebp), %eax ; (a redundant move) [1] .L6: addl $4, -16(%ebp) ; ++finish_cur .L4: movl %eax, 8(%esp) ; OOPS --- here we're using the value [2] ; of finish_cur before the increment! movl -24(%ebp), %eax movl $.LC2, (%esp) movl %eax, 4(%esp) .LEHB1: call printf Looking at the RTL dumps, the problem first seems to appear after the loop2_done pass. Here's an excerpt from that file, starting at the insn corresponding to [1] above and continuing to [2]. Note that after the increment, there's a branch around an insn that reloads the value of finish_cur from memory before the printf call --- without that jump, the program would work correctly. That jump is not present in the previous RTL dump, loop2_unswitch. (insn 122 56 57 2 (set (reg:SI 79 [ clusters.D.1787._M_impl._M_finish_cur ]) (mem/s/j:SI (plus:SI (reg/f:SI 20 frame) (const_int -8 [0xfffffff8])) [0 <variable>._M_impl._M_start_node+0 S4 A32])) 34 {*movsi_1} (nil) (nil)) ;; End of basic block 2, registers live: (nil) ;; Start of basic block 3, registers live: (nil) (code_label 57 122 58 3 6 "" [1 uses]) (note 58 57 59 3 [bb 3] NOTE_INSN_BASIC_BLOCK) (note 59 58 60 3 ("x.cc") 48) (insn 60 59 128 3 x.cc:48 (parallel [ (set (mem/s/j/c:SI (plus:SI (reg/f:SI 20 frame) (const_int -8 [0xfffffff8])) [0 clusters.D.1787._M_impl._M_finish_cur+0 S4 A32]) (plus:SI (mem/s/j/c:SI (plus:SI (reg/f:SI 20 frame) (const_int -8 [0xfffffff8])) [0 clusters.D.1787._M_impl._M_finish_cur+0 S4 A32]) (const_int 4 [0x4]))) (clobber (reg:CC 17 flags)) ]) 148 {*addsi_1} (nil) (nil)) (jump_insn 128 60 129 3 (set (pc) (label_ref 61)) -1 (nil) (nil)) ;; End of basic block 3, registers live: (nil) (barrier 129 128 127) ;; Start of basic block 4, registers live: (nil) (code_label 127 129 126 4 12 "" [1 uses]) (note 126 127 121 4 [bb 4] NOTE_INSN_BASIC_BLOCK) (insn 121 126 61 4 (set (reg:SI 79 [ clusters.D.1787._M_impl._M_finish_cur ]) (mem/s/j:SI (plus:SI (reg/f:SI 20 frame) (const_int -8 [0xfffffff8])) [0 <variable>._M_impl._M_start_node+0 S4 A32])) 34 {*movsi_1} (nil) (nil)) ;; End of basic block 4, registers live: (nil) ;; Start of basic block 5, registers live: (nil) (code_label 61 121 62 5 4 "" [1 uses]) (note 62 61 63 5 [bb 5] NOTE_INSN_BASIC_BLOCK) (note 63 62 65 5 ("x.cc") 51) (insn 65 63 66 5 x.cc:51 (set (mem:SI (plus:SI (reg/f:SI 7 sp) (const_int 8 [0x8])) [0 S4 A32]) (reg:SI 79 [ clusters.D.1787._M_impl._M_finish_cur ])) 34 {*movsi_1} (nil) (nil)) Environment: System: Linux karma 2.6.14.2sss #1 PREEMPT Mon Nov 21 10:03:24 EST 2005 i686 i686 i386 GNU/Linux Architecture: i686 <machine, os, target, libraries (multiple lines)> host: i686-pc-linux-gnu build: i686-pc-linux-gnu target: i686-pc-linux-gnu configured with: /home/sss/gcc/gcc/configure --prefix=/usr/local/gcc --enable-threads=posix --enable-long-long --enable-languages=c,c++,fortran How-To-Repeat: See above. ------- Comment #1 from snyder at fnal dot gov 2005-11-28 01:24 ------- Fix: <how to correct or work around the problem, if known (multiple lines)> -- Summary: 4.1: miscompilation in loop optimization Product: gcc Version: 4.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: snyder at fnal dot gov 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=25130
[Bug rtl-optimization/25130] New: 4.1: miscompilation in loop optimization
gcc-bugzilla at gcc dot gnu dot org Sun, 27 Nov 2005 17:24:51 -0800
- [Bug rtl-optimization/25130] New: 4.1... gcc-bugzilla at gcc dot gnu dot org
- [Bug rtl-optimization/25130] [4.1... pinskia at gcc dot gnu dot org
- [Bug rtl-optimization/25130] [4.1... wilson at gcc dot gnu dot org
- [Bug rtl-optimization/25130] [4.1... steven at gcc dot gnu dot org
- [Bug rtl-optimization/25130] [4.1... steven at gcc dot gnu dot org
- [Bug rtl-optimization/25130] [4.1... steven at gcc dot gnu dot org
- [Bug rtl-optimization/25130] [4.1... steven at gcc dot gnu dot org
- [Bug rtl-optimization/25130] [4.1... steven at gcc dot gnu dot org
- [Bug rtl-optimization/25130] [4.1... steven at gcc dot gnu dot org
- [Bug rtl-optimization/25130] [4.1... steven at gcc dot gnu dot org
- [Bug rtl-optimization/25130] [4.1... steven at gcc dot gnu dot org