public inbox for gcc-prs@sourceware.org
help / color / mirror / Atom feed
From: Richard Henderson <rth@redhat.com>
To: nobody@gcc.gnu.org
Cc: gcc-prs@gcc.gnu.org
Subject: Re: c/3651: shifting unsigned long on 64 bit machine incorrectly does sign extension
Date: Tue, 17 Jul 2001 02:06:00 -0000	[thread overview]
Message-ID: <20010717090602.18102.qmail@sourceware.cygnus.com> (raw)

The following reply was made to PR c/3651; it has been noted by GNATS.

From: Richard Henderson <rth@redhat.com>
To: mark.dewing@intel.com
Cc: gcc-gnats@gcc.gnu.org, gcc-patches@gcc.gnu.org
Subject: Re: c/3651: shifting unsigned long on 64 bit machine incorrectly does sign extension
Date: Tue, 17 Jul 2001 02:01:55 -0700

 On Wed, Jul 11, 2001 at 07:09:17PM -0000, mark.dewing@intel.com wrote:
 > Right shifting an unsigned long should not do a sign
 > extension.  This shift on an unsigned long variable works
 > okay, but doing this shift on an expression that has
 > been cast to unsigned long does not.
 > This problem also occurs on Alpha Tru64 with gcc 2.7.2.1
 > and IRIX with gcc 2.8.1 in 64 bit mode.
 
 I'm currently testing the following patch on alphaev6-linux.
 Assuming no regressions, I'll check it in tomorrow.
 
 
 r~
 
 
 	* c-typeck.c (build_binary_op): Do not shorten unsigned
 	right shift after sign extension.
 
 Index: c-typeck.c
 ===================================================================
 RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v
 retrieving revision 1.128
 diff -c -p -d -r1.128 c-typeck.c
 *** c-typeck.c	2001/07/07 01:07:17	1.128
 --- c-typeck.c	2001/07/17 08:56:46
 *************** build_binary_op (code, orig_op0, orig_op
 *** 2469,2490 ****
   	      /* We can shorten only if the shift count is less than the
   		 number of bits in the smaller type size.  */
   	      && compare_tree_int (op1, TYPE_PRECISION (TREE_TYPE (arg0))) < 0
 ! 	      /* If arg is sign-extended and then unsigned-shifted,
 ! 		 we can simulate this with a signed shift in arg's type
 ! 		 only if the extended result is at least twice as wide
 ! 		 as the arg.  Otherwise, the shift could use up all the
 ! 		 ones made by sign-extension and bring in zeros.
 ! 		 We can't optimize that case at all, but in most machines
 ! 		 it never happens because available widths are 2**N.  */
 ! 	      && (!TREE_UNSIGNED (final_type)
 ! 		  || unsigned_arg
 ! 		  || (2 * TYPE_PRECISION (TREE_TYPE (arg0))
 ! 		      <= TYPE_PRECISION (result_type))))
   	    {
   	      /* Do an unsigned shift if the operand was zero-extended.  */
   	      result_type
 ! 		= signed_or_unsigned_type (unsigned_arg,
 ! 					   TREE_TYPE (arg0));
   	      /* Convert value-to-be-shifted to that type.  */
   	      if (TREE_TYPE (op0) != result_type)
   		op0 = convert (result_type, op0);
 --- 2469,2480 ----
   	      /* We can shorten only if the shift count is less than the
   		 number of bits in the smaller type size.  */
   	      && compare_tree_int (op1, TYPE_PRECISION (TREE_TYPE (arg0))) < 0
 ! 	      /* We cannot drop an unsigned shift after sign-extension.  */
 ! 	      && (!TREE_UNSIGNED (final_type) || unsigned_arg))
   	    {
   	      /* Do an unsigned shift if the operand was zero-extended.  */
   	      result_type
 ! 		= signed_or_unsigned_type (unsigned_arg, TREE_TYPE (arg0));
   	      /* Convert value-to-be-shifted to that type.  */
   	      if (TREE_TYPE (op0) != result_type)
   		op0 = convert (result_type, op0);
 Index: testsuite/gcc.c-torture/execute/20010717-1.c
 ===================================================================
 RCS file: 20010717-1.c
 diff -N 20010717-1.c
 *** /dev/null	Tue May  5 13:32:27 1998
 --- 20010717-1.c	Tue Jul 17 01:56:46 2001
 ***************
 *** 0 ****
 --- 1,28 ----
 + static void test (unsigned long, unsigned long);
 + extern void abort (void);
 + 
 + int
 + main ()
 + {
 +   int i, j;
 +   unsigned long u, r1, r2;
 + 
 +   i = -16;
 +   j = 1;
 +   u = i + j;
 + 
 +   /* no sign extension upon shift */
 +   r1 = u >> 1;
 +   /* sign extension upon shift, but there shouldn't be */
 +   r2 = ((unsigned long) (i + j)) >> 1;
 +   test (r1, r2);
 + 
 +   return 0;
 + }
 + 
 + static void
 + test (unsigned long x, unsigned long y)
 + {
 +   if (x != y)
 +     abort ();
 + }


             reply	other threads:[~2001-07-17  2:06 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-07-17  2:06 Richard Henderson [this message]
  -- strict thread matches above, loose matches on Subject: below --
2002-04-23  2:09 rth
2001-07-11 12:16 mark.dewing

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=20010717090602.18102.qmail@sourceware.cygnus.com \
    --to=rth@redhat.com \
    --cc=gcc-prs@gcc.gnu.org \
    --cc=nobody@gcc.gnu.org \
    /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).