------- Comment #3 from wilson at tuliptree dot org  2008-04-12 00:45 -------
Subject: Re:   New: unsinged long long and while loop evaluation
 regression?

I can reproduce this on a 32-bit x86-linux machine (i.e. a 32-bit HWI). 
  The unsigned long long 0xffffffff becomes a (const_double -1 0), and 
then in expand_mult in expmed.c we have
           /* If we are multiplying in DImode, it may still be a win 

              to try to work with shifts and adds.  */
           if (CONST_DOUBLE_HIGH (op1) == 0)
             coeff = CONST_DOUBLE_LOW (op1);
After this line, expand_mult thinks we are multiplying by -1 and we get 
the wrong result.

I think there is a false assumption here that we can get CONST_DOUBLEs 
which can be simplified to a single word.  Maybe in the olden days we 
always created a CONST_DOUBLE for DImode constants?  This stuff has 
changed so many times it is hard to remember.  I don't think we do it 
that way anymore.

Anyways, if this assumption is not false, then the code needs to look 
more like the code in immed_double_const in emit-rtl.c, which does
   /* If this integer fits in one word, return a CONST_INT.  */
   if ((i1 == 0 && i0 >= 0) || (i1 == ~0 && i0 < 0))
     return GEN_INT (i0);
where i1 is CONST_DOUBLE_HIGH and i0 is CONST_DOUBLE_LOW, and only in 
the case that this tests succeeds can we set coeff to CONST_DOUBLE_LOW.

The same bug is in mainline, and probably goes a long ways back.

Jim


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35885

Reply via email to