http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60533

            Bug ID: 60533
           Summary: [4.8/4.9 regression] Error introduced by bb-reorder at
                    -O3
           Product: gcc
           Version: 4.9.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: wschmidt at gcc dot gnu.org
                CC: ebotcazou at gcc dot gnu.org
              Host: powerpc64-unknown-linux-gnu
            Target: powerpc64-unknown-linux-gnu
             Build: powerpc64-unknown-linux-gnu

For GCC 4.8 and current trunk, compiling the attached test case with "g++ -O3"
produces an executable that fails with a memory access violation.  I've tracked
this down to the bb-reorder phase, which breaks up a lifetime of general
register 6 by moving its definition and one of its uses very far apart.  Since
r6 is a volatile register, the call clobbers its value, eventually resulting in
a bogus address.

The error is introduced into this function:

;; Function unsigned int vigra::labelVolume(SrcIterator, SrcShape,
SrcAccessor,\
 DestIterator, DestAccessor, Neighborhood3D, EqualityFunctor) [with
SrcIterator\
 = vigra::StridedMultiIterator<3u, int, const int&, const int*>; SrcAccessor =
\
vigra::StandardConstValueAccessor<int>; SrcShape = vigra::TinyVector<long int,
\
3>; DestIterator = vigra::StridedMultiIterator<3u, int, int&, int*>;
DestAccess\
or = vigra::StandardValueAccessor<int>; Neighborhood3D =
vigra::Neighborhood3DS\
ix::NeighborCode3D; EqualityFunctor = std::equal_to<int>]
(_ZN5vigra11labelVolu\
meINS_20StridedMultiIteratorILj3EiRKiPS2_EENS_26StandardConstValueAccessorIiEEN\
S_10TinyVectorIlLi3EEENS1_ILj3EiRiPiEENS_21StandardValueAccessorIiEENS_17Neighb\
orhood3DSix14NeighborCode3DESt8equal_toIiEEEjT_T1_T0_T2_T3_T4_T5_,
funcdef_no=5\
419, decl_uid=81154, cgraph_uid=1943)

I'm also attaching the dumps from before and after the bb-reorder phase.  In
the 225r.rtl_dce dump, r6 is defined by insn 266 in block 25, and used by insn
268 in block 25 and insn 283 in block 26.  Block 26 has block 25 as its only
predecessor.

Following bb-reorder, insns 266 and 268 are now in block 12, but insn 283 is in
block 87, a great distance away.  As a result, r6 is now upward exposed by insn
283 in block 87, which has blocks 12 and 86 as predecessors.  Block 86 ends
with a call in insn 887, which clobbers the volatile register r6.  So along the
path from block 86 to block 87, insn 283 is guaranteed to see garbage in r6.

There is nothing in the prior graph corresponding to a path from block 86 to
block 87; this bogus path was introduced by the block reordering.

(Apologies for the size of the preprocessed test case.  I tried to reduce it
with multidelta but kept hanging my machine partway through.)

Reply via email to