diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 01c06b16e1e..f42b287413b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2017-05-31 Graham Markall + + * config/arc/arc.c (arc_print_operand): Handle constant operands. + (arc_rtx_costs): Add costs for new patterns. + * config/arc/arc.md: Additional *add_n and *sub_n patterns. + * config/arc/predicates.md: Add _1_2_3_operand predicate. + 2017-05-31 Richard Sandiford * tree-ssa-strlen.c (get_next_strinfo): New function. diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c index 91c28e73554..42730d55d80 100644 --- a/gcc/config/arc/arc.c +++ b/gcc/config/arc/arc.c @@ -3483,6 +3483,14 @@ arc_print_operand (FILE *file, rtx x, int code) return; + case 'c': + if (GET_CODE (x) == CONST_INT) + fprintf (file, "%d", INTVAL (x) ); + else + output_operand_lossage ("invalid operands to %%c code"); + + return; + case 'M': if (GET_CODE (x) == CONST_INT) fprintf (file, "%d",exact_log2(~INTVAL (x)) ); @@ -4895,8 +4903,10 @@ arc_rtx_costs (rtx x, machine_mode mode, int outer_code, *total = COSTS_N_INSNS (2); return false; case PLUS: - if (GET_CODE (XEXP (x, 0)) == MULT - && _2_4_8_operand (XEXP (XEXP (x, 0), 1), VOIDmode)) + if ((GET_CODE (XEXP (x, 0)) == ASHIFT + && _1_2_3_operand (XEXP (XEXP (x, 0), 1), VOIDmode)) + || (GET_CODE (XEXP (x, 0)) == MULT + && _2_4_8_operand (XEXP (XEXP (x, 0), 1), VOIDmode))) { *total += (rtx_cost (XEXP (x, 1), mode, PLUS, 0, speed) + rtx_cost (XEXP (XEXP (x, 0), 0), mode, PLUS, 1, speed)); @@ -4904,8 +4914,10 @@ arc_rtx_costs (rtx x, machine_mode mode, int outer_code, } return false; case MINUS: - if (GET_CODE (XEXP (x, 1)) == MULT - && _2_4_8_operand (XEXP (XEXP (x, 1), 1), VOIDmode)) + if ((GET_CODE (XEXP (x, 1)) == ASHIFT + && _1_2_3_operand (XEXP (XEXP (x, 1), 1), VOIDmode)) + || (GET_CODE (XEXP (x, 1)) == MULT + && _2_4_8_operand (XEXP (XEXP (x, 1), 1), VOIDmode))) { *total += (rtx_cost (XEXP (x, 0), mode, PLUS, 0, speed) + rtx_cost (XEXP (XEXP (x, 1), 0), mode, PLUS, 1, speed)); diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md index edb983f1b2d..ec783a047f2 100644 --- a/gcc/config/arc/arc.md +++ b/gcc/config/arc/arc.md @@ -2993,6 +2993,19 @@ (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))]) (set (match_dup 3) (match_dup 4))]) +(define_insn "*add_n" + [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,W,W,w,w") + (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "Rcqq,c,c,c,c,c") + (match_operand:SI 2 "_1_2_3_operand" "")) + (match_operand:SI 3 "nonmemory_operand" "0,0,c,?Cal,?c,??Cal")))] + "" + "add%c2%? %0,%3,%1%&" + [(set_attr "type" "shift") + (set_attr "length" "*,4,4,8,4,8") + (set_attr "predicable" "yes,yes,no,no,no,no") + (set_attr "cond" "canuse,canuse,nocond,nocond,nocond,nocond") + (set_attr "iscompact" "maybe,false,false,false,false,false")]) + (define_insn "*add_n" [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,W,W,w,w") (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "Rcqq,c,c,c,c,c") @@ -3008,6 +3021,19 @@ ;; N.B. sub[123] has the operands of the MINUS in the opposite order from ;; what synth_mult likes. +(define_insn "*sub_n" + [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w") + (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,c,?Cal") + (ashift:SI (match_operand:SI 2 "register_operand" "c,c,c") + (match_operand:SI 3 "_1_2_3_operand" ""))))] + "" + "sub%c3%? %0,%1,%2" + [(set_attr "type" "shift") + (set_attr "length" "4,4,8") + (set_attr "predicable" "yes,no,no") + (set_attr "cond" "canuse,nocond,nocond") + (set_attr "iscompact" "false")]) + (define_insn "*sub_n" [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w") (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,c,?Cal") diff --git a/gcc/config/arc/predicates.md b/gcc/config/arc/predicates.md index 7ddec9149d1..1f6643853c5 100644 --- a/gcc/config/arc/predicates.md +++ b/gcc/config/arc/predicates.md @@ -615,6 +615,11 @@ (match_test "TARGET_ARC700 || TARGET_EA_SET"))) ) +(define_predicate "_1_2_3_operand" + (and (match_code "const_int") + (match_test "INTVAL (op) == 1 || INTVAL (op) == 2 || INTVAL (op) == 3")) +) + (define_predicate "_2_4_8_operand" (and (match_code "const_int") (match_test "INTVAL (op) == 2 || INTVAL (op) == 4 || INTVAL (op) == 8")) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8b74dc3364a..fa0bbef93a7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-05-31 Graham Markall + + * gcc.target/arc/add_n-combine.c: New test. + * gcc.target/arc/sub_n-combine.c: New test. + 2017-05-31 Richard Biener PR target/80880 diff --git a/gcc/testsuite/gcc.target/arc/add_n-combine.c b/gcc/testsuite/gcc.target/arc/add_n-combine.c new file mode 100644 index 00000000000..db6454f1462 --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/add_n-combine.c @@ -0,0 +1,48 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-rtl-combine" } */ + +struct b1 { + char c; + char bg; +}; + +struct bj1 { + char bk; + struct b1 bn[]; +}; + +struct b2 { + short c; + char bg; +}; + +struct bj2 { + short bk; + struct b2 bn[]; +}; + +struct b3 { + int c; + char bg; +}; + +struct bj3 { + int bk; + struct b3 bn[]; +}; + + +struct bj1 at1; +struct bj2 at2; +struct bj3 at3; + +int bu; +void a(); + +void f() { + a(at1.bn[bu]); + a(at2.bn[bu]); + a(at3.bn[bu]); +} + +/* { dg-final { scan-rtl-dump-times "\\*add_n" 3 "combine" } } */ diff --git a/gcc/testsuite/gcc.target/arc/sub_n-combine.c b/gcc/testsuite/gcc.target/arc/sub_n-combine.c new file mode 100644 index 00000000000..4e227e41fb9 --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/sub_n-combine.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-rtl-combine" } */ + +int a; + +double b1() { + int c = a << 1; + return 1 - c; +} + +double b2() { + int c = a << 2; + return 1 - c; +} + +double b3() { + int c = a << 3; + return 1 - c; +} + +/* { dg-final { scan-rtl-dump-times "\\*sub_n" 3 "combine" } } */