This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug optimization/15295] New: Instruction scheduling with -O2 on i686 creates fatal aliasing bug
- From: "arno at mpi-sb dot mpg dot de" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 5 May 2004 12:10:15 -0000
- Subject: [Bug optimization/15295] New: Instruction scheduling with -O2 on i686 creates fatal aliasing bug
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
I believe to have found a C++ program for which optimized (-O2) compilation
on an i686 machine by combination of function inlining and out-of-order
instruction scheduling leads to assembler code in which two registers point
to the same piece of memory in two different roles, and accesses to it are
performed in the wrong order, leading to a crash in the code.
I couldn't find an earlier bug report subsuming my problem.
I tried but failed to construct a small example; apparently the problem
depends on a large context. I have attached a single preprocessed source
file resched_aliasing.ii (1.2 MB) which was created by
$ g++-3.3.3 -Wno-deprecated -O2 -Wall -g -c resched_aliasing.C -E -o
resched_aliasing.ii -I(many dirs) -D(some defines)
The errorneous assembler output resched_aliasing.s can be generated with
$ g++-3.3.3 -O2 resched_aliasing.ii -g -S
(I've left out the .s file according to the bug reporting instructions.)
Both invocations of g++ do not generate warnings etc.
The executable created from that code (which requires linking against
several libraries that are irrelevant here) crashes with a SIGSEGV in the
following place (see .s file after label .LBB1256 in line 7695):
( 1) .LBB1256:
( 2) movl _ZN4CORE10MemoryPoolINS_9BigRatRepEE7memPoolE, %eax
( 3) testl %eax, %eax
( 4) jne .L2368
(jump is taken)
( 5) ...
( 6) .L2368:
( 7) decl _ZN4CORE10MemoryPoolINS_9BigRatRepEE7memPoolE+4
( 8) movl %eax, %ebx
( 9) movl -40(%ebp), %edi
(10) movl $1, (%ebx)
(11) movl (%eax), %eax
This code is a mixture of a MemoryPool, maintaining a linked list of
uninitialized or destroyed BigRatRep objects, and the constructor of
BigRatRep's base class RCRepImpl, which initializes the refCount member
varible at offset 0 to the value 1.
The relevant source code lines are these:
(.ii file, around line 34719)
template<class T>
class MemoryPool {
// ...
void* allocate(size_t) {
if (next == __null)
expandFreeList();
MemoryPool<T> *head = next;
next = head->next;
nCount --;
return head;
}
// ...
};
(.ii file, around line 36991)
template<class Deriving>
class RCRepImpl {
public:
RCRepImpl() : refCount(1) {}
// ...
};
In line (2) of the assembler code, the pointer `next' is read into %eax.
It is then checked to be non-zero (lines (3..6)). The decrement of `nCount'
in line (7) and the unrelated line (9) are irrelevant here. The problem is
that in (8) %ebx becomes an alias for %eax, and the initialization of refCount
to 1 in line (9) is scheduled before `next = head->next' takes place in line
(11): now (11) is an access to the illegal address 0x1, causing the segfault.
The problem goes away when compiling without optimization or when making
the allocate() member function non-inline (by giving its definition outside
the class definition).
The incriminated pieces of source code come from the current beta snapshot
of the CORE library. Other parts of the source code come from gmp-4.1.3
and boost-1.30.2 and the yet unreleased EXACUS library project. Their
various open source licenses apply.
I'm using g++-3.3.3 which was configured as follows:
./configure --prefix=/usr/local/gcc-3.3/gcc-3.3.3 --program-suffix=-3.3.3
--enable-languages=c,c++ : (reconfigured) ./configure
--prefix=/usr/local/gcc-3.3/gcc-3.3.3 --program-suffix=-3.3.3
--enable-languages=c,c++ : (reconfigured) ./configure
--prefix=/usr/local/gcc-3.3/gcc-3.3.3 --program-suffix=-3.3.3
--enable-languages=c,c++
Thanks a lot in advance!
--
Summary: Instruction scheduling with -O2 on i686 creates fatal
aliasing bug
Product: gcc
Version: 3.3.3
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: optimization
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: arno at mpi-sb dot mpg dot de
CC: gcc-bugs at gcc dot gnu dot org
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=15295