You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[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
0 commit comments