Disallow 'B' constraints on amdgcn addc/subb
authorAndrew Stubbs <ams@codesourcery.com>
Tue, 7 Jan 2020 14:35:21 +0000 (14:35 +0000)
committerAndrew Stubbs <ams@gcc.gnu.org>
Tue, 7 Jan 2020 14:35:21 +0000 (14:35 +0000)
2020-01-07  Andrew Stubbs  <ams@codesourcery.com>

gcc/
* config/gcn/constraints.md (DA): Update description and match.
(DB): Likewise.
(Db): New constraint.
* config/gcn/gcn-protos.h (gcn_inline_constant64_p): Add second
parameter.
* config/gcn/gcn.c (gcn_inline_constant64_p): Add 'mixed' parameter.
Implement 'Db' mixed immediate type.
* config/gcn/gcn-valu.md (addcv64si3<exec_vcc>): Rework constraints.
(addcv64si3_dup<exec_vcc>): Delete.
(subcv64si3<exec_vcc>): Rework constraints.
(addv64di3): Rework constraints.
(addv64di3_exec): Rework constraints.
(subv64di3): Rework constraints.
(addv64di3_dup): Delete.
(addv64di3_dup_exec): Delete.
(addv64di3_zext): Rework constraints.
(addv64di3_zext_exec): Rework constraints.
(addv64di3_zext_dup): Rework constraints.
(addv64di3_zext_dup_exec): Rework constraints.
(addv64di3_zext_dup2): Rework constraints.
(addv64di3_zext_dup2_exec): Rework constraints.
(addv64di3_sext_dup2): Rework constraints.
(addv64di3_sext_dup2_exec): Rework constraints.

From-SVN: r279959

gcc/ChangeLog
gcc/config/gcn/constraints.md
gcc/config/gcn/gcn-protos.h
gcc/config/gcn/gcn-valu.md
gcc/config/gcn/gcn.c

index 3609886..56d45ab 100644 (file)
@@ -1,3 +1,29 @@
+2020-01-07  Andrew Stubbs  <ams@codesourcery.com>
+
+       * config/gcn/constraints.md (DA): Update description and match.
+       (DB): Likewise.
+       (Db): New constraint.
+       * config/gcn/gcn-protos.h (gcn_inline_constant64_p): Add second
+       parameter.
+       * config/gcn/gcn.c (gcn_inline_constant64_p): Add 'mixed' parameter.
+       Implement 'Db' mixed immediate type.
+       * config/gcn/gcn-valu.md (addcv64si3<exec_vcc>): Rework constraints.
+       (addcv64si3_dup<exec_vcc>): Delete.
+       (subcv64si3<exec_vcc>): Rework constraints.
+       (addv64di3): Rework constraints.
+       (addv64di3_exec): Rework constraints.
+       (subv64di3): Rework constraints.
+       (addv64di3_dup): Delete.
+       (addv64di3_dup_exec): Delete.
+       (addv64di3_zext): Rework constraints.
+       (addv64di3_zext_exec): Rework constraints.
+       (addv64di3_zext_dup): Rework constraints.
+       (addv64di3_zext_dup_exec): Rework constraints.
+       (addv64di3_zext_dup2): Rework constraints.
+       (addv64di3_zext_dup2_exec): Rework constraints.
+       (addv64di3_sext_dup2): Rework constraints.
+       (addv64di3_sext_dup2_exec): Rework constraints.
+
 2020-01-07  Andre Vieira  <andre.simoesdiasvieira@arm.com>
 
        * doc/sourcebuild.texi (arm_little_endian, arm_nothumb): Documented
index f2de943..dd6615b 100644 (file)
        (match_test "gcn_constant64_p (op)")))
 
 (define_constraint "DA"
-  "Splittable inline immediate 64-bit parameter"
+  "Immediate 64-bit parameter, low and high part match 'A'"
   (and (match_code "const_int,const_double,const_vector")
-       (match_test "gcn_inline_constant64_p (op)")))
+       (match_test "gcn_inline_constant64_p (op, 0)")))
+
+(define_constraint "Db"
+  "Immediate 64-bit parameter, low part matches 'B', high part matches 'A'"
+  (and (match_code "const_int,const_double,const_vector")
+       (match_test "gcn_inline_constant64_p (op, 1)")))
 
 (define_constraint "DB"
-  "Splittable immediate 64-bit parameter"
+  "Immediate 64-bit parameter, low and high part match 'B'"
   (match_code "const_int,const_double,const_vector"))
 
 (define_constraint "U"
index 92a6aa7..e4dadd3 100644 (file)
@@ -51,7 +51,7 @@ extern int gcn_hard_regno_nregs (int regno, machine_mode mode);
 extern void gcn_hsa_declare_function_name (FILE *file, const char *name,
                                           tree decl);
 extern HOST_WIDE_INT gcn_initial_elimination_offset (int, int);
-extern bool gcn_inline_constant64_p (rtx);
+extern bool gcn_inline_constant64_p (rtx, bool);
 extern bool gcn_inline_constant_p (rtx);
 extern int gcn_inline_fp_constant_p (rtx, bool);
 extern reg_class gcn_mode_code_base_reg_class (machine_mode, addr_space_t,
index e301a43..7dd7bb9 100644 (file)
   [(set_attr "type" "vop2,vop3b")
    (set_attr "length" "8,8")])
 
-; This pattern does not accept SGPR because VCC read already counts as an
-; SGPR use and number of SGPR operands is limited to 1.
+; v_addc does not accept an SGPR because the VCC read already counts as an
+; SGPR use and the number of SGPR operands is limited to 1.  It does not
+; accept "B" immediate constants due to a related bus conflict.
 
 (define_insn "addcv64si3<exec_vcc>"
-  [(set (match_operand:V64SI 0 "register_operand" "=v,v")
+  [(set (match_operand:V64SI 0 "register_operand"    "=v,   v")
        (plus:V64SI
          (plus:V64SI
            (vec_merge:V64SI
              (vec_duplicate:V64SI (const_int 1))
              (vec_duplicate:V64SI (const_int 0))
-             (match_operand:DI 3 "register_operand" " cV,Sv"))
-           (match_operand:V64SI 1 "gcn_alu_operand" "%vA,vA"))
-         (match_operand:V64SI 2 "gcn_alu_operand"   " vB,vB")))
-   (set (match_operand:DI 4 "register_operand"      "=cV,Sg")
+             (match_operand:DI 3 "register_operand" " cV,cVSv"))
+           (match_operand:V64SI 1 "gcn_alu_operand" "% v,  vA"))
+         (match_operand:V64SI 2 "gcn_alu_operand"   " vA,  vA")))
+   (set (match_operand:DI 4 "register_operand"      "=cV,cVSg")
        (ior:DI (ltu:DI (plus:V64SI
                          (plus:V64SI
                            (vec_merge:V64SI
                          (match_dup 1))
                        (match_dup 1))))]
   ""
-  "v_addc%^_u32\t%0, %4, %1, %2, %3"
-  [(set_attr "type" "vop2,vop3b")
-   (set_attr "length" "4,8")])
-
-(define_insn "addcv64si3_dup<exec_vcc>"
-  [(set (match_operand:V64SI 0 "register_operand" "=v,v")
-       (plus:V64SI
-         (plus:V64SI
-           (vec_merge:V64SI
-             (vec_duplicate:V64SI (const_int 1))
-             (vec_duplicate:V64SI (const_int 0))
-             (match_operand:DI 3 "register_operand" " cV, Sv"))
-           (match_operand:V64SI 1 "gcn_alu_operand" "%vA, vA"))
-         (vec_duplicate:V64SI
-           (match_operand:SI 2 "gcn_alu_operand"    "SvB,SvB"))))
-   (set (match_operand:DI 4 "register_operand"  "=cV, Sg")
-       (ior:DI (ltu:DI (plus:V64SI (plus:V64SI
-                                     (vec_merge:V64SI
-                                       (vec_duplicate:V64SI (const_int 1))
-                                       (vec_duplicate:V64SI (const_int 0))
-                                       (match_dup 3))
-                                     (match_dup 1))
-                                   (vec_duplicate:V64SI
-                                     (match_dup 2)))
-                       (vec_duplicate:V64SI
-                         (match_dup 2)))
-               (ltu:DI (plus:V64SI (vec_merge:V64SI
-                                     (vec_duplicate:V64SI (const_int 1))
-                                     (vec_duplicate:V64SI (const_int 0))
-                                     (match_dup 3))
-                                   (match_dup 1))
-                       (match_dup 1))))]
-  ""
-  "v_addc%^_u32\t%0, %4, %1, %2, %3"
+  "v_addc%^_u32\t%0, %4, %2, %1, %3"
   [(set_attr "type" "vop2,vop3b")
    (set_attr "length" "4,8")])
 
   [(set_attr "type" "vop2,vop3b,vop2,vop3b")
    (set_attr "length" "8")])
 
-; This pattern does not accept SGPR because VCC read already counts
-; as a SGPR use and number of SGPR operands is limited to 1.
+; v_subb does not accept an SGPR because the VCC read already counts as an
+; SGPR use and the number of SGPR operands is limited to 1.  It does not
+; accept "B" immediate constants due to a related bus conflict.
 
 (define_insn "subcv64si3<exec_vcc>"
   [(set (match_operand:V64SI 0 "register_operand"    "= v, v, v, v")
            (vec_merge:V64SI
              (vec_duplicate:V64SI (const_int 1))
              (vec_duplicate:V64SI (const_int 0))
-             (match_operand:DI 3 "gcn_alu_operand"  " cV,Sv,cV,Sv"))
-           (match_operand:V64SI 1 "gcn_alu_operand" " vA,vA,vB,vB"))
-         (match_operand:V64SI 2 "gcn_alu_operand"   " vB,vB,vA,vA")))
-   (set (match_operand:DI 4 "register_operand"      "=cV,Sg,cV,Sg")
+             (match_operand:DI 3 "gcn_alu_operand"  " cV,cVSv,cV,cVSv"))
+           (match_operand:V64SI 1 "gcn_alu_operand" " vA,  vA, v,  vA"))
+         (match_operand:V64SI 2 "gcn_alu_operand"   "  v,  vA,vA,  vA")))
+   (set (match_operand:DI 4 "register_operand"      "=cV,cVSg,cV,cVSg")
        (ior:DI (gtu:DI (minus:V64SI (minus:V64SI
                                       (vec_merge:V64SI
                                         (vec_duplicate:V64SI (const_int 1))
    v_subbrev%^_u32\t%0, %4, %2, %1, %3
    v_subbrev%^_u32\t%0, %4, %2, %1, %3"
   [(set_attr "type" "vop2,vop3b,vop2,vop3b")
-   (set_attr "length" "8")])
+   (set_attr "length" "4,8,4,8")])
 
 (define_insn_and_split "addv64di3"
-  [(set (match_operand:V64DI 0 "register_operand"   "=  &v")
+  [(set (match_operand:V64DI 0 "register_operand"   "= &v,  &v")
        (plus:V64DI
-         (match_operand:V64DI 1 "register_operand" "%  v0")
-         (match_operand:V64DI 2 "gcn_alu_operand"  "vSvB0")))
+         (match_operand:V64DI 1 "register_operand" "%vDb,vDb0")
+         (match_operand:V64DI 2 "gcn_alu_operand"  "vDb0, vDb")))
    (clobber (reg:DI VCC_REG))]
   ""
   "#"
    (set_attr "length" "8")])
 
 (define_insn_and_split "addv64di3_exec"
-  [(set (match_operand:V64DI 0 "register_operand"                "=  &v")
+  [(set (match_operand:V64DI 0 "register_operand"               "= &v,  &v")
        (vec_merge:V64DI
          (plus:V64DI
-           (match_operand:V64DI 1 "register_operand"             "%  v0")
-           (match_operand:V64DI 2 "gcn_alu_operand"              "vSvB0"))
-         (match_operand:V64DI 3 "gcn_register_or_unspec_operand" "   U0")
-         (match_operand:DI 4 "gcn_exec_reg_operand"              "    e")))
+           (match_operand:V64DI 1 "register_operand"            "%vDb,vDb0")
+           (match_operand:V64DI 2 "gcn_alu_operand"             "vDb0, vDb"))
+         (match_operand:V64DI 3 "gcn_register_or_unspec_operand" " U0,  U0")
+         (match_operand:DI 4 "gcn_exec_reg_operand"             "   e,   e")))
    (clobber (reg:DI VCC_REG))]
   ""
   "#"
    (set_attr "length" "8")])
 
 (define_insn_and_split "subv64di3"
-  [(set (match_operand:V64DI 0 "register_operand"  "= &v,   &v,   &v,  &v")
+  [(set (match_operand:V64DI 0 "register_operand"  "=&v,  &v,  &v, &v")
        (minus:V64DI                                                 
-         (match_operand:V64DI 1 "gcn_alu_operand" "vSvB,vSvB0,    v,  v0")
-         (match_operand:V64DI 2 "gcn_alu_operand" "  v0,    v,vSvB0,vSvB")))
+         (match_operand:V64DI 1 "gcn_alu_operand" "vDb,vDb0,   v, v0")
+         (match_operand:V64DI 2 "gcn_alu_operand" " v0,   v,vDb0,vDb")))
    (clobber (reg:DI VCC_REG))]
   ""
   "#"
   [(set_attr "type" "vmult")
    (set_attr "length" "8")])
 
-(define_insn_and_split "addv64di3_dup"
-  [(set (match_operand:V64DI 0 "register_operand"   "= &v")
-       (plus:V64DI
-         (match_operand:V64DI 1 "register_operand" "  v0")
-         (vec_duplicate:V64DI
-           (match_operand:DI 2 "gcn_alu_operand"   "SvDB"))))
-   (clobber (reg:DI VCC_REG))]
-  ""
-  "#"
-  "gcn_can_split_p  (V64DImode, operands[0])
-   && gcn_can_split_p (V64DImode, operands[1])
-   && gcn_can_split_p (V64DImode, operands[2])"
-  [(const_int 0)]
-  {
-    rtx vcc = gen_rtx_REG (DImode, VCC_REG);
-    emit_insn (gen_addv64si3_vcc_dup
-               (gcn_operand_part (V64DImode, operands[0], 0),
-                gcn_operand_part (DImode, operands[2], 0),
-                gcn_operand_part (V64DImode, operands[1], 0),
-                vcc));
-    emit_insn (gen_addcv64si3_dup
-               (gcn_operand_part (V64DImode, operands[0], 1),
-                gcn_operand_part (V64DImode, operands[1], 1),
-                gcn_operand_part (DImode, operands[2], 1),
-                vcc, vcc));
-    DONE;
-  }
-  [(set_attr "type" "vmult")
-   (set_attr "length" "8")])
-
-(define_insn_and_split "addv64di3_dup_exec"
-  [(set (match_operand:V64DI 0 "register_operand"                "= &v")
-       (vec_merge:V64DI
-         (plus:V64DI
-           (match_operand:V64DI 1 "register_operand"             "  v0")
-           (vec_duplicate:V64DI
-             (match_operand:DI 2 "gcn_alu_operand"               "SvDB")))
-         (match_operand:V64DI 3 "gcn_register_or_unspec_operand" "  U0")
-         (match_operand:DI 4 "gcn_exec_reg_operand"              "   e")))
-   (clobber (reg:DI VCC_REG))]
-  ""
-  "#"
-  "gcn_can_split_p  (V64DImode, operands[0])
-   && gcn_can_split_p (V64DImode, operands[1])
-   && gcn_can_split_p (V64DImode, operands[2])
-   && gcn_can_split_p (V64DImode, operands[3])"
-  [(const_int 0)]
-  {
-    rtx vcc = gen_rtx_REG (DImode, VCC_REG);
-    emit_insn (gen_addv64si3_vcc_dup_exec
-               (gcn_operand_part (V64DImode, operands[0], 0),
-                gcn_operand_part (DImode, operands[2], 0),
-                gcn_operand_part (V64DImode, operands[1], 0),
-                vcc,
-                gcn_operand_part (V64DImode, operands[3], 0),
-                operands[4]));
-    emit_insn (gen_addcv64si3_dup_exec
-               (gcn_operand_part (V64DImode, operands[0], 1),
-                gcn_operand_part (V64DImode, operands[1], 1),
-                gcn_operand_part (DImode, operands[2], 1),
-                vcc, vcc,
-                gcn_operand_part (V64DImode, operands[3], 1),
-                operands[4]));
-    DONE;
-  }
-  [(set_attr "type" "vmult")
-   (set_attr "length" "8")])
-
 (define_insn_and_split "addv64di3_zext"
-  [(set (match_operand:V64DI 0 "register_operand"    "=&v,&v")
+  [(set (match_operand:V64DI 0 "register_operand"    "=&v, &v,  &v,  &v")
        (plus:V64DI
          (zero_extend:V64DI
-           (match_operand:V64SI 1 "gcn_alu_operand" "0vA,0vB"))
-         (match_operand:V64DI 2 "gcn_alu_operand"   "0vB,0vA")))
+           (match_operand:V64SI 1 "gcn_alu_operand" "0vA,0vB,  vA,  vB"))
+         (match_operand:V64DI 2 "gcn_alu_operand"   "vDb,vDA,0vDb,0vDA")))
    (clobber (reg:DI VCC_REG))]
   ""
   "#"
     DONE;
   }
   [(set_attr "type" "vmult")
-   (set_attr "length" "8,8")])
+   (set_attr "length" "8")])
 
 (define_insn_and_split "addv64di3_zext_exec"
-  [(set (match_operand:V64DI 0 "register_operand"                "=&v,&v")
+  [(set (match_operand:V64DI 0 "register_operand"       "=&v,  &v, &v,  &v")
        (vec_merge:V64DI
          (plus:V64DI
            (zero_extend:V64DI
-             (match_operand:V64SI 1 "gcn_alu_operand"            "0vA,0vB"))
-           (match_operand:V64DI 2 "gcn_alu_operand"              "0vB,0vA"))
-         (match_operand:V64DI 3 "gcn_register_or_unspec_operand" " U0, U0")
-         (match_operand:DI 4 "gcn_exec_reg_operand"              "  e,  e")))
+             (match_operand:V64SI 1 "gcn_alu_operand"   "0vA,  vA,0vB,  vB"))
+           (match_operand:V64DI 2 "gcn_alu_operand"     "vDb,0vDb,vDA,0vDA"))
+         (match_operand:V64DI 3 "gcn_register_or_unspec_operand"
+                                                        " U0,  U0, U0,  U0")
+         (match_operand:DI 4 "gcn_exec_reg_operand"     "  e,   e,  e,   e")))
    (clobber (reg:DI VCC_REG))]
   ""
   "#"
     DONE;
   }
   [(set_attr "type" "vmult")
-   (set_attr "length" "8,8")])
+   (set_attr "length" "8")])
 
 (define_insn_and_split "addv64di3_zext_dup"
-  [(set (match_operand:V64DI 0 "register_operand"   "=&v")
+  [(set (match_operand:V64DI 0 "register_operand"   "= &v,  &v")
        (plus:V64DI
          (zero_extend:V64DI
            (vec_duplicate:V64SI
-             (match_operand:SI 1 "gcn_alu_operand" "BSv")))
-         (match_operand:V64DI 2 "gcn_alu_operand"  "vA0")))
+             (match_operand:SI 1 "gcn_alu_operand" " BSv, ASv")))
+         (match_operand:V64DI 2 "gcn_alu_operand"  "vDA0,vDb0")))
    (clobber (reg:DI VCC_REG))]
   ""
   "#"
    (set_attr "length" "8")])
 
 (define_insn_and_split "addv64di3_zext_dup_exec"
-  [(set (match_operand:V64DI 0 "register_operand"                "=&v")
+  [(set (match_operand:V64DI 0 "register_operand"               "= &v,  &v")
        (vec_merge:V64DI
          (plus:V64DI
            (zero_extend:V64DI
              (vec_duplicate:V64SI
-               (match_operand:SI 1 "gcn_alu_operand"             "BSv")))
-           (match_operand:V64DI 2 "gcn_alu_operand"              "vA0"))
-         (match_operand:V64DI 3 "gcn_register_or_unspec_operand" " U0")
-         (match_operand:DI 4 "gcn_exec_reg_operand"              "  e")))
+               (match_operand:SI 1 "gcn_alu_operand"            " ASv, BSv")))
+           (match_operand:V64DI 2 "gcn_alu_operand"             "vDb0,vDA0"))
+         (match_operand:V64DI 3 "gcn_register_or_unspec_operand" " U0,  U0")
+         (match_operand:DI 4 "gcn_exec_reg_operand"             "   e,   e")))
    (clobber (reg:DI VCC_REG))]
   ""
   "#"
    (set_attr "length" "8")])
 
 (define_insn_and_split "addv64di3_zext_dup2"
-  [(set (match_operand:V64DI 0 "register_operand"                    "= v")
+  [(set (match_operand:V64DI 0 "register_operand"                   "= &v")
        (plus:V64DI
          (zero_extend:V64DI (match_operand:V64SI 1 "gcn_alu_operand" " vA"))
-         (vec_duplicate:V64DI (match_operand:DI 2 "gcn_alu_operand"  "BSv"))))
+         (vec_duplicate:V64DI (match_operand:DI 2 "gcn_alu_operand" "DbSv"))))
    (clobber (reg:DI VCC_REG))]
   ""
   "#"
    (set_attr "length" "8")])
 
 (define_insn_and_split "addv64di3_zext_dup2_exec"
-  [(set (match_operand:V64DI 0 "register_operand"                     "= v")
+  [(set (match_operand:V64DI 0 "register_operand"                     "=&v")
        (vec_merge:V64DI
          (plus:V64DI
            (zero_extend:V64DI (match_operand:V64SI 1 "gcn_alu_operand"
    (set_attr "length" "8")])
 
 (define_insn_and_split "addv64di3_sext_dup2"
-  [(set (match_operand:V64DI 0 "register_operand"                    "= v")
+  [(set (match_operand:V64DI 0 "register_operand"                    "=&v")
        (plus:V64DI
          (sign_extend:V64DI (match_operand:V64SI 1 "gcn_alu_operand" " vA"))
          (vec_duplicate:V64DI (match_operand:DI 2 "gcn_alu_operand"  "BSv"))))
    (set_attr "length" "8")])
 
 (define_insn_and_split "addv64di3_sext_dup2_exec"
-  [(set (match_operand:V64DI 0 "register_operand"                     "= v")
+  [(set (match_operand:V64DI 0 "register_operand"                     "=&v")
        (vec_merge:V64DI
          (plus:V64DI
            (sign_extend:V64DI (match_operand:V64SI 1 "gcn_alu_operand"
   {
     rtx tmp = gen_reg_rtx (V64DImode);
     rtx v1 = gen_rtx_REG (V64SImode, VGPR_REGNO (1));
+    rtx op1vec = gen_reg_rtx (V64DImode);
 
     emit_insn (gen_mulv64di3_zext_dup2 (tmp, v1, operands[2]));
-    emit_insn (gen_addv64di3_dup (operands[0], tmp, operands[1]));
+    emit_insn (gen_vec_duplicatev64si (op1vec, operands[1]));
+    emit_insn (gen_addv64di3 (operands[0], tmp, op1vec));
     DONE;
   })
 
index b361cff..4056f72 100644 (file)
@@ -902,16 +902,17 @@ gcn_constant_p (rtx x)
 
 /* Return true if X is a constant representable as two inline immediate
    constants in a 64-bit instruction that is split into two 32-bit
-   instructions.  */
+   instructions.
+   When MIXED is set, the low-part is permitted to use the full 32-bits.  */
 
 bool
-gcn_inline_constant64_p (rtx x)
+gcn_inline_constant64_p (rtx x, bool mixed)
 {
   if (GET_CODE (x) == CONST_VECTOR)
     {
       if (!vgpr_vector_mode_p (GET_MODE (x)))
        return false;
-      if (!gcn_inline_constant64_p (CONST_VECTOR_ELT (x, 0)))
+      if (!gcn_inline_constant64_p (CONST_VECTOR_ELT (x, 0), mixed))
        return false;
       for (int i = 1; i < 64; i++)
        if (CONST_VECTOR_ELT (x, i) != CONST_VECTOR_ELT (x, 0))
@@ -925,7 +926,8 @@ gcn_inline_constant64_p (rtx x)
 
   rtx val_lo = gcn_operand_part (DImode, x, 0);
   rtx val_hi = gcn_operand_part (DImode, x, 1);
-  return gcn_inline_constant_p (val_lo) && gcn_inline_constant_p (val_hi);
+  return ((mixed || gcn_inline_constant_p (val_lo))
+         && gcn_inline_constant_p (val_hi));
 }
 
 /* Return true if X is a constant representable as an immediate constant