https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120553
--- Comment #7 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The master branch has been updated by Uros Bizjak <u...@gcc.gnu.org>: https://gcc.gnu.org/g:ed57e5de634eda91f32e0e61724d8f103ef648dd commit r16-1196-ged57e5de634eda91f32e0e61724d8f103ef648dd Author: Uros Bizjak <ubiz...@gmail.com> Date: Thu Jun 5 22:53:35 2025 +0200 [i386] Improve "mov<mode>cc" expander for DImode immediates [PR120553] "mov<mode>cc" expander uses x86_64_general_operand predicate that limits the range of immediate operands to 32-bit size. The usage of this predicate causes ifcvt to force out-of-range immediates to registers when converting through noce_try_cmove. The testcase: long long foo (long long c) { return c >= 0 ? 0x400000000ll : -1ll; } compiles (-O2) to: foo: testq %rdi, %rdi movq $-1, %rax movabsq $0x400000000, %rdx cmovns %rdx, %rax ret The above testcase can be compiled to a more optimized code without problematic CMOV instruction if 64-bit immediates are allowed in "mov<mode>cc" expander: foo: movq %rdi, %rax sarq $63, %rax btsq $34, %rax ret The expander calls the ix86_expand_int_movcc function which internally sanitizes arguments of emitted logical insns using expand_simple_binop. The out-of-range immediates are forced to a temporary register just before the instruction, so the instruction combiner is then able to synthesize 64-bit BTS instruction. The code improves even for non-exact-log2 64-bit immediates, e.g. long long foo (long long c) { return c >= 0 ? 0x400001234ll : -1ll; } that now compiles to: foo: movabsq $0x400001234, %rdx movq %rdi, %rax sarq $63, %rax orq %rdx, %rax ret again avoiding problematic CMOV instruction. PR target/120553 gcc/ChangeLog: * config/i386/i386.md (mov<mode>cc): Use "general_operand" predicate for operands 2 and 3 for all modes. gcc/testsuite/ChangeLog: * gcc.target/i386/pr120553.c: New test.