This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug rtl-optimization/25130] New: 4.1: miscompilation in loop optimization
- From: "gcc-bugzilla at gcc dot gnu dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 28 Nov 2005 01:24:47 -0000
- Subject: [Bug rtl-optimization/25130] New: 4.1: miscompilation in loop optimization
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
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