[arm] Improve handling of DImode comparisions against constants.
authorRichard Earnshaw <rearnsha@arm.com>
Fri, 18 Oct 2019 19:03:35 +0000 (19:03 +0000)
committerRichard Earnshaw <rearnsha@gcc.gnu.org>
Fri, 18 Oct 2019 19:03:35 +0000 (19:03 +0000)
commit22060d0e575e7754eb1355763d22bbe37c3caa13
tree3b043d4b797da18e48a2963b8c3b12f8102d6769
parent5899656b61231cc0e2dac4d7a58fab58674ba344
[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.

From-SVN: r277178
gcc/ChangeLog
gcc/config/arm/arm.c
gcc/config/arm/arm.md