c-typeck.c (build_binary_op): Do not shorten unsigned right shift after sign extension.

* c-typeck.c (build_binary_op): Do not shorten unsigned
        right shift after sign extension.

From-SVN: r44080
This commit is contained in:
Richard Henderson 2001-07-17 12:01:54 -07:00 committed by Richard Henderson
parent 4fe706d8e0
commit 91a18fe0e6
4 changed files with 34 additions and 13 deletions

View File

@ -1,3 +1,8 @@
2001-07-17 Richard Henderson <rth@redhat.com>
* c-typeck.c (build_binary_op): Do not shorten unsigned
right shift after sign extension.
Tue Jul 17 16:56:05 CEST 2001 Jan Hubicka <jh@suse.cz>
* combine.c (combine_simplify_rtx): Attempt to simplify

View File

@ -2469,22 +2469,12 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
/* 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))))
/* 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));
= 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);

View File

@ -1,3 +1,7 @@
2001-07-17 Richard Henderson <rth@redhat.com>
* gcc.c-torture/execute/20010717-1.c: New.
2001-07-17 Joseph S. Myers <jsm28@cam.ac.uk>
* gcc.c-torture/compile/20010714-1.c, gcc.dg/format/attr-4.c: New

View File

@ -0,0 +1,22 @@
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;
if (r1 != r2)
abort ();
return 0;
}