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  <ja...@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

Reply via email to