https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127965
--- Comment #5 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:56fcf06ffbdf39d3a6a20298d9c0a3a80fc95f70 commit r17-5401-g56fcf06ffbdf39d3a6a20298d9c0a3a80fc95f70 Author: Jakub Jelinek <[email protected]> Date: Tue Oct 20 12:06:59 2026 +0200 isel: Fix up optimize_atomic_bit_test_and [PR127965] If __atomic_fetch_{or,and}_* has its lhs used only in a cast, optimize_atomic_bit_test_and accepts it in some cases with else if (TYPE_PRECISION (TREE_TYPE (use_lhs)) <= TYPE_PRECISION (TREE_TYPE (use_rhs))) condition where use_lhs is the lhs of the cast and use_rhs is the rhs1 of that. This is used with there is ~ operation followed by NOP_EXPR to BOOLEAN_TYPE (in that case narrowing conversion is ok and we just verify the atomic operation ors in or performs and not of the least significant bit, or if there is masking and we verify corresponding mask (again, narrowing cast is ok). r13-3760 added another case, < 0 or >= 0 comparisons as a pattern to test the most significant bit. Initially I thought narrowing conversion would need to be avoided for that case, but it is just fine, all we need to do is use the correct and mask for that, use most significant bit of the narrower type (i.e. TREE_TYPE (use_lhs) instead of TREE_TYPE (use_rhs). Even that doesn't fix everything, another problem was that it was computing the most significant bit from TYPE_SIZE_UNIT multiplied by BITS_PER_UNIT. That works for type_has_mode_precision_p types, but not for others, e.g. _BitInt. < 0 compares the most significant bit of its precision. Furthermore, just in case, I've added a test for !TYPE_UNSIGNED, in simplified code < 0 or >= 0 on unsigned would be likely optimized away, but maybe we get unsimplified stmt. The other changes are fixes for typos in the surrounding comments and some formatting nits. 2026-10-20 Jakub Jelinek <[email protected]> PR tree-optimization/127965 * gimple-isel.cc (optimize_atomic_bit_test_and): For the < 0 and >= 0 cases, punt if TREE_TYPE (use_lhs) is unsigned. Compute ibit from TYPE_PRECISION of TREE_TYPE (use_lhs) rather than TYPE_SIZE_UNIT of TREE_TYPE (use_rhs). Fix comment pastos and other nits. Formatting fix. (gimple_isel_builtin_call): Formatting fix. * gcc.dg/pr127965-1.c: New test. * gcc.dg/pr127965-2.c: New test. * gcc.target/i386/pr127965-1.c: New test. * gcc.target/i386/pr127965-2.c: New test. Reviewed-by: Richard Biener <[email protected]>
