+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
/* 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
--- /dev/null
+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;
+}