public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Richard Guenther <richard.guenther@gmail.com>
To: Richard Guenther <richard.guenther@gmail.com>,
	Mike Stump <mikestump@comcast.net>,
		gcc-patches Patches <gcc-patches@gcc.gnu.org>,
	rdsandiford@googlemail.com
Subject: Re: remove wrong code in immed_double_const
Date: Tue, 20 Mar 2012 12:47:00 -0000	[thread overview]
Message-ID: <CAFiYyc1Mwzyf9ghQWZNQ4UcQ1EJovdX4qW49YOatZBZVLPK0hg@mail.gmail.com> (raw)
In-Reply-To: <g4zkbbfofy.fsf@richards-thinkpad.stglab.manchester.uk.ibm.com>

On Tue, Mar 20, 2012 at 1:26 PM, Richard Sandiford
<rdsandiford@googlemail.com> wrote:
> Richard Guenther <richard.guenther@gmail.com> writes:
>>> I've no objection to moving the assert down to after the GEN_INT.
>>> But it sounds like I'm on my own with the whole CONST_DOUBLE sign thing.
>>> (That is, if we remove the assert altogether, we effectively treat the
>>> number as sign-extended if it happens to fit in a CONST_INT, and
>>> zero-extended otherwise.
>>
>> Why do we treat it zero-extended otherwise?  Because we use
>> gen_int_mode for CONST_INTs, which sign-extends?
>
> Just to make sure we're not talking past each other, I meant
> moving the assert to:
>
>    /* If this integer fits in one word, return a CONST_INT.  */
> [A] if ((i1 == 0 && i0 >= 0) || (i1 == ~0 && i0 < 0))
>      return GEN_INT (i0);
>
> <---HERE--->
>
>    /* We use VOIDmode for integers.  */
>    value = rtx_alloc (CONST_DOUBLE);
>    PUT_MODE (value, VOIDmode);
>
>    CONST_DOUBLE_LOW (value) = i0;
>    CONST_DOUBLE_HIGH (value) = i1;
>
>    for (i = 2; i < (sizeof CONST_DOUBLE_FORMAT - 1); i++)
>      XWINT (value, i) = 0;
>
>    return lookup_const_double (value);
>
> [A] treats i0 and i1 as a sign-extended value.  So if we
> removed the assert (or moved it to the suggested place):
>
>    immed_double_const (-1, -1, 4_hwi_mode)
>
> would create -1 in 4_hwi_mode, represented as a CONST_INT.
> The three implicit high-order HWIs are -1.  That's fine,
> because CONST_INT has long been defined as sign-extending
> rather than zero-extending.
>
> But if we fail the [A] test, we go on to create a CONST_DOUBLE.
> The problem is that AIUI we have never defined what happens for
> CONST_DOUBLE if the mode is wider than 2 HWIs.  Again AIUI,
> that's why the assert is there.
>
> This matters because of things like the handling in simplify_immed_subreg
> (which, e.g., we use to generate CONST_DOUBLE pool constants, split
> constant moves in lower-subreg.c, etc.).  CONST_INT is already
> well-defined to be a sign-extended constant, and we handle it correctly:
>
>      switch (GET_CODE (el))
>        {
>        case CONST_INT:
>          for (i = 0;
>               i < HOST_BITS_PER_WIDE_INT && i < elem_bitsize;
>               i += value_bit)
>            *vp++ = INTVAL (el) >> i;
>          /* CONST_INTs are always logically sign-extended.  */
>          for (; i < elem_bitsize; i += value_bit)
>            *vp++ = INTVAL (el) < 0 ? -1 : 0;
>          break;
>
> But because of this assert, the equivalent meaning for
> CONST_DOUBLE has never been defined, and the current code
> happens to zero-extend it:
>
>        case CONST_DOUBLE:
>          if (GET_MODE (el) == VOIDmode)
>            {
>              /* If this triggers, someone should have generated a
>                 CONST_INT instead.  */
>              gcc_assert (elem_bitsize > HOST_BITS_PER_WIDE_INT);
>
>              for (i = 0; i < HOST_BITS_PER_WIDE_INT; i += value_bit)
>                *vp++ = CONST_DOUBLE_LOW (el) >> i;
>              while (i < HOST_BITS_PER_WIDE_INT * 2 && i < elem_bitsize)
>                {
>                  *vp++
>                    = CONST_DOUBLE_HIGH (el) >> (i - HOST_BITS_PER_WIDE_INT);
>                  i += value_bit;
>                }
>              /* It shouldn't matter what's done here, so fill it with
>                 zero.  */
>              for (; i < elem_bitsize; i += value_bit)
>                *vp++ = 0;
>            }
>
> So the upshot is that:
>
>    immed_double_const (-1, -1, 4_hwi_mode)
>
> sign-extends i1 (the second -1), creating (-1, -1, -1, -1).  But:
>
>    immed_double_const (0, -1, 4_hwi_mode)
>
> effectively (as the code falls out at the moment) zero-extends it,
> creating (0, -1, 0, 0).  That kind of inconsistency seems wrong.
>
> So what I was trying to say was that if we remove the assert
> altogether, and allow CONST_DOUBLEs to be wider than 2 HWIs,
> we need to define what the "implicit" high-order HWIs of a
> CONST_DOUBLE are, just like we already do for CONST_INT.
> If we remove the assert altogether, it very much matters
> what is done by that last "*vp" line.
>
> If Mike or anyone is up to doing that, then great.  But if instead
> it's just a case of handling zero correctly, moving rather than
> removing the assert seems safer.
>
> I'm obviously not explaining this well :-)

Ok, I see what you mean.  Yes, moving the assert past the GEN_INT
case (though that is specifically meant to deal with the VOIDmode case
I think?) is ok.

Thanks,
Richard.

> Richard

  reply	other threads:[~2012-03-20 12:47 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-03-16 21:54 Mike Stump
2012-03-16 22:04 ` Steven Bosscher
2012-03-17  1:03   ` Mike Stump
2012-03-17  7:37 ` Richard Sandiford
2012-03-18  0:29   ` Mike Stump
2012-03-18 10:16     ` Richard Sandiford
2012-03-18 16:35       ` Mike Stump
2012-03-19 21:44         ` Richard Sandiford
2012-03-19 23:31           ` Mike Stump
2012-03-20 10:32             ` Richard Guenther
2012-03-20 10:50               ` Richard Sandiford
2012-03-20 11:38                 ` Richard Guenther
2012-03-20 12:27                   ` Richard Sandiford
2012-03-20 12:47                     ` Richard Guenther [this message]
2012-03-20 13:55                     ` Michael Matz
2012-03-20 20:44                       ` Mike Stump
2012-03-21 13:47                         ` Michael Matz
2012-03-21 17:01                           ` Mike Stump
2012-03-22 13:16                             ` Michael Matz
2012-03-22 18:37                               ` Mike Stump
2012-03-20 19:41                     ` Mike Stump
2012-03-21  1:01                     ` Mike Stump
2012-03-21 13:17                       ` Richard Sandiford
2012-03-21 21:36                         ` Mike Stump
2012-03-22 10:16                           ` Richard Sandiford
2012-03-22 10:25                             ` Richard Sandiford
2012-03-22 20:28                             ` Mike Stump
2012-03-23 10:02                               ` Richard Sandiford
2012-03-26 19:14                                 ` Mike Stump
2012-03-26 20:04                                   ` Richard Sandiford
2012-03-26 23:57                                     ` Mike Stump
2012-04-04 21:07                                       ` Mike Stump
2012-03-22 14:12                           ` Michael Matz
2012-03-22 18:55                             ` Mike Stump

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAFiYyc1Mwzyf9ghQWZNQ4UcQ1EJovdX4qW49YOatZBZVLPK0hg@mail.gmail.com \
    --to=richard.guenther@gmail.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=mikestump@comcast.net \
    --cc=rdsandiford@googlemail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).