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]>
