https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125907
--- Comment #7 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The master branch has been updated by hongtao Liu <[email protected]>: https://gcc.gnu.org/g:31c8e6c019106d3e816e1bae77c4c9a70adf6957 commit r17-1950-g31c8e6c019106d3e816e1bae77c4c9a70adf6957 Author: liuhongt <[email protected]> Date: Sun Jun 21 23:29:49 2026 -0700 i386: Allow immediate cmov arm in *cmov_bt<mode> [PR125907] The "bt followed by cmov" splitter only matched when both cmov arms were nonimmediate_operand, so "(a & (1 << b)) ? c : imm" could not be folded into bt + cmov and instead emitted a sal/shr + and + cmov sequence. Keep the existing define_split for the two-register case unchanged, and add a separate define_insn_and_split for the immediate false-arm case. The immediate arm must be materialized into a register, and that extra move cannot be expressed in a combine define_split (which is limited to two insns), so the new pattern is a define_insn_and_split that combine recognizes as a single insn. Because it is a real insn whose split sets the flags register, it carries a (clobber (reg:CC FLAGS_REG)), matching the sibling bt helpers. gcc/ChangeLog: PR target/125907 * config/i386/i386.md (*cmov_bt<SWI248:mode>): New define_insn_and_split handling a const_int false arm, forced into a register by the splitter. Leave the existing define_split for the nonimmediate case unchanged. gcc/testsuite/ChangeLog: PR target/125907 * gcc.target/i386/bt-cmov-1.c: New test.
