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

Reply via email to