This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix up sign extension in bswap
- From: Jakub Jelinek <jakub at redhat dot com>
- To: "Thomas Preud'homme" <thomas dot preudhomme at arm dot com>, Richard Biener <rguenther at suse dot de>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 28 Oct 2014 13:27:14 +0100
- Subject: [PATCH] Fix up sign extension in bswap
- Authentication-results: sourceware.org; auth=none
- References: <000001cfd198$71470e30$53d52a90$ at arm dot com> <CAFiYyc12bCCxtunYgib+kPvY7-R=ygiw0sBY-bPz=V7NkqPRyQ at mail dot gmail dot com> <000601cfed11$6702fdf0$3508f9d0$ at arm dot com>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
On Tue, Oct 21, 2014 at 10:28:40AM +0100, Thomas Preud'homme wrote:
> --- a/gcc/tree-ssa-math-opts.c
> +++ b/gcc/tree-ssa-math-opts.c
> @@ -1916,7 +1916,8 @@ find_bswap_or_nop_1 (gimple stmt, struct symbolic_number *n, int limit)
> if (!TYPE_UNSIGNED (n->type) && type_size > old_type_size
> && HEAD_MARKER (n->n, old_type_size))
> for (i = 0; i < type_size - old_type_size; i++)
> - n->n |= MARKER_BYTE_UNKNOWN << (type_size - 1 - i);
> + n->n |= MARKER_BYTE_UNKNOWN
> + << ((type_size - 1 - i) * BITS_PER_MARKER);
>
> if (type_size < 64 / BITS_PER_MARKER)
> {
As my last bootstrap-ubsan bootstrap revealed, this is still wrong.
Here is a fix (other spots where MARKER_BYTE_UNKNOWN is shifted up
are correct). Bootstrapped/regtested on i686-linux, ok for trunk?
Thomas, you know the code better, can you from the fix figure out
a testcase that current trunk miscompiles or doesn't optimize
because of this bug?
2014-10-28 Jakub Jelinek <jakub@redhat.com>
* tree-ssa-math-opts.c (find_bswap_or_nop_1): Use uint64_t
type for the left shift in CASE_CONVERT case.
--- gcc/tree-ssa-math-opts.c.jj 2014-10-27 19:41:14.000000000 +0100
+++ gcc/tree-ssa-math-opts.c 2014-10-27 23:43:41.956495361 +0100
@@ -1926,7 +1926,7 @@ find_bswap_or_nop_1 (gimple stmt, struct
if (!TYPE_UNSIGNED (n->type) && type_size > old_type_size
&& HEAD_MARKER (n->n, old_type_size))
for (i = 0; i < type_size - old_type_size; i++)
- n->n |= MARKER_BYTE_UNKNOWN
+ n->n |= (uint64_t) MARKER_BYTE_UNKNOWN
<< ((type_size - 1 - i) * BITS_PER_MARKER);
if (type_size < 64 / BITS_PER_MARKER)
Jakub