]> git.ipfire.org Git - thirdparty/gcc.git/commit
[arm] Improve handling of DImode comparisions against constants.
authorrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 18 Oct 2019 19:03:35 +0000 (19:03 +0000)
committerrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 18 Oct 2019 19:03:35 +0000 (19:03 +0000)
commitd6852b4754ab01c95fded5453fd9fa93dbb7ea94
tree3b043d4b797da18e48a2963b8c3b12f8102d6769
parent1790ea25c003bac0d71094c4b2c0ca2ec9ddad29
[arm] Improve handling of DImode comparisions against constants.

In almost all cases it is better to handle inequality handling against constants
by transforming comparisons of the form (reg <GE/LT/GEU/LTU> const) into
(reg <GT/LE/GTU/LEU> (const+1)).  However, there are many cases that we could
handle but currently failed to do so because we forced the constant into a
register too early in the pattern expansion.  To permit this to be done we need
to defer forcing the constant into a register until after we've had the chance
to do the transform - in some cases that may even mean that we no-longer need
to force the constant into a register at all.  For example, on Arm, the case:

_Bool f8 (unsigned long long a) { return a > 0xffffffff; }

previously compiled to

        mov     r3, #0
        cmp     r1, r3
        mvn     r2, #0
        cmpeq   r0, r2
        movhi   r0, #1
        movls   r0, #0
        bx      lr

But now compiles to

        cmp     r1, #1
        cmpeq   r0, #0
        movcs   r0, #1
        movcc   r0, #0
        bx      lr

Which although not yet completely optimal, is certainly better than
previously.

* config/arm/arm.md (cbranchdi4): Accept reg_or_int_operand for
operand 2.
(cstoredi4): Similarly, but for operand 3.
* config/arm/arm.c (arm_canoncialize_comparison): Allow canonicalization
of unsigned compares with a constant on Arm.  Prefer using const+1 and
adjusting the comparison over swapping the operands whenever the
original constant was not valid.
(arm_gen_dicompare_reg): If Y is not a valid operand, force it to a
register here.
(arm_validize_comparison): Do not force invalid DImode operands to
registers here.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@277178 138bc75d-0d04-0410-961f-82ee72b054a4
gcc/ChangeLog
gcc/config/arm/arm.c
gcc/config/arm/arm.md