Commit 91a18fe0 by Richard Henderson Committed by Richard Henderson

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
parent 4fe706d8
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
......
......@@ -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);
......
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
......
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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment