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 >