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

--- Comment #3 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jakub Jelinek <[email protected]>:

https://gcc.gnu.org/g:253c4edd1d5d20d562ca89329d9664812538f0a5

commit r17-4807-g253c4edd1d5d20d562ca89329d9664812538f0a5
Author: Jakub Jelinek <[email protected]>
Date:   Thu Oct 1 10:38:49 2026 +0200

    bitintlower: Fix up bswapg/bitreverseg lowering [PR127669]

    The following testcase is miscompiled for 2 reasons.

    One missed optimization is that fold_stmt_1 doesn't seem to attempt to
    use fold_const_call for internal functions into whose argument a constant
    is propagated.  For normal builtins, I think fold_stmt_1 ->
gimple_fold_call
    -> gimple_fold_builtin -> fold_call_stmt -> fold_builtin_n ->
    fold_builtin_{1,2,3} -> fold_const_call optimizes it, but for internal
    fns we just have selected set of optimizations we do on them but
    fold_const_call isn't among those.  That would be certainly nice to get
    fixed, but this patch doesn't do that.

    The other problem is forgotten flag.  Because of the above missed
    optimization we end up with .BITREVERSE (1) call before bitintlower, where
    that 1 is unsigned _BitInt(129).  If there is a partial limb (like in
    this case 1 bit), we emit handling of the result partial limb in straight
    line code (but that actually reads some bits from the least significant
limb
    of the function argument), and then have a loop to handle the remaining
    limbs.  We use there handle_operand with an index which is not constant
    in the loop (obviously) and using this read any limbs in the argument in
    reverse order, including the partial limb.
    Now, handle_operand has an optimization, for most of the lowerings we have
    a guarantee that the partial limb is accessed only in straight line code
with
    a constant index and e.g. for constants reading the partial limb in that
    case simply folds into the constant value of that partial limb.  So, we
    optimize and emit into .rodata only fewer limbs (all but the partial one)
    unless it is one of the even more optimized ones (where we treat 0, all
ones
    or values fitting into fewer limbs by always using a constant or by
    extending at runtime).  The exception to this has been the LSHIFT_EXPR
    lowering and we have the m_var_msb flag to tell we need all the bits
    including the partial limb.  Given the way .BSWAP/.BITREVERSE expansion
    works, we need that flag for those too.

    2026-10-01  Jakub Jelinek  <[email protected]>

            PR middle-end/127669
            * gimple-lower-bitint.cc
(bitint_large_huge::lower_bswap_bitreverse):
            Set m_var_msb to true.

            * gcc.dg/torture/bitint-110.c: New test.

    Reviewed-by: Richard Biener <[email protected]>

Reply via email to