This is the mail archive of the gcc-patches@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: Thread-safe profiling


> Because the -1LL will be 0xffffffffffffffff in the tree expression.  Now 
> the expand_expr call above will turn that tree constant into a RTL 
> constant, namely (const_int -1 [0xffffffff]), that is correct as far as I 
> can see, as RTL constants are implicitely sign extended.

This is actually a special case in convert_modes.  The code looks
like:

  if (unsignedp && GET_MODE_CLASS (mode) == MODE_INT
      && GET_MODE_BITSIZE (mode) == 2 * HOST_BITS_PER_WIDE_INT
      && GET_CODE (x) == CONST_INT && INTVAL (x) < 0)
    {
      HOST_WIDE_INT val = INTVAL (x);
      if (oldmode != VOIDmode
          && HOST_BITS_PER_WIDE_INT > GET_MODE_BITSIZE (oldmode))
        {
          int width = GET_MODE_BITSIZE (oldmode);

          /* We need to zero extend VAL.  */
          val &= ((HOST_WIDE_INT) 1 << width) - 1;
        }

      return immed_double_const (val, (HOST_WIDE_INT) 0, mode);
    }

But a few lines below, it says:

      /* ?? If we don't know OLDMODE, we have to assume here that
         X does not need sign- or zero-extension.   This may not be
         the case, but it's the best we can do.  */

Without your patch, oldmode is VOIDmode.  It looks to me like the
correct thing to do would be not to do the truncate and zero extension
in this case:

  if (unsignedp && GET_MODE_CLASS (mode) == MODE_INT
      && GET_MODE_BITSIZE (mode) == 2 * HOST_BITS_PER_WIDE_INT
      && GET_CODE (x) == CONST_INT && INTVAL (x) < 0

      /* If oldmode is VOIDmode, all we can do is hope that the
         constant was indeed signed and thus truncated to a
         CONST_INT.  In other words, we have to assume that X
         does not need sign- or zero-extension as we do below.  */
      && oldmode != VOIDmode)
    {
      HOST_WIDE_INT val = INTVAL (x);
      int width = GET_MODE_BITSIZE (oldmode);

      /* Test if we need to zero extend the low part too.  */
      if (width < HOST_BITS_PER_WIDE_INT)
        val &= ((HOST_WIDE_INT) 1 << width) - 1;

      return immed_double_const (val, (HOST_WIDE_INT) 0, mode);
    }

I haven't tested this in any way.  One {obv,ted}ious thing to test it
would be to put an "assert (oldmode != VOIDmode)" in the current
code, see how many tests break on 32-bit platforms with 32-bits
HOST_WODE_INT, and analyze them one by one...

Paolo


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