This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: help interpreting gcc 4.1.1 optimisation bug


andrew@walrond.org writes:
 > On Mon, Jun 12, 2006 at 12:32:36PM +0100, Andrew Haley wrote:
 > > andrew@walrond.org writes:
 > >  > I want a reduced test case for this problem for bugzilla, but don't
 > >  > really know the exact cause. I _think_ code is being improperly
 > >  > optimized away, but I don't know. This function is part of a
 > >  > BigInteger library, and works perfectly upto and including -O2, but
 > >  > produces bogus results at -O3, unless I uncomment the debug_msg()
 > >  > line, which just dumps the contents of 'i' to the screen. I'm
 > >  > guessing that without it, the compiler fails to notice that i's
 > >  > contents are being accessed via the _front8/_back8 pointers, and
 > >  > throws the preceeding 'i' related code away. Heres the code:
 > >  > 
 > >  >     void Integer::export_bytes(Data& _buffer, PortMode _mode) const
 > >  >     {
 > >  >         debug_scope("export_bytes(Data&)");
 > >  > 
 > >  >         Integer i(*this,1);
 > >  > 
 > >  >         if (_mode==SIGNED) {
 > >  >             if (*mBack & TOP_BIT)
 > >  >                 i.grow(1,0);
 > >  >             if (sign()<0)
 > >  >                 i.twoscomplement();
 > >  >         }
 > >  > 
 > >  >         for (UnsignedW* p=i.mFront; p<=i.mBack; p++)
 > >  >             *p = host2little(*p);
 > >  > 
 > >  >         Unsigned8* _front8 = reinterpret_cast<Unsigned8*>(i.mFront);
 > >  >         Unsigned8* _back8 = _front8+(i.mSize*WORD_BYTES)-1;
 > >  >         if (_mode==UNSIGNED)
 > >  >             while (_back8!=_front8 and *_back8==0)
 > >  >                 _back8--;
 > >  >         else if (mSign==1)
 > >  >             while (_back8!=_front8 and *_back8==0 and
 > >  >                    !(*(_back8-1)&0x80))
 > >  >                 _back8--;
 > >  >         else
 > >  >             while (_back8!=_front8 and *_back8==0xff and
 > >  >                    *(_back8-1)&0x80)
 > >  >                 _back8--;
 > >  > 
 > >  >         //debug_msg(String("Force i\n")+i.dump());
 > >  > 
 > >  >         _buffer.assign(_front8, _back8+1);
 > >  >     }
 > >  > 
 > >  > Any thoughts on how to proceed?
 > > 
 > > I think your code is broken.  A reinterpret_cast from foo* to bar* is
 > > only well-defined if foo and bar are compatible types or one of
 > > {foo,bar} is type char.  I can't be sure from your code, but I'm
 > > guessing that i.mFront is not declared as a pointer to Unsigned8, but
 > > as a pointer to an incompatible type UnsignedW.
 > 
 > typedef unsigned long UnsignedW;
 > typedef unsigned char Unsigned8;
 > typdef std::vector<Unsigned8> Data;
 > 
 > mFront is defined as UnsignedW*, an array of words constituting the
 > big integer.

OK.  That should be fine, then.

 > Having converted the words from host to little endian with
 > host2little(), I am simply reading (exporting) the bytes out into a
 > vector using std::vector::assign(InputIter first, InputIter last)
 > 
 > Seems legit, no?

The only likely significant difference with -O3 is that small
functions get inlined.

I'm starting to be a little suspicious about host2little().  I wonder
if that's well-defined.

I'm just guessing here becasue I can't see the code.  Is it possible
for you to turn this into a small test case that anyone can run?

Andrew.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]