------- Comment #29 from jakub at gcc dot gnu dot org 2007-12-11 11:13 ------- Actually, I was wrong, that insn 99 is inside of the if (__count == 1) { ... return ...; } So it is dbr that messes this up. Simplified testcase (only for visual inspection of the generated code, someone with access to pa could turn that into an executable testcase):
extern "C" void __assert (const char *, const char *, int); template<typename S, typename T> S foo1 (S s1, S s2, int i1, const int &i2, T t); template<typename S, typename T> S foo (S s1, S s2, int i1, const int &i2, T t) { if (i1 <= 0) return s1; if (i1 == 1) { while (s1 != s2 && !bool (t (*s1, i2))) ++s1; return s1; } return foo1 (s1, s2, i1, i2, t); } template<typename T> struct B { T *first; T *last; B (T *x, T *y) : first (x), last (y) { } }; template<class T> struct C { C () { } typedef B<T> BT; T *t; BT *bt; C (T *x, BT *y) : t (x), bt (y) { (t >= bt->first && t <= bt->last) ? (void) 0 : __assert ("f", "y", 203); } C (const C &in) : t (in.t), bt (in.bt) { } bool operator!= (const C& in) const { (bt != __null && bt == in.bt) ? (void) 0 : __assert ("g", "y", 212); (t >= bt->first && in.t >= bt->first) ? (void) 0 : __assert ("h", "y", 213); return t != in.t; } C& operator= (const C& in) { t = in.t; bt = in.bt; return *this; } }; template<class T> struct D : public C<T> { typedef B<T> BT; D (T *x, BT *y) : C<T> (x, y) { } D (const D &in) : C<T> (in) { } D () { this->t = __null; this->bt = __null; } T& operator* () const { (this->bt && this->t < this->bt->last) ? (void) 0 : __assert ("x", "y", 292); return *(this->t); } D& operator++ () { (this->bt && this->t < this->bt->last) ? (void) 0 : __assert ("z", "y", 303); this->t++; return *this; } }; bool pred (int i, int j) { return i == j; } int main () { int a[2] = { 0, 0 }; D<int>::BT ct (&a[0], &a[1]); foo (D<int> (&a[0], &ct), D<int> (&a[1], &ct), 0, 1, pred); return 0; } At -O2 this has: comib,>= 0,%r24,L$0025 stw %r4,-72(%r30) comib,= 1,%r24,L$0026 ldil LR'L$C0002,%r28 stw %r7,-52(%r30) ldw 4(%r26),%r20 ldo -112(%r30),%r25 ldo -120(%r30),%r26 stw %r20,-116(%r30) ldw 4(%r6),%r19 ldw 0(%r3),%r20 stw %r19,-108(%r30) stw %r20,-120(%r30) ldw 0(%r6),%r19 .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR bl _Z4foo1I1DIiEPFbiiEET_S4_S4_iRKiT0_,%r2 stw %r19,-112(%r30) where the undesirable ldil LR'L$C0002,%r28 is in the delay slot of the conditional branch. %r28 should contain the original %r28 value passed to the function. -- jakub at gcc dot gnu dot org changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |rsandifo at nildram dot co | |dot uk Component|rtl-optimization |tree-optimization http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32636