Bug 15295 - Instruction scheduling with -O2 on i686 creates fatal aliasing bug
Summary: Instruction scheduling with -O2 on i686 creates fatal aliasing bug
Status: RESOLVED DUPLICATE of bug 11915
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 3.3.3
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-05-05 12:09 UTC by Arno Eigenwillig
Modified: 2005-07-23 22:49 UTC (History)
1 user (show)

See Also:
Host: i686-pc-linux-gnu
Target: i686-pc-linux-gnu
Build: i686-pc-linux-gnu
Known to work:
Known to fail:
Last reconfirmed:


Attachments
Test case mentioned in report (169.08 KB, application/gzip)
2004-05-05 12:11 UTC, Arno Eigenwillig
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Arno Eigenwillig 2004-05-05 12:09:55 UTC
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!
Comment 1 Arno Eigenwillig 2004-05-05 12:11:29 UTC
Created attachment 6225 [details]
Test case mentioned in report
Comment 2 Andrew Pinski 2004-05-05 12:41:27 UTC
This is a dup of either bug 11915, 14822 or many other invalid aliasing "bugs".

*** This bug has been marked as a duplicate of 11915 ***