On Thu, 5 Jun 2025, Uros Bizjak wrote: > "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.
Nice! > 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. > > Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}. > > Uros. > -- Richard Biener <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, Germany; GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)