aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Earnshaw <rearnsha@arm.com>2019-10-18 19:04:30 +0000
committerRichard Earnshaw <rearnsha@gcc.gnu.org>2019-10-18 19:04:30 +0000
commitdb962d0ad4501f2f673fc3fadd4ac572ef9a177e (patch)
treea05d2a014c9ad429bbdef51155c9ff57d92fab77 /gcc
parentdbba8a1707ffe25375282e0a075e7dff8d41ef90 (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/config/arm/arm.md78
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