On Wed, May 11, 2011 at 8:26 PM, Jakub Jelinek <ja...@redhat.com> wrote:
> Hi!
>
> My http://gcc.gnu.org/ml/gcc-patches/2010-03/msg01379.html
> debug info optimization (meant primarily for x86_64) as the following
> testcase shows unfortunately breaks on powerpc64-linux and can in theory
> everywhere where lowpart_subreg of some REG accepted by
> use_narrower_mode_test isn't valid and thus returns NULL.
>
> This patch fixes it by not optimizing if the SUBREG isn't valid.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux (where it never
> hits though) and on the testcase on powerpc64-linux.
>
> Ok for trunk/4.6?

Ok.

Thanks,
Richard.

> 2011-05-11  Jakub Jelinek  <ja...@redhat.com>
>
>        PR debug/48967
>        * var-tracking.c (use_narrower_mode_test) <case REG>: Return 1
>        if validate_subreg fails.
>
>        * g++.dg/opt/pr48967.C: New test.
>
> --- gcc/var-tracking.c.jj       2011-05-11 19:39:04.000000000 +0200
> +++ gcc/var-tracking.c  2011-05-11 19:51:48.000000000 +0200
> @@ -745,6 +745,10 @@ use_narrower_mode_test (rtx *loc, void *
>     case REG:
>       if (cselib_lookup (*loc, GET_MODE (SUBREG_REG (subreg)), 0, VOIDmode))
>        return 1;
> +      if (!validate_subreg (GET_MODE (subreg), GET_MODE (*loc),
> +                           *loc, subreg_lowpart_offset (GET_MODE (subreg),
> +                                                        GET_MODE (*loc))))
> +       return 1;
>       return -1;
>     case PLUS:
>     case MINUS:
> --- gcc/testsuite/g++.dg/opt/pr48967.C.jj       2011-05-11 19:52:56.000000000 
> +0200
> +++ gcc/testsuite/g++.dg/opt/pr48967.C  2011-05-11 19:52:27.000000000 +0200
> @@ -0,0 +1,98 @@
> +// PR debug/48967
> +// { dg-do compile }
> +// { dg-options "-g -O2" }
> +
> +template <typename> struct A;
> +template <typename T> struct A <T *>
> +{
> +  typedef T ref;
> +};
> +template <typename T, typename> struct B
> +{
> +  typedef A <T> t;
> +  typedef typename t::ref ref;
> +  ref operator * () { return ref (); }
> +};
> +template <typename T> struct I
> +{
> +  typedef T *cp;
> +  template <typename T1> struct J
> +  {
> +    typedef I <T1> other;
> +  };
> +};
> +template <typename T> struct S : public I <T>
> +{
> +};
> +template <typename T, typename _A> struct E
> +{
> +  typedef typename _A::template J <T>::other at;
> +};
> +template <typename T, typename _A = S <T> > struct D
> +{
> +  typedef E <T, _A> _Base;
> +  typedef typename _Base::at at;
> +  typedef typename at::cp cp;
> +  typedef B <cp, D> H;
> +};
> +template <class T> struct F
> +{
> +  T *operator -> () { return __null; }
> +};
> +template <typename T> long
> +lfloor (T x)
> +{
> +  return static_cast <long>(x) - (x && x != static_cast <long>(x));
> +}
> +template <typename T> long
> +lround (T x)
> +{
> +  return lfloor (x - 0.5) + 1;
> +}
> +class M;
> +template <typename> class P;
> +typedef P <M> Q;
> +template <typename> struct P
> +{
> +  float x ();
> +};
> +struct CV
> +{
> +  Q c;
> +};
> +struct C
> +{
> +  void foo (const CV &) const;
> +  class O;
> +  typedef D <F <O> > R;
> +  R n;
> +};
> +struct S3
> +{
> +  S3 (int, int);
> +};
> +struct S2
> +{
> +  S3 sx, sy;
> +  S2 (int x = 0, int y = 0, int s = 0, int t = 0) : sx (x, y), sy (s, t) {}
> +};
> +template <typename> struct N
> +{
> +  int bar ();
> +};
> +struct C::O
> +{
> +  N <float> o;
> +  void foo (CV r, int)
> +  {
> +    Q c = r.c;
> +    float t = 0.5 * (o.bar ());
> +    S2 (lround (c.x ()), t);
> +  }
> +};
> +void
> +C::foo (const CV &w) const
> +{
> +  R::H m;
> +  (*m)->foo (w, 8);
> +}
>
>        Jakub
>

Reply via email to