diff options
author | Richard Earnshaw <rearnsha@arm.com> | 2019-10-18 19:04:30 +0000 |
---|---|---|
committer | Richard Earnshaw <rearnsha@gcc.gnu.org> | 2019-10-18 19:04:30 +0000 |
commit | db962d0ad4501f2f673fc3fadd4ac572ef9a177e (patch) | |
tree | a05d2a014c9ad429bbdef51155c9ff57d92fab77 /gcc | |
parent | dbba8a1707ffe25375282e0a075e7dff8d41ef90 (diff) | |
download | gcc-db962d0ad4501f2f673fc3fadd4ac572ef9a177e.zip gcc-db962d0ad4501f2f673fc3fadd4ac572ef9a177e.tar.gz gcc-db962d0ad4501f2f673fc3fadd4ac572ef9a177e.tar.bz2 |
[arm] Allow the summation result of signed add-with-overflow to be discarded.
This patch matches the signed add-with-overflow patterns when the
summation itself is dropped. In this case we can use CMN (or CMP with
some immediates). There are a small number of constants in thumb2
where this can result in less dense code (as we lack 16-bit CMN with
immediate patterns). To handle this we use peepholes to try these
alternatives when either a scratch is available (0 <= i <= 7) or the
original register is dead (0 <= i <= 255). We don't use a scratch in
the pattern as if those conditions are not satisfied then the 32-bit
form is preferable to forcing a reload.
* config/arm/arm.md (addsi3_compareV_reg_nosum): New insn.
(addsi3_compareV_imm_nosum): New insn. Also add peephole2 patterns
to transform this back into the summation version when that leads
to smaller code.
From-SVN: r277185
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/config/arm/arm.md | 78 |
2 files changed, 85 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4c82758..4a5a139 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,12 @@ 2019-10-18 Richard Earnshaw <rearnsha@arm.com> + * config/arm/arm.md (addsi3_compareV_reg_nosum): New insn. + (addsi3_compareV_imm_nosum): New insn. Also add peephole2 patterns + to transform this back into the summation version when that leads + to smaller code. + +2019-10-18 Richard Earnshaw <rearnsha@arm.com> + * config/arm/arm.md (addv<mode>4): Delete. (addvsi4): New pattern. Handle immediate values that the architecture supports. diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index b5214c7..be002f7 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -803,6 +803,21 @@ (set_attr "type" "alus_sreg")] ) +(define_insn "*addsi3_compareV_reg_nosum" + [(set (reg:CC_V CC_REGNUM) + (compare:CC_V + (plus:DI + (sign_extend:DI (match_operand:SI 0 "register_operand" "%l,r")) + (sign_extend:DI (match_operand:SI 1 "register_operand" "l,r"))) + (sign_extend:DI (plus:SI (match_dup 0) (match_dup 1)))))] + "TARGET_32BIT" + "cmn%?\\t%0, %1" + [(set_attr "conds" "set") + (set_attr "arch" "t2,*") + (set_attr "length" "2,4") + (set_attr "type" "alus_sreg")] +) + (define_insn "addsi3_compareV_imm" [(set (reg:CC_V CC_REGNUM) (compare:CC_V @@ -828,6 +843,69 @@ (set_attr "type" "alus_imm")] ) +(define_insn "addsi3_compareV_imm_nosum" + [(set (reg:CC_V CC_REGNUM) + (compare:CC_V + (plus:DI + (sign_extend:DI + (match_operand:SI 0 "register_operand" "l,r,r")) + (match_operand 1 "arm_addimm_operand" "Pw,I,L")) + (sign_extend:DI (plus:SI (match_dup 0) (match_dup 1)))))] + "TARGET_32BIT + && INTVAL (operands[1]) == ARM_SIGN_EXTEND (INTVAL (operands[1]))" + "@ + cmp%?\\t%0, #%n1 + cmn%?\\t%0, %1 + cmp%?\\t%0, #%n1" + [(set_attr "conds" "set") + (set_attr "arch" "t2,*,*") + (set_attr "length" "2,4,4") + (set_attr "type" "alus_imm")] +) + +;; We can handle more constants efficently if we can clobber either a scratch +;; or the other source operand. We deliberately leave this late as in +;; high register pressure situations it's not worth forcing any reloads. +(define_peephole2 + [(match_scratch:SI 2 "l") + (set (reg:CC_V CC_REGNUM) + (compare:CC_V + (plus:DI + (sign_extend:DI + (match_operand:SI 0 "low_register_operand")) + (match_operand 1 "const_int_operand")) + (sign_extend:DI (plus:SI (match_dup 0) (match_dup 1)))))] + "TARGET_THUMB2 + && satisfies_constraint_Pd (operands[1])" + [(parallel[ + (set (reg:CC_V CC_REGNUM) + (compare:CC_V + (plus:DI (sign_extend:DI (match_dup 0)) + (sign_extend:DI (match_dup 1))) + (sign_extend:DI (plus:SI (match_dup 0) (match_dup 1))))) + (set (match_dup 2) (plus:SI (match_dup 0) (match_dup 1)))])] +) + +(define_peephole2 + [(set (reg:CC_V CC_REGNUM) + (compare:CC_V + (plus:DI + (sign_extend:DI + (match_operand:SI 0 "low_register_operand")) + (match_operand 1 "const_int_operand")) + (sign_extend:DI (plus:SI (match_dup 0) (match_dup 1)))))] + "TARGET_THUMB2 + && dead_or_set_p (peep2_next_insn (0), operands[0]) + && satisfies_constraint_Py (operands[1])" + [(parallel[ + (set (reg:CC_V CC_REGNUM) + (compare:CC_V + (plus:DI (sign_extend:DI (match_dup 0)) + (sign_extend:DI (match_dup 1))) + (sign_extend:DI (plus:SI (match_dup 0) (match_dup 1))))) + (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))])] +) + (define_insn "addsi3_compare0" [(set (reg:CC_NOOV CC_REGNUM) (compare:CC_NOOV |