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.

Reply via email to