https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113722

--- Comment #5 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jakub Jelinek <ja...@gcc.gnu.org>:

https://gcc.gnu.org/g:09df058a09f888daad26fa80634068b38b4ad04d

commit r14-8776-g09df058a09f888daad26fa80634068b38b4ad04d
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Sat Feb 3 14:38:27 2024 +0100

    wide-int: Fix up wi::bswap_large [PR113722]

    Since bswap has been converted from a method to a function we miscompile
    the following testcase.  The problem is the assumption that the passed in
    len argument (number of limbs in the xval array) is the upper bound for the
    bswap result, which is true only if precision is <= 64.  If precision is
    larger than that, e.g. 128 as in the testcase, if the argument has only
    one limb (i.e. 0 to ~(unsigned HOST_WIDE_INT) 0), the result can still
    need 2 limbs for that precision, or generally BLOCKS_NEEDED (precision)
    limbs, it all depends on how many least significant limbs of the operand
    are zero.  bswap_large as implemented only cleared len limbs of result,
    then swapped the bytes (invoking UB when oring something in all the limbs
    above it) and finally passed len to canonize, saying that more limbs
    aren't needed.

    The following patch fixes it by renaming len to xlen (so that it is clear
    it is X's length), using it solely for safe_uhwi argument when we attempt
    to read from X, and using new len = BLOCKS_NEEDED (precision) instead in
    the other two spots (i.e. when clearing the val array, turned it also
    into memset, and in canonize argument).  wi::bswap asserts it isn't invoked
    on widest_int, so we are always invoked on wide_int or similar and those
    have preallocated result sized for the corresponding precision (i.e.
    BLOCKS_NEEDED (precision)).

    2024-02-03  Jakub Jelinek  <ja...@redhat.com>

            PR middle-end/113722
            * wide-int.cc (wi::bswap_large): Rename third argument from
            len to xlen and adjust use in safe_uhwi.  Add len variable, set
            it to BLOCKS_NEEDED (precision) and use it for clearing of val
            and as canonize argument.  Clear val using memset instead of
            a loop.

            * gcc.dg/pr113722.c: New test.

Reply via email to