diff options
author | Richard Henderson <rth@redhat.com> | 2001-07-17 12:01:54 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2001-07-17 12:01:54 -0700 |
commit | 91a18fe0e6d96ec2cdad7d4f12ada3b4f5ed11e6 (patch) | |
tree | c9572ed6e5246afd03ce187bb2507cce9039341a | |
parent | 4fe706d8e0fc99538a988e63a3db7f529cd561d6 (diff) | |
download | gcc-91a18fe0e6d96ec2cdad7d4f12ada3b4f5ed11e6.zip gcc-91a18fe0e6d96ec2cdad7d4f12ada3b4f5ed11e6.tar.gz gcc-91a18fe0e6d96ec2cdad7d4f12ada3b4f5ed11e6.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/c-typeck.c | 16 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/20010717-1.c | 22 |
4 files changed, 34 insertions, 13 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 49be9d8..39b7e98 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 9e50c37..7bde430 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5d8d2dc..b266dfc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 diff --git a/gcc/testsuite/gcc.c-torture/execute/20010717-1.c b/gcc/testsuite/gcc.c-torture/execute/20010717-1.c new file mode 100644 index 0000000..65199da --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/20010717-1.c @@ -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; +} |