Committed. Thank you for your review, Claudiu
> -----Original Message----- > From: Andrew Burgess [mailto:andrew.burg...@embecosm.com] > Sent: Saturday, April 07, 2018 11:07 AM > To: Claudiu Zissulescu <claz...@gmail.com> > Cc: gcc-patches@gcc.gnu.org; claudiu.zissule...@synopsys.com; > francois.bed...@synopsys.com > Subject: Re: [PATCH] [ARC] Add/update combiner patterns. > > * Claudiu Zissulescu <claz...@gmail.com> [2018-03-07 13:59:03 +0200]: > > > From: claziss <claz...@synopsys.com> > > > > Hi Andrew, > > > > Please find the following patch which improves generating more > instructions with .f flag (i.e., compare with zero). > > > > Ok to apply? > > Looks good. > > Thanks. > Andrew > > > > Claudiu > > > > gcc/ > > 2018-01-26 Claudiu Zissulescu <claz...@synopsys.com> > > > > * config/arc/arc.md (add_shift): New pattern. > > (add_shift2): Likewise. > > (sub_shift): Likewise. > > (sub_shift_cmp0_noout): Likewise. > > (compare_si_ashiftsi): Likewise. > > (xbfu_cmp0_noout): New combine pattern. > > (xbfu_cmp0"): Likewise. > > (movsi_set_cc_insn): Place the predicable variant first. > > (commutative_binary_cmp0_noout): Remove clobber. > > (commutative_binary_cmp0): New pattern. > > (noncommutative_binary_cmp0): Likewise. > > (noncommutative_binary_cmp0_noout): Likewise. > > (noncommutative_binary_comparison_result_used): Removed. > > (rsub_cmp0): New pattern. > > (rsub_cmp0_noout): Likewise. > > (extzvsi): Changed, keep only meaningful variants. > > (SQH, SEZ): New iterators. > > (SQH_postfix): New mode attribute. > > (SEZ_prefix): New code attribute. > > (<SEZ_prefix>xt<SQH_postfix>_cmp0_noout): New instruction > pattern. > > (<SEZ_prefix>xt<SQH_postfix>_cmp0): Likewise. > > * config/arc/predicates.md (cc_set_register): Use CC_REG instead > > of numerical value. > > (noncommutative_operator): Check the availability of barrel > > shifter option. > > --- > > gcc/config/arc/arc.md | 274 > ++++++++++++++++++++++++++++++++++++------- > > gcc/config/arc/predicates.md | 6 +- > > 2 files changed, 233 insertions(+), 47 deletions(-) > > > > diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md > > index 7633d36b5a6..fb3432964ac 100644 > > --- a/gcc/config/arc/arc.md > > +++ b/gcc/config/arc/arc.md > > @@ -810,20 +810,90 @@ archs4x, archs4xd, archs4xd_slow" > > "st%U0 %1,%0\;st%U0.di %1,%0" > > [(set_attr "type" "store")]) > > > > +;; Combiner patterns for compare with zero > > +(define_mode_iterator SQH [QI HI]) > > +(define_mode_attr SQH_postfix [(QI "b") (HI "%_")]) > > + > > +(define_code_iterator SEZ [sign_extend zero_extend]) > > +(define_code_attr SEZ_prefix [(sign_extend "sex") (zero_extend "ext")]) > > + > > +(define_insn "*<SEZ_prefix>xt<SQH_postfix>_cmp0_noout" > > + [(set (match_operand 0 "cc_set_register" "") > > + (compare:CC_ZN (SEZ:SI (match_operand:SQH 1 "register_operand" > "r")) > > + (const_int 0)))] > > + "" > > + "<SEZ_prefix><SQH_postfix>.f\\t0,%1" > > + [(set_attr "type" "compare") > > + (set_attr "cond" "set_zn")]) > > + > > +(define_insn "*<SEZ_prefix>xt<SQH_postfix>_cmp0" > > + [(set (match_operand 0 "cc_set_register" "") > > + (compare:CC_ZN (SEZ:SI (match_operand:SQH 1 "register_operand" > "r")) > > + (const_int 0))) > > + (set (match_operand:SI 2 "register_operand" "=r") > > + (SEZ:SI (match_dup 1)))] > > + "" > > + "<SEZ_prefix><SQH_postfix>.f\\t%2,%1" > > + [(set_attr "type" "compare") > > + (set_attr "cond" "set_zn")]) > > + > > +(define_insn "*xbfu_cmp0_noout" > > + [(set (match_operand 0 "cc_set_register" "") > > + (compare:CC_Z > > + (zero_extract:SI > > + (match_operand:SI 1 "register_operand" " r,r") > > + (match_operand:SI 2 "const_int_operand" "C3p,n") > > + (match_operand:SI 3 "const_int_operand" " n,n")) > > + (const_int 0)))] > > + "TARGET_HS && TARGET_BARREL_SHIFTER" > > + { > > + int assemble_op2 = (((INTVAL (operands[2]) - 1) & 0x1f) << 5) | (INTVAL > (operands[3]) & 0x1f); > > + operands[2] = GEN_INT (assemble_op2); > > + return "xbfu%?.f\\t0,%1,%2"; > > + } > > + [(set_attr "type" "shift") > > + (set_attr "iscompact" "false") > > + (set_attr "length" "4,8") > > + (set_attr "predicable" "no") > > + (set_attr "cond" "set_zn")]) > > + > > +(define_insn "*xbfu_cmp0" > > + [(set (match_operand 4 "cc_set_register" "") > > + (compare:CC_Z > > + (zero_extract:SI > > + (match_operand:SI 1 "register_operand" "0 ,r,0") > > + (match_operand:SI 2 "const_int_operand" "C3p,n,n") > > + (match_operand:SI 3 "const_int_operand" "n ,n,n")) > > + (const_int 0))) > > + (set (match_operand:SI 0 "register_operand" "=r,r,r") > > + (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))] > > + "TARGET_HS && TARGET_BARREL_SHIFTER" > > + { > > + int assemble_op2 = (((INTVAL (operands[2]) - 1) & 0x1f) << 5) | (INTVAL > (operands[3]) & 0x1f); > > + operands[2] = GEN_INT (assemble_op2); > > + return "xbfu%?.f\\t%0,%1,%2"; > > + } > > + [(set_attr "type" "shift") > > + (set_attr "iscompact" "false") > > + (set_attr "length" "4,8,8") > > + (set_attr "predicable" "yes,no,yes") > > + (set_attr "cond" "set_zn")]) > > + > > +; splitting to 'tst' allows short insns and combination into brcc. > > (define_insn_and_split "*movsi_set_cc_insn" > > - [(set (match_operand:CC_ZN 2 "cc_set_register" "") > > - (match_operator:CC_ZN 3 "zn_compare_operator" > > - [(match_operand:SI 1 "nonmemory_operand" "cI,cL,Cal") > (const_int 0)])) > > - (set (match_operand:SI 0 "register_operand" "=w,w,w") > > + [(set (match_operand 2 "cc_set_register" "") > > + (match_operator 3 "zn_compare_operator" > > + [(match_operand:SI 1 "nonmemory_operand" > "rL,rI,Cal") > > + (const_int 0)])) > > + (set (match_operand:SI 0 "register_operand" "=r,r,r") > > (match_dup 1))] > > "" > > - "mov%?.f %0,%1" > > - ; splitting to 'tst' allows short insns and combination into brcc. > > + "mov%?.f\\t%0,%1" > > "reload_completed && operands_match_p (operands[0], operands[1])" > > [(set (match_dup 2) (match_dup 3))] > > "" > > [(set_attr "type" "compare") > > - (set_attr "predicable" "no,yes,yes") > > + (set_attr "predicable" "yes,no,yes") > > (set_attr "cond" "set_zn") > > (set_attr "length" "4,4,8")]) > > > > @@ -973,19 +1043,35 @@ archs4x, archs4xd, archs4xd_slow" > > (set_attr "cond" "set_zn") > > (set_attr "length" "*,4,4,4,8")]) > > > > -(define_insn "*commutative_binary_comparison" > > - [(set (match_operand:CC_ZN 0 "cc_set_register" "") > > - (match_operator:CC_ZN 5 "zn_compare_operator" > > +;; The next two patterns are for plos, ior, xor, and, and mult. > > +(define_insn "*commutative_binary_cmp0_noout" > > + [(set (match_operand 0 "cc_set_register" "") > > + (match_operator 4 "zn_compare_operator" > > + [(match_operator:SI 3 "commutative_operator" > > + [(match_operand:SI 1 "register_operand" "%r,r") > > + (match_operand:SI 2 "nonmemory_operand" "rL,Cal")]) > > + (const_int 0)]))] > > + "" > > + "%O3.f\\t0,%1,%2" > > + [(set_attr "type" "compare") > > + (set_attr "cond" "set_zn") > > + (set_attr "length" "4,8")]) > > + > > +(define_insn "*commutative_binary_cmp0" > > + [(set (match_operand 3 "cc_set_register" "") > > + (match_operator 5 "zn_compare_operator" > > [(match_operator:SI 4 "commutative_operator" > > - [(match_operand:SI 1 "register_operand" "%c,c") > > - (match_operand:SI 2 "nonmemory_operand" "cL,Cal")]) > > + [(match_operand:SI 1 "register_operand" "%0, 0,r,r") > > + (match_operand:SI 2 "nonmemory_operand" "rL,rI,r,Cal")]) > > (const_int 0)])) > > - (clobber (match_scratch:SI 3 "=X,X"))] > > + (set (match_operand:SI 0 "register_operand" "=r,r,r,r") > > + (match_dup 4))] > > "" > > - "%O4.f 0,%1,%2" > > + "%O4.f\\t%0,%1,%2" > > [(set_attr "type" "compare") > > (set_attr "cond" "set_zn") > > - (set_attr "length" "4,8")]) > > + (set_attr "predicable" "yes,yes,no,no") > > + (set_attr "length" "4,4,4,8")]) > > > > ; for flag setting 'add' instructions like if (a+b) { ...} > > ; the combiner needs this pattern > > @@ -1059,32 +1145,60 @@ archs4x, archs4xd, archs4xd_slow" > > (set_attr "cond" "set_zn,set_zn,set_zn") > > (set_attr "length" "4,4,8")]) > > > > -; this pattern is needed by combiner for cases like if (c=a<<b) { ... } > > -(define_insn "*noncommutative_binary_comparison_result_used" > > - [(set (match_operand 3 "cc_register" "") > > +(define_insn "*noncommutative_binary_cmp0" > > + [(set (match_operand 3 "cc_set_register" "") > > (match_operator 5 "zn_compare_operator" > > [(match_operator:SI 4 "noncommutative_operator" > > - [(match_operand:SI 1 "register_operand" "c,0,c") > > - (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")]) > > - (const_int 0)])) > > - (set (match_operand:SI 0 "register_operand" "=w,w,w") > > - (match_dup 4 ))] > > - "TARGET_BARREL_SHIFTER || GET_CODE (operands[4]) == MINUS" > > - "%O4.f %0,%1,%2" > > - [(set_attr "type" "compare,compare,compare") > > - (set_attr "cond" "set_zn,set_zn,set_zn") > > - (set_attr "length" "4,4,8")]) > > + [(match_operand:SI 1 "register_operand" "0,r,0, 0,r") > > + (match_operand:SI 2 "nonmemory_operand" "rL,r,I,Cal,Cal")]) > > + (const_int 0)])) > > + (set (match_operand:SI 0 "register_operand" "=r,r,r,r,r") > > + (match_dup 4))] > > + "" > > + "%O4%?.f\\t%0,%1,%2" > > + [(set_attr "type" "compare") > > + (set_attr "cond" "set_zn") > > + (set_attr "predicable" "yes,no,no,yes,no") > > + (set_attr "length" "4,4,4,8,8")]) > > > > -(define_insn "*noncommutative_binary_comparison" > > - [(set (match_operand:CC_ZN 0 "cc_set_register" "") > > - (match_operator:CC_ZN 5 "zn_compare_operator" > > +(define_insn "*noncommutative_binary_cmp0_noout" > > + [(set (match_operand 0 "cc_set_register" "") > > + (match_operator 3 "zn_compare_operator" > > [(match_operator:SI 4 "noncommutative_operator" > > - [(match_operand:SI 1 "register_operand" "c,c") > > - (match_operand:SI 2 "nonmemory_operand" "cL,Cal")]) > > + [(match_operand:SI 1 "register_operand" "r,r") > > + (match_operand:SI 2 "nonmemory_operand" "rL,Cal")]) > > + (const_int 0)]))] > > + "" > > + "%O4.f\\t0,%1,%2" > > + [(set_attr "type" "compare") > > + (set_attr "cond" "set_zn") > > + (set_attr "length" "4,8")]) > > + > > +;;rsub variants > > +(define_insn "*rsub_cmp0" > > + [(set (match_operand 4 "cc_set_register" "") > > + (match_operator 3 "zn_compare_operator" > > + [(minus:SI > > + (match_operand:SI 1 "nonmemory_operand" "rL,Cal") > > + (match_operand:SI 2 "register_operand" "r,r")) > > (const_int 0)])) > > - (clobber (match_scratch:SI 3 "=X,X"))] > > - "TARGET_BARREL_SHIFTER || GET_CODE (operands[4]) == MINUS" > > - "%O4.f 0,%1,%2" > > + (set (match_operand:SI 0 "register_operand" "=r,r") > > + (minus:SI (match_dup 1) (match_dup 2)))] > > + "" > > + "rsub.f\\t%0,%2,%1" > > + [(set_attr "type" "compare") > > + (set_attr "cond" "set_zn") > > + (set_attr "length" "4,8")]) > > + > > +(define_insn "*rsub_cmp0_noout" > > + [(set (match_operand 0 "cc_set_register" "") > > + (match_operator 3 "zn_compare_operator" > > + [(minus:SI > > + (match_operand:SI 1 "nonmemory_operand" "rL,Cal") > > + (match_operand:SI 2 "register_operand" "r,r")) > > + (const_int 0)]))] > > + "" > > + "rsub.f\\t0,%2,%1" > > [(set_attr "type" "compare") > > (set_attr "cond" "set_zn") > > (set_attr "length" "4,8")]) > > @@ -5624,23 +5738,22 @@ archs4x, archs4xd, archs4xd_slow" > > DONE; > > }) > > > > - > > (define_insn "extzvsi" > > - [(set (match_operand:SI 0 "register_operand" "=r , r > > , r, r, r") > > - (zero_extract:SI (match_operand:SI 1 "register_operand" "0 , r , 0, > 0, r") > > - (match_operand:SI 2 "const_int_operand" "C3p, > C3p, i, i, i") > > - (match_operand:SI 3 "const_int_operand" "i , i , i, > > i, > i")))] > > + [(set (match_operand:SI 0 "register_operand" "=r , > > r,r,r") > > + (zero_extract:SI (match_operand:SI 1 "register_operand" "0 , r,r,0") > > + (match_operand:SI 2 "const_int_operand" > "C3p,C3p,n,n") > > + (match_operand:SI 3 "const_int_operand" "n , > n,n,n")))] > > "TARGET_HS && TARGET_BARREL_SHIFTER" > > { > > int assemble_op2 = (((INTVAL (operands[2]) - 1) & 0x1f) << 5) | (INTVAL > (operands[3]) & 0x1f); > > operands[2] = GEN_INT (assemble_op2); > > - return "xbfu%? %0,%1,%2"; > > + return "xbfu%?\\t%0,%1,%2"; > > } > > [(set_attr "type" "shift") > > (set_attr "iscompact" "false") > > - (set_attr "length" "4,4,4,8,8") > > - (set_attr "predicable" "yes,no,no,yes,no") > > - (set_attr "cond" "canuse,nocond,nocond,canuse,nocond")]) > > + (set_attr "length" "4,4,8,8") > > + (set_attr "predicable" "yes,no,no,yes") > > + (set_attr "cond" "canuse,nocond,nocond,canuse_limm")]) > > > > (define_insn "kflag" > > [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" > "rL,I,Cal")] > > @@ -6439,6 +6552,77 @@ archs4x, archs4xd, archs4xd_slow" > > (set_attr "type" "block")] > > ) > > > > +(define_insn "*add_shift" > > + [(set (match_operand:SI 0 "register_operand" "=q,r,r") > > + (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "q,r,r") > > + (match_operand:SI 2 "_1_2_3_operand" "")) > > + (match_operand:SI 3 "nonmemory_operand" "0,r,Cal")))] > > + "" > > + "add%2%?\\t%0,%3,%1" > > + [(set_attr "length" "*,4,8") > > + (set_attr "predicable" "yes,no,no") > > + (set_attr "iscompact" "maybe,false,false") > > + (set_attr "cond" "canuse,nocond,nocond")]) > > + > > +(define_insn "*add_shift2" > > + [(set (match_operand:SI 0 "register_operand" "=q,r,r") > > + (plus:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal") > > + (ashift:SI (match_operand:SI 2 "register_operand" "q,r,r") > > + (match_operand:SI 3 "_1_2_3_operand" ""))))] > > + "" > > + "add%3%?\\t%0,%1,%2" > > + [(set_attr "length" "*,4,8") > > + (set_attr "predicable" "yes,no,no") > > + (set_attr "iscompact" "maybe,false,false") > > + (set_attr "cond" "canuse,nocond,nocond")]) > > + > > +(define_insn "*sub_shift" > > + [(set (match_operand:SI 0"register_operand" "=r,r,r") > > + (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal") > > + (ashift:SI (match_operand:SI 2 "register_operand" "r,r,r") > > + (match_operand:SI 3 "_1_2_3_operand" ""))))] > > + "" > > + "sub%3\\t%0,%1,%2" > > + [(set_attr "length" "4,4,8") > > + (set_attr "cond" "canuse,nocond,nocond") > > + (set_attr "predicable" "yes,no,no")]) > > + > > +(define_insn "*sub_shift_cmp0_noout" > > + [(set (match_operand 0 "cc_set_register" "") > > + (compare:CC > > + (minus:SI (match_operand:SI 1 "register_operand" "r") > > + (ashift:SI (match_operand:SI 2 "register_operand" "r") > > + (match_operand:SI 3 "_1_2_3_operand" ""))) > > + (const_int 0)))] > > + "" > > + "sub%3.f\\t0,%1,%2" > > + [(set_attr "length" "4")]) > > + > > +(define_insn "*compare_si_ashiftsi" > > + [(set (match_operand 0 "cc_set_register" "") > > + (compare:CC (match_operand:SI 1 "register_operand" "r") > > + (ashift:SI (match_operand:SI 2 "register_operand" "r") > > + (match_operand:SI 3 "_1_2_3_operand" ""))))] > > + "" > > + "sub%3.f\\t0,%1,%2" > > + [(set_attr "length" "4")]) > > + > > +;; Convert the sequence > > +;; asl rd,rn,_1_2_3 > > +;; cmp ra,rd > > +;; into > > +;; sub{123}.f 0,ra,rn > > +(define_peephole2 > > + [(set (match_operand:SI 0 "register_operand" "") > > + (ashift:SI (match_operand:SI 1 "register_operand" "") > > + (match_operand:SI 2 "_1_2_3_operand" ""))) > > + (set (reg:CC CC_REG) > > + (compare:CC (match_operand:SI 3 "register_operand" "") > > + (match_dup 0)))] > > + "peep2_reg_dead_p (2, operands[0])" > > + [(set (reg:CC CC_REG) (compare:CC (match_dup 3) > > + (ashift:SI (match_dup 1) (match_dup 2))))]) > > + > > ;; include the arc-FPX instructions > > (include "fpx.md") > > > > diff --git a/gcc/config/arc/predicates.md b/gcc/config/arc/predicates.md > > index 38651f79bf4..0abfc839b07 100644 > > --- a/gcc/config/arc/predicates.md > > +++ b/gcc/config/arc/predicates.md > > @@ -522,7 +522,7 @@ > > return FALSE; > > } > > > > - if (REGNO (op) != 61) > > + if (REGNO (op) != CC_REG) > > return FALSE; > > if (mode == rmode > > || (mode == CC_ZNmode && rmode == CC_Zmode) > > @@ -609,7 +609,9 @@ > > ) > > > > (define_predicate "noncommutative_operator" > > - (ior (match_code "minus,ashift,ashiftrt,lshiftrt,rotatert") > > + (ior (and (match_code "ashift,ashiftrt,lshiftrt,rotatert") > > + (match_test "TARGET_BARREL_SHIFTER")) > > + (match_code "minus") > > (and (match_code "ss_minus") > > (match_test "TARGET_ARC700 || TARGET_EA_SET"))) > > ) > > -- > > 2.14.3 > >