[ARC] Add/update combiner patterns.
authorClaudiu Zissulescu <claziss@synopsys.com>
Mon, 9 Apr 2018 15:05:19 +0000 (17:05 +0200)
committerClaudiu Zissulescu <claziss@gcc.gnu.org>
Mon, 9 Apr 2018 15:05:19 +0000 (17:05 +0200)
gcc/
2018-01-26  Claudiu Zissulescu  <claziss@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.

From-SVN: r259237

gcc/ChangeLog
gcc/config/arc/arc.md
gcc/config/arc/predicates.md

index 6d0a2692beff329a49e6df3a4566bac369a24a98..2328fd781023a0df82b5af31d7dd518a3afa0530 100644 (file)
@@ -1,3 +1,31 @@
+2018-04-09  Claudiu Zissulescu  <claziss@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.
+
 2018-04-09  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/85284
index 2ffd30043743d143c12ed9b0c50c44ce1729ef65..127ed8ebee99920496c385662e86f6cb98a9085a 100644 (file)
   "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")])
 
    (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
    (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")])
  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")]
    (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")
 
index 38651f79bf43d29fd1eb4a5e02f57fa5127fd627..0abfc839b078774372a8090546043577d5d3f49e 100644 (file)
        return FALSE;
     }
 
-  if (REGNO (op) != 61)
+  if (REGNO (op) != CC_REG)
     return FALSE;
   if (mode == rmode
       || (mode == CC_ZNmode && rmode == CC_Zmode)
 )
 
 (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")))
 )