]> git.ipfire.org Git - thirdparty/gcc.git/commit
[i386] Improve "mov<mode>cc" expander for DImode immediates [PR120553]
authorUros Bizjak <ubizjak@gmail.com>
Thu, 5 Jun 2025 20:53:35 +0000 (22:53 +0200)
committerUros Bizjak <ubizjak@gmail.com>
Thu, 5 Jun 2025 20:55:07 +0000 (22:55 +0200)
commited57e5de634eda91f32e0e61724d8f103ef648dd
tree2d6ebfaf85c77da30aad91f5894b6b204280d7c8
parenta27540cf24368aa377fa33f1055432d8ae68f6a6
[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.
gcc/config/i386/i386.md
gcc/testsuite/gcc.target/i386/pr120553.c [new file with mode: 0644]