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> Tue Jul 17 16:56:05 CEST 2001 Jan Hubicka <jh@suse.cz>
* combine.c (combine_simplify_rtx): Attempt to simplify * combine.c (combine_simplify_rtx): Attempt to simplify
......
...@@ -2469,22 +2469,12 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) ...@@ -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 /* We can shorten only if the shift count is less than the
number of bits in the smaller type size. */ number of bits in the smaller type size. */
&& compare_tree_int (op1, TYPE_PRECISION (TREE_TYPE (arg0))) < 0 && compare_tree_int (op1, TYPE_PRECISION (TREE_TYPE (arg0))) < 0
/* If arg is sign-extended and then unsigned-shifted, /* We cannot drop an unsigned shift after sign-extension. */
we can simulate this with a signed shift in arg's type && (!TREE_UNSIGNED (final_type) || unsigned_arg))
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. */ /* Do an unsigned shift if the operand was zero-extended. */
result_type result_type
= signed_or_unsigned_type (unsigned_arg, = signed_or_unsigned_type (unsigned_arg, TREE_TYPE (arg0));
TREE_TYPE (arg0));
/* Convert value-to-be-shifted to that type. */ /* Convert value-to-be-shifted to that type. */
if (TREE_TYPE (op0) != result_type) if (TREE_TYPE (op0) != result_type)
op0 = convert (result_type, op0); 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> 2001-07-17 Joseph S. Myers <jsm28@cam.ac.uk>
* gcc.c-torture/compile/20010714-1.c, gcc.dg/format/attr-4.c: New * 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