[arm] clean up alu+shift patterns
authorRichard Earnshaw <rearnsha@arm.com>
Mon, 21 Oct 2019 15:52:58 +0000 (15:52 +0000)
committerRichard Earnshaw <rearnsha@gcc.gnu.org>
Mon, 21 Oct 2019 15:52:58 +0000 (15:52 +0000)
My DImode arithmetic patches introduced a bug on thumb2 where we could
generate a register controlled shift into an ALU operation.  In
fairness the bug was always present, but latent.

As part of cleaning this up (and auditing to ensure I've caught them
all this time) I've gone through all the shift generating patterns in
the MD files and cleaned them up, reducing some duplicate patterns
between the arm and thumb2 descriptions where we can now share the
same pattern.  In some cases we were missing the shift attribute; in
most cases I've eliminated an ugly attribute setting using the fact
that we normally need separate alternatives for shift immediate and
shift reg to simplify the logic.

* config/arm/iterators.md (t2_binop0): Fix typo in comment.
* config/arm/arm.md (addsi3_carryin_shift): Simplify selection of the
type attribute.
(subsi3_carryin_shift): Separate into register and constant controlled
alternatives.  Use shift_amount_operand for operand 4.  Set shift
attribute and simplify type attribute.
(subsi3_carryin_shift_alt): Likewise.
(rsbsi3_carryin_shift): Likewise.
(rsbsi3_carryin_shift_alt): Likewise.
(andsi_not_shiftsi_si): Enable for TARGET_32BIT.  Separate constant
and register controlled shifts into distinct alternatives.
(andsi_not_shiftsi_si_scc_no_reuse): Likewise.
(andsi_not_shiftsi_si_scc): Likewise.
(arm_cmpsi_negshiftsi_si): Likewise.
(not_shiftsi): Remove redundant M constraint from alternative 1.
(not_shiftsi_compare0): Likewise.
(arm_cmpsi_insn): Remove redundant alternative 2.
(cmpsi_shift_swp): Likewise.
(sub_shiftsi): Likewise.
(sub_shiftsi_compare0_scratch): Likewise.
* config/arm/thumb2.md (thumb_andsi_not_shiftsi_si): Delete pattern.
(thumb2_cmpsi_neg_shiftsi): Likewise.

From-SVN: r277262

gcc/ChangeLog
gcc/config/arm/arm.md
gcc/config/arm/iterators.md
gcc/config/arm/thumb2.md

index 8c20cb8c33cf1e3ca30e2434fb8849bc0fc04fa5..50121777940e620e50274f707c3702da7d793f9a 100644 (file)
@@ -1,3 +1,28 @@
+2019-10-21  Richard Earnshaw  <rearnsha@arm.com>
+
+       * config/arm/iterators.md (t2_binop0): Fix typo in comment.
+       * config/arm/arm.md (addsi3_carryin_shift): Simplify selection of the
+       type attribute.
+       (subsi3_carryin_shift): Separate into register and constant controlled
+       alternatives.  Use shift_amount_operand for operand 4.  Set shift
+       attribute and simplify type attribute.
+       (subsi3_carryin_shift_alt): Likewise.
+       (rsbsi3_carryin_shift): Likewise.
+       (rsbsi3_carryin_shift_alt): Likewise.
+       (andsi_not_shiftsi_si): Enable for TARGET_32BIT.  Separate constant
+       and register controlled shifts into distinct alternatives.
+       (andsi_not_shiftsi_si_scc_no_reuse): Likewise.
+       (andsi_not_shiftsi_si_scc): Likewise.
+       (arm_cmpsi_negshiftsi_si): Likewise.
+       (not_shiftsi): Remove redundant M constraint from alternative 1.
+       (not_shiftsi_compare0): Likewise.
+       (arm_cmpsi_insn): Remove redundant alternative 2.
+       (cmpsi_shift_swp): Likewise.
+       (sub_shiftsi): Likewise.
+       (sub_shiftsi_compare0_scratch): Likewise.
+       * config/arm/thumb2.md (thumb_andsi_not_shiftsi_si): Delete pattern.
+       (thumb2_cmpsi_neg_shiftsi): Likewise.
+
 2019-10-21  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/92162
index 7ef0c16580d406492e35f6daf85a93c2fe35dd5d..039fdd02479abfc4ad36bf35ce55172cdcfb9c1b 100644 (file)
    (set_attr "arch" "32,a")
    (set_attr "shift" "3")
    (set_attr "predicable" "yes")
-   (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
-                     (const_string "alu_shift_imm")
-                     (const_string "alu_shift_reg")))]
+   (set_attr "type" "alu_shift_imm,alu_shift_reg")]
 )
 
 (define_insn "*addsi3_carryin_clobercc"
 )
 
 (define_insn "*subsi3_carryin_shift"
-  [(set (match_operand:SI 0 "s_register_operand" "=r")
+  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
        (minus:SI (minus:SI
-                  (match_operand:SI 1 "s_register_operand" "r")
+                  (match_operand:SI 1 "s_register_operand" "r,r")
                   (match_operator:SI 2 "shift_operator"
-                   [(match_operand:SI 3 "s_register_operand" "r")
-                    (match_operand:SI 4 "reg_or_int_operand" "rM")]))
+                   [(match_operand:SI 3 "s_register_operand" "r,r")
+                    (match_operand:SI 4 "shift_amount_operand" "M,r")]))
                  (match_operand:SI 5 "arm_borrow_operation" "")))]
   "TARGET_32BIT"
   "sbc%?\\t%0, %1, %3%S2"
   [(set_attr "conds" "use")
+   (set_attr "arch" "32,a")
+   (set_attr "shift" "3")
    (set_attr "predicable" "yes")
-   (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
-                                   (const_string "alu_shift_imm")
-                                   (const_string "alu_shift_reg")))]
+   (set_attr "type" "alu_shift_imm,alu_shift_reg")]
 )
 
 (define_insn "*subsi3_carryin_shift_alt"
-  [(set (match_operand:SI 0 "s_register_operand" "=r")
+  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
        (minus:SI (minus:SI
-                  (match_operand:SI 1 "s_register_operand" "r")
+                  (match_operand:SI 1 "s_register_operand" "r,r")
                   (match_operand:SI 5 "arm_borrow_operation" ""))
                  (match_operator:SI 2 "shift_operator"
-                  [(match_operand:SI 3 "s_register_operand" "r")
-                   (match_operand:SI 4 "reg_or_int_operand" "rM")])))]
+                  [(match_operand:SI 3 "s_register_operand" "r,r")
+                   (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
   "TARGET_32BIT"
   "sbc%?\\t%0, %1, %3%S2"
   [(set_attr "conds" "use")
+   (set_attr "arch" "32,a")
+   (set_attr "shift" "3")
    (set_attr "predicable" "yes")
-   (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
-                                   (const_string "alu_shift_imm")
-                                   (const_string "alu_shift_reg")))]
+   (set_attr "type" "alu_shift_imm,alu_shift_reg")]
 )
 
+;; No RSC in Thumb2
 (define_insn "*rsbsi3_carryin_shift"
-  [(set (match_operand:SI 0 "s_register_operand" "=r")
+  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
        (minus:SI (minus:SI
                   (match_operator:SI 2 "shift_operator"
-                   [(match_operand:SI 3 "s_register_operand" "r")
-                    (match_operand:SI 4 "reg_or_int_operand" "rM")])
-                  (match_operand:SI 1 "s_register_operand" "r"))
+                   [(match_operand:SI 3 "s_register_operand" "r,r")
+                    (match_operand:SI 4 "shift_amount_operand" "M,r")])
+                  (match_operand:SI 1 "s_register_operand" "r,r"))
                  (match_operand:SI 5 "arm_borrow_operation" "")))]
   "TARGET_ARM"
   "rsc%?\\t%0, %1, %3%S2"
   [(set_attr "conds" "use")
    (set_attr "predicable" "yes")
-   (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
-                     (const_string "alu_shift_imm")
-                     (const_string "alu_shift_reg")))]
+   (set_attr "type" "alu_shift_imm,alu_shift_reg")]
 )
 
 (define_insn "*rsbsi3_carryin_shift_alt"
-  [(set (match_operand:SI 0 "s_register_operand" "=r")
+  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
        (minus:SI (minus:SI
                   (match_operator:SI 2 "shift_operator"
-                   [(match_operand:SI 3 "s_register_operand" "r")
-                    (match_operand:SI 4 "reg_or_int_operand" "rM")])
+                   [(match_operand:SI 3 "s_register_operand" "r,r")
+                    (match_operand:SI 4 "shift_amount_operand" "M,r")])
                    (match_operand:SI 5 "arm_borrow_operation" ""))
-                 (match_operand:SI 1 "s_register_operand" "r")))]
+                 (match_operand:SI 1 "s_register_operand" "r,r")))]
   "TARGET_ARM"
   "rsc%?\\t%0, %1, %3%S2"
   [(set_attr "conds" "use")
    (set_attr "predicable" "yes")
-   (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
-                     (const_string "alu_shift_imm")
-                     (const_string "alu_shift_reg")))]
+   (set_attr "type" "alu_shift_imm,alu_shift_reg")]
 )
 
 ; transform ((x << y) - 1) to ~(~(x-1) << y)  Where X is a constant.
 )
 
 (define_insn "andsi_not_shiftsi_si"
-  [(set (match_operand:SI 0 "s_register_operand" "=r")
+  [(set (match_operand:SI 0 "s_register_operand" "=r,r")
        (and:SI (not:SI (match_operator:SI 4 "shift_operator"
-                        [(match_operand:SI 2 "s_register_operand" "r")
-                         (match_operand:SI 3 "arm_rhs_operand" "rM")]))
-               (match_operand:SI 1 "s_register_operand" "r")))]
-  "TARGET_ARM"
+                        [(match_operand:SI 2 "s_register_operand" "r,r")
+                         (match_operand:SI 3 "shift_amount_operand" "M,r")]))
+               (match_operand:SI 1 "s_register_operand" "r,r")))]
+  "TARGET_32BIT"
   "bic%?\\t%0, %1, %2%S4"
   [(set_attr "predicable" "yes")
    (set_attr "shift" "2")
-   (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
-                     (const_string "logic_shift_imm")
-                     (const_string "logic_shift_reg")))]
+   (set_attr "arch" "32,a")
+   (set_attr "type" "logic_shift_imm,logic_shift_reg")]
 )
 
 ;; Shifted bics pattern used to set up CC status register and not reusing
   [(set (reg:CC_NOOV CC_REGNUM)
        (compare:CC_NOOV
                (and:SI (not:SI (match_operator:SI 0 "shift_operator"
-                       [(match_operand:SI 1 "s_register_operand" "r")
-                        (match_operand:SI 2 "arm_rhs_operand" "rM")]))
-                       (match_operand:SI 3 "s_register_operand" "r"))
+                       [(match_operand:SI 1 "s_register_operand" "r,r")
+                        (match_operand:SI 2 "shift_amount_operand" "M,r")]))
+                       (match_operand:SI 3 "s_register_operand" "r,r"))
                (const_int 0)))
-   (clobber (match_scratch:SI 4 "=r"))]
-  "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
+   (clobber (match_scratch:SI 4 "=r,r"))]
+  "TARGET_32BIT"
   "bics%?\\t%4, %3, %1%S0"
   [(set_attr "predicable" "yes")
+   (set_attr "arch" "32,a")
    (set_attr "conds" "set")
    (set_attr "shift" "1")
-   (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
-                     (const_string "logic_shift_imm")
-                     (const_string "logic_shift_reg")))]
+   (set_attr "type" "logic_shift_imm,logic_shift_reg")]
 )
 
 ;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
   [(parallel [(set (reg:CC_NOOV CC_REGNUM)
        (compare:CC_NOOV
                (and:SI (not:SI (match_operator:SI 0 "shift_operator"
-                       [(match_operand:SI 1 "s_register_operand" "r")
-                        (match_operand:SI 2 "arm_rhs_operand" "rM")]))
-                       (match_operand:SI 3 "s_register_operand" "r"))
+                       [(match_operand:SI 1 "s_register_operand" "r,r")
+                        (match_operand:SI 2 "shift_amount_operand" "M,r")]))
+                       (match_operand:SI 3 "s_register_operand" "r,r"))
                (const_int 0)))
-       (set (match_operand:SI 4 "s_register_operand" "=r")
+       (set (match_operand:SI 4 "s_register_operand" "=r,r")
             (and:SI (not:SI (match_op_dup 0
                     [(match_dup 1)
                      (match_dup 2)]))
                     (match_dup 3)))])]
-  "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
+  "TARGET_32BIT"
   "bics%?\\t%4, %3, %1%S0"
   [(set_attr "predicable" "yes")
+   (set_attr "arch" "32,a")
    (set_attr "conds" "set")
    (set_attr "shift" "1")
-   (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
-                     (const_string "logic_shift_imm")
-                     (const_string "logic_shift_reg")))]
+   (set_attr "type" "logic_shift_imm,logic_shift_reg")]
 )
 
 (define_insn "*andsi_notsi_si_compare0"
   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
        (not:SI (match_operator:SI 3 "shift_operator"
                 [(match_operand:SI 1 "s_register_operand" "r,r")
-                 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
+                 (match_operand:SI 2 "shift_amount_operand" "M,r")])))]
   "TARGET_32BIT"
   "mvn%?\\t%0, %1%S3"
   [(set_attr "predicable" "yes")
        (compare:CC_NOOV
         (not:SI (match_operator:SI 3 "shift_operator"
                  [(match_operand:SI 1 "s_register_operand" "r,r")
-                  (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
+                  (match_operand:SI 2 "shift_amount_operand" "M,r")]))
         (const_int 0)))
    (set (match_operand:SI 0 "s_register_operand" "=r,r")
        (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
        (compare:CC_NOOV
         (not:SI (match_operator:SI 3 "shift_operator"
                  [(match_operand:SI 1 "s_register_operand" "r,r")
-                  (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
+                  (match_operand:SI 2 "shift_amount_operand" "M,r")]))
         (const_int 0)))
    (clobber (match_scratch:SI 0 "=r,r"))]
   "TARGET_32BIT"
 
 (define_insn "*cmpsi_shiftsi"
   [(set (reg:CC CC_REGNUM)
-       (compare:CC (match_operand:SI   0 "s_register_operand" "r,r,r")
+       (compare:CC (match_operand:SI   0 "s_register_operand" "r,r")
                    (match_operator:SI  3 "shift_operator"
-                    [(match_operand:SI 1 "s_register_operand" "r,r,r")
-                     (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
+                    [(match_operand:SI 1 "s_register_operand" "r,r")
+                     (match_operand:SI 2 "shift_amount_operand" "M,r")])))]
   "TARGET_32BIT"
   "cmp\\t%0, %1%S3"
   [(set_attr "conds" "set")
    (set_attr "shift" "1")
-   (set_attr "arch" "32,a,a")
-   (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
+   (set_attr "arch" "32,a")
+   (set_attr "type" "alus_shift_imm,alus_shift_reg")])
 
 (define_insn "*cmpsi_shiftsi_swp"
   [(set (reg:CC_SWP CC_REGNUM)
        (compare:CC_SWP (match_operator:SI 3 "shift_operator"
-                        [(match_operand:SI 1 "s_register_operand" "r,r,r")
-                         (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
-                       (match_operand:SI 0 "s_register_operand" "r,r,r")))]
+                        [(match_operand:SI 1 "s_register_operand" "r,r")
+                         (match_operand:SI 2 "shift_amount_operand" "M,r")])
+                       (match_operand:SI 0 "s_register_operand" "r,r")))]
   "TARGET_32BIT"
   "cmp%?\\t%0, %1%S3"
   [(set_attr "conds" "set")
    (set_attr "shift" "1")
-   (set_attr "arch" "32,a,a")
-   (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
+   (set_attr "arch" "32,a")
+   (set_attr "type" "alus_shift_imm,alus_shift_reg")])
 
 (define_insn "*arm_cmpsi_negshiftsi_si"
   [(set (reg:CC_Z CC_REGNUM)
        (compare:CC_Z
         (neg:SI (match_operator:SI 1 "shift_operator"
-                   [(match_operand:SI 2 "s_register_operand" "r")
-                    (match_operand:SI 3 "reg_or_int_operand" "rM")]))
-        (match_operand:SI 0 "s_register_operand" "r")))]
-  "TARGET_ARM"
+                   [(match_operand:SI 2 "s_register_operand" "r,r")
+                    (match_operand:SI 3 "shift_amount_operand" "M,r")]))
+        (match_operand:SI 0 "s_register_operand" "r,r")))]
+  "TARGET_32BIT"
   "cmn%?\\t%0, %2%S1"
   [(set_attr "conds" "set")
-   (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
-                                   (const_string "alus_shift_imm")
-                                   (const_string "alus_shift_reg")))
+   (set_attr "arch" "32,a")
+   (set_attr "shift" "2")
+   (set_attr "type" "alus_shift_imm,alus_shift_reg")
    (set_attr "predicable" "yes")]
 )
 
 (define_insn "*sub_shiftsi_compare0"
   [(set (reg:CC_NOOV CC_REGNUM)
        (compare:CC_NOOV
-        (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
+        (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
                   (match_operator:SI 2 "shift_operator"
-                   [(match_operand:SI 3 "s_register_operand" "r,r,r")
-                    (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
+                   [(match_operand:SI 3 "s_register_operand" "r,r")
+                    (match_operand:SI 4 "shift_amount_operand" "M,r")]))
         (const_int 0)))
-   (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
+   (set (match_operand:SI 0 "s_register_operand" "=r,r")
        (minus:SI (match_dup 1)
                  (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
   "TARGET_32BIT"
   "subs%?\\t%0, %1, %3%S2"
   [(set_attr "conds" "set")
    (set_attr "shift" "3")
-   (set_attr "arch" "32,a,a")
-   (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
+   (set_attr "arch" "32,a")
+   (set_attr "type" "alus_shift_imm,alus_shift_reg")])
 
 (define_insn "*sub_shiftsi_compare0_scratch"
   [(set (reg:CC_NOOV CC_REGNUM)
        (compare:CC_NOOV
-        (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
+        (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
                   (match_operator:SI 2 "shift_operator"
-                   [(match_operand:SI 3 "s_register_operand" "r,r,r")
-                    (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
+                   [(match_operand:SI 3 "s_register_operand" "r,r")
+                    (match_operand:SI 4 "shift_amount_operand" "M,r")]))
         (const_int 0)))
-   (clobber (match_scratch:SI 0 "=r,r,r"))]
+   (clobber (match_scratch:SI 0 "=r,r"))]
   "TARGET_32BIT"
   "subs%?\\t%0, %1, %3%S2"
   [(set_attr "conds" "set")
    (set_attr "shift" "3")
-   (set_attr "arch" "32,a,a")
-   (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
+   (set_attr "arch" "32,a")
+   (set_attr "type" "alus_shift_imm,alus_shift_reg")])
 \f
 
 (define_insn_and_split "*and_scc"
index 5f1c833ad80ab6c85006338292f947dc141ed52f..4eb203365a6c10492a948b45db38c244ec191427 100644 (file)
 (define_code_iterator FCVT [unsigned_float float])
 
 ;; plus and minus are the only SHIFTABLE_OPS for which Thumb2 allows
-;; a stack pointer opoerand.  The minus operation is a candidate for an rsub
+;; a stack pointer operand.  The minus operation is a candidate for an rsub
 ;; and hence only plus is supported.
 (define_code_attr t2_binop0
   [(plus "rk") (minus "r") (ior "r") (xor "r") (and "r")])
index 8d0b6be920518e891c1d3a88274b70395a44a124..7fce50b045b40f0d29ba792dce05e43072dad3b0 100644 (file)
 ;; changes made in armv5t as "thumb2".  These are considered part
 ;; the 16-bit Thumb-1 instruction set.
 
-;; Thumb-2 only allows shift by constant on data processing instructions
-(define_insn "*thumb_andsi_not_shiftsi_si"
-  [(set (match_operand:SI 0 "s_register_operand" "=r")
-       (and:SI (not:SI (match_operator:SI 4 "shift_operator"
-                        [(match_operand:SI 2 "s_register_operand" "r")
-                         (match_operand:SI 3 "const_int_operand" "M")]))
-               (match_operand:SI 1 "s_register_operand" "r")))]
-  "TARGET_THUMB2"
-  "bic%?\\t%0, %1, %2%S4"
-  [(set_attr "predicable" "yes")
-   (set_attr "shift" "2")
-   (set_attr "type" "alu_shift_imm")]
-)
-
 ;; We use the '0' constraint for operand 1 because reload should
 ;; be smart enough to generate an appropriate move for the r/r/r case.
 (define_insn_and_split "*thumb2_smaxsi3"
   [(set_attr "type" "store_8")]
 )
 
-(define_insn "*thumb2_cmpsi_neg_shiftsi"
-  [(set (reg:CC CC_REGNUM)
-       (compare:CC (match_operand:SI 0 "s_register_operand" "r")
-                   (neg:SI (match_operator:SI 3 "shift_operator"
-                            [(match_operand:SI 1 "s_register_operand" "r")
-                             (match_operand:SI 2 "const_int_operand" "M")]))))]
-  "TARGET_THUMB2"
-  "cmn%?\\t%0, %1%S3"
-  [(set_attr "conds" "set")
-   (set_attr "shift" "1")
-   (set_attr "type" "alus_shift_imm")]
-)
-
 (define_insn_and_split "*thumb2_mov_scc"
   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
        (match_operator:SI 1 "arm_comparison_operator_mode"