From dbba8a1707ffe25375282e0a075e7dff8d41ef90 Mon Sep 17 00:00:00 2001 From: Richard Earnshaw Date: Fri, 18 Oct 2019 19:04:22 +0000 Subject: [PATCH] [arm] Improve code generation for addvsi4. Similar to the improvements for uaddvsi4, this patch improves the code generation for addvsi4 to handle immediates and to add alternatives that better target thumb2. To do this we separate out the expansion of uaddvsi4 from that of uaddvdi4 and then add an additional pattern to handle constants. Also, while doing this I've fixed the incorrect usage of NE instead of COMPARE in the generated RTL. * config/arm/arm.md (addv4): Delete. (addvsi4): New pattern. Handle immediate values that the architecture supports. (addvdi4): New pattern. (addsi3_compareV): Rename to ... (addsi3_compareV_reg): ... this. Add constraints for thumb2 variants and use COMPARE rather than NE. (addsi3_compareV_imm): New pattern. * config/arm/arm.c (arm_select_cc_mode): Return CC_Vmode for a signed-overflow check. From-SVN: r277184 --- gcc/ChangeLog | 13 +++++++++ gcc/config/arm/arm.c | 8 ++++++ gcc/config/arm/arm.md | 63 ++++++++++++++++++++++++++++++++++++------- 3 files changed, 74 insertions(+), 10 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 902cf51a37c..4c82758a060 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2019-10-18 Richard Earnshaw + + * config/arm/arm.md (addv4): Delete. + (addvsi4): New pattern. Handle immediate values that the architecture + supports. + (addvdi4): New pattern. + (addsi3_compareV): Rename to ... + (addsi3_compareV_reg): ... this. Add constraints for thumb2 variants + and use COMPARE rather than NE. + (addsi3_compareV_imm): New pattern. + * config/arm/arm.c (arm_select_cc_mode): Return CC_Vmode for + a signed-overflow check. + 2019-10-18 Richard Earnshaw * config/arm/arm-modes.def (CC_ADC): New CC mode. diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index fb1a6810651..ba23970d060 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -15411,6 +15411,14 @@ arm_select_cc_mode (enum rtx_code op, rtx x, rtx y) || arm_borrow_operation (y, DImode))) return CC_Bmode; + if (GET_MODE (x) == DImode + && (op == EQ || op == NE) + && GET_CODE (x) == PLUS + && GET_CODE (XEXP (x, 0)) == SIGN_EXTEND + && GET_CODE (y) == SIGN_EXTEND + && GET_CODE (XEXP (y, 0)) == PLUS) + return CC_Vmode; + if (GET_MODE_CLASS (GET_MODE (x)) == MODE_CC) return GET_MODE (x); diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 9f0e43571fd..b5214c79c35 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -488,14 +488,30 @@ " ) -(define_expand "addv4" - [(match_operand:SIDI 0 "register_operand") - (match_operand:SIDI 1 "register_operand") - (match_operand:SIDI 2 "register_operand") +(define_expand "addvsi4" + [(match_operand:SI 0 "s_register_operand") + (match_operand:SI 1 "s_register_operand") + (match_operand:SI 2 "arm_add_operand") (match_operand 3 "")] "TARGET_32BIT" { - emit_insn (gen_add3_compareV (operands[0], operands[1], operands[2])); + if (CONST_INT_P (operands[2])) + emit_insn (gen_addsi3_compareV_imm (operands[0], operands[1], operands[2])); + else + emit_insn (gen_addsi3_compareV_reg (operands[0], operands[1], operands[2])); + arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]); + + DONE; +}) + +(define_expand "addvdi4" + [(match_operand:DI 0 "register_operand") + (match_operand:DI 1 "register_operand") + (match_operand:DI 2 "register_operand") + (match_operand 3 "")] + "TARGET_32BIT" +{ + emit_insn (gen_adddi3_compareV (operands[0], operands[1], operands[2])); arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]); DONE; @@ -770,21 +786,48 @@ (set_attr "type" "multiple")] ) -(define_insn "addsi3_compareV" +(define_insn "addsi3_compareV_reg" [(set (reg:CC_V CC_REGNUM) - (ne:CC_V + (compare:CC_V (plus:DI - (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) - (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))) + (sign_extend:DI (match_operand:SI 1 "register_operand" "%l,0,r")) + (sign_extend:DI (match_operand:SI 2 "register_operand" "l,r,r"))) (sign_extend:DI (plus:SI (match_dup 1) (match_dup 2))))) - (set (match_operand:SI 0 "register_operand" "=r") + (set (match_operand:SI 0 "register_operand" "=l,r,r") (plus:SI (match_dup 1) (match_dup 2)))] "TARGET_32BIT" "adds%?\\t%0, %1, %2" [(set_attr "conds" "set") + (set_attr "arch" "t2,t2,*") + (set_attr "length" "2,2,4") (set_attr "type" "alus_sreg")] ) +(define_insn "addsi3_compareV_imm" + [(set (reg:CC_V CC_REGNUM) + (compare:CC_V + (plus:DI + (sign_extend:DI + (match_operand:SI 1 "register_operand" "l,0,l,0,r,r")) + (match_operand 2 "arm_addimm_operand" "Pd,Py,Px,Pw,I,L")) + (sign_extend:DI (plus:SI (match_dup 1) (match_dup 2))))) + (set (match_operand:SI 0 "register_operand" "=l,l,l,l,r,r") + (plus:SI (match_dup 1) (match_dup 2)))] + "TARGET_32BIT + && INTVAL (operands[2]) == ARM_SIGN_EXTEND (INTVAL (operands[2]))" + "@ + adds%?\\t%0, %1, %2 + adds%?\\t%0, %0, %2 + subs%?\\t%0, %1, #%n2 + subs%?\\t%0, %0, #%n2 + adds%?\\t%0, %1, %2 + subs%?\\t%0, %1, #%n2" + [(set_attr "conds" "set") + (set_attr "arch" "t2,t2,t2,t2,*,*") + (set_attr "length" "2,2,2,2,4,4") + (set_attr "type" "alus_imm")] +) + (define_insn "addsi3_compare0" [(set (reg:CC_NOOV CC_REGNUM) (compare:CC_NOOV -- 2.30.2