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.)