This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug rtl-optimization/25130] New: 4.1: miscompilation in loop optimization




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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]