re PR rtl-optimization/83628 (performance regression when accessing arrays on alpha)
authorUros Bizjak <uros@gcc.gnu.org>
Thu, 4 Jan 2018 09:42:01 +0000 (10:42 +0100)
committerUros Bizjak <uros@gcc.gnu.org>
Thu, 4 Jan 2018 09:42:01 +0000 (10:42 +0100)
PR target/83628
* config/alpha/alpha.md (*sadd<modesuffix>): Use ASHIFT
instead of MULT rtx.  Update all corresponding splitters.
(*saddl_se): Ditto.
(*ssub<modesuffix>): Ditto.
(*ssubl_se): Ditto.
(*cmp_sadd_di): Update split patterns.
(*cmp_sadd_si): Ditto.
(*cmp_sadd_sidi): Ditto.
(*cmp_ssub_di): Ditto.
(*cmp_ssub_si): Ditto.
(*cmp_ssub_sidi): Ditto.
* config/alpha/predicates.md (const23_operand): New predicate.
* config/alpha/alpha.c (alpha_rtx_costs) [PLUS, MINUS]:
Look for ASHIFT, not MULT inner operand.
(alpha_split_conditional_move): Update for *sadd<modesuffix> change.

testsuite/ChangeLog:

PR target/83628
* gcc.target/alpha/pr83628-1.c: New test.
* gcc.target/alpha/pr83628-2.c: Ditto.

From-SVN: r256228

gcc/ChangeLog
gcc/config/alpha/alpha.c
gcc/config/alpha/alpha.md
gcc/config/alpha/predicates.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/alpha/pr83628-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/alpha/pr83628-2.c [new file with mode: 0644]

index 71ac19d67eec8780b276d7e631b1eca7bf2ef3b1..f62f43f3dbfe44c368c837cfdfebe5bf9eb7721e 100644 (file)
@@ -1,3 +1,22 @@
+2018-01-04  Uros Bizjak  <ubizjak@gmail.com>
+
+       PR target/83628
+       * config/alpha/alpha.md (*sadd<modesuffix>): Use ASHIFT
+       instead of MULT rtx.  Update all corresponding splitters.
+       (*saddl_se): Ditto.
+       (*ssub<modesuffix>): Ditto.
+       (*ssubl_se): Ditto.
+       (*cmp_sadd_di): Update split patterns.
+       (*cmp_sadd_si): Ditto.
+       (*cmp_sadd_sidi): Ditto.
+       (*cmp_ssub_di): Ditto.
+       (*cmp_ssub_si): Ditto.
+       (*cmp_ssub_sidi): Ditto.
+       * config/alpha/predicates.md (const23_operand): New predicate.
+       * config/alpha/alpha.c (alpha_rtx_costs) [PLUS, MINUS]:
+       Look for ASHIFT, not MULT inner operand.
+       (alpha_split_conditional_move): Update for *sadd<modesuffix> change.
+
 2018-01-04  Martin Liska  <mliska@suse.cz>
 
        PR gcov-profile/83669
 
 2018-01-02  Aaron Sawdey  <acsawdey@linux.vnet.ibm.com>
 
-        * config/rs6000/rs6000-string.c (expand_block_move): Allow the use of
-        unaligned VSX load/store on P8/P9.
-        (expand_block_clear): Allow the use of unaligned VSX
+       * config/rs6000/rs6000-string.c (expand_block_move): Allow the use of
+       unaligned VSX load/store on P8/P9.
+       (expand_block_clear): Allow the use of unaligned VSX
        load/store on P8/P9.
 
 2018-01-02  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
index 814dc6a85f4dbc44c3f87007c43b810b84ee00e7..2f6d118606a33cb66b72edfcfa9a20e9f0f03f65 100644 (file)
@@ -1435,8 +1435,8 @@ alpha_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno, int *total,
     case MINUS:
       if (float_mode_p)
        *total = cost_data->fp_add;
-      else if (GET_CODE (XEXP (x, 0)) == MULT
-              && const48_operand (XEXP (XEXP (x, 0), 1), VOIDmode))
+      else if (GET_CODE (XEXP (x, 0)) == ASHIFT
+              && const23_operand (XEXP (XEXP (x, 0), 1), VOIDmode))
        {
          *total = (rtx_cost (XEXP (XEXP (x, 0), 0), mode,
                              (enum rtx_code) outer_code, opno, speed)
@@ -2963,8 +2963,8 @@ alpha_split_conditional_move (enum rtx_code code, rtx dest, rtx cond,
          add_op = GEN_INT (f);
          if (sext_add_operand (add_op, mode))
            {
-             tmp = gen_rtx_MULT (DImode, copy_rtx (subtarget),
-                                 GEN_INT (diff));
+             tmp = gen_rtx_ASHIFT (DImode, copy_rtx (subtarget),
+                                   GEN_INT (exact_log2 (diff)));
              tmp = gen_rtx_PLUS (DImode, tmp, add_op);
              emit_insn (gen_rtx_SET (target, tmp));
            }
index b177a37ef67c0cde473db66d280a238b05a99fd5..7493f3e9d3510124212e3c4628176a6639a89a68 100644 (file)
   "! sext_add_operand (operands[2], SImode) && INTVAL (operands[2]) > 0
    && INTVAL (operands[2]) % 4 == 0"
   [(set (match_dup 3) (match_dup 4))
-   (set (match_dup 0) (sign_extend:DI (plus:SI (mult:SI (match_dup 3)
-                                                       (match_dup 5))
+   (set (match_dup 0) (sign_extend:DI (plus:SI (ashift:SI (match_dup 3)
+                                                         (match_dup 5))
                                               (match_dup 1))))]
 {
   HOST_WIDE_INT val = INTVAL (operands[2]) / 4;
     val /= 2, mult = 8;
 
   operands[4] = GEN_INT (val);
-  operands[5] = GEN_INT (mult);
+  operands[5] = GEN_INT (exact_log2 (mult));
 })
 
 (define_split
 (define_insn "*sadd<modesuffix>"
   [(set (match_operand:I48MODE 0 "register_operand" "=r,r")
        (plus:I48MODE
-        (mult:I48MODE (match_operand:I48MODE 1 "reg_not_elim_operand" "r,r")
-                      (match_operand:I48MODE 2 "const48_operand" "I,I"))
+        (ashift:I48MODE (match_operand:I48MODE 1 "reg_not_elim_operand" "r,r")
+                        (match_operand:I48MODE 2 "const23_operand" "I,I"))
         (match_operand:I48MODE 3 "sext_add_operand" "rI,O")))]
   ""
   "@
-   s%2add<modesuffix> %1,%3,%0
-   s%2sub<modesuffix> %1,%n3,%0")
+   s%P2add<modesuffix> %1,%3,%0
+   s%P2sub<modesuffix> %1,%n3,%0")
 
 (define_insn "*saddl_se"
   [(set (match_operand:DI 0 "register_operand" "=r,r")
        (sign_extend:DI
-        (plus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r,r")
-                          (match_operand:SI 2 "const48_operand" "I,I"))
+        (plus:SI (ashift:SI (match_operand:SI 1 "reg_not_elim_operand" "r,r")
+                            (match_operand:SI 2 "const23_operand" "I,I"))
                  (match_operand:SI 3 "sext_add_operand" "rI,O"))))]
   ""
   "@
-   s%2addl %1,%3,%0
-   s%2subl %1,%n3,%0")
+   s%P2addl %1,%3,%0
+   s%P2subl %1,%n3,%0")
 
 (define_split
   [(set (match_operand:DI 0 "register_operand")
        (sign_extend:DI
-        (plus:SI (mult:SI (match_operator:SI 1 "comparison_operator"
+        (plus:SI (ashift:SI (match_operator:SI 1 "comparison_operator"
                                              [(match_operand 2)
                                               (match_operand 3)])
-                          (match_operand:SI 4 "const48_operand"))
+                          (match_operand:SI 4 "const23_operand"))
                  (match_operand:SI 5 "sext_add_operand"))))
    (clobber (match_operand:DI 6 "reg_not_elim_operand"))]
   ""
   [(set (match_dup 6) (match_dup 7))
    (set (match_dup 0)
-       (sign_extend:DI (plus:SI (mult:SI (match_dup 8) (match_dup 4))
+       (sign_extend:DI (plus:SI (ashift:SI (match_dup 8) (match_dup 4))
                                 (match_dup 5))))]
 {
   operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[1]), DImode,
 (define_insn "*ssub<modesuffix>"
   [(set (match_operand:I48MODE 0 "register_operand" "=r")
        (minus:I48MODE
-        (mult:I48MODE (match_operand:I48MODE 1 "reg_not_elim_operand" "r")
-                      (match_operand:I48MODE 2 "const48_operand" "I"))
+        (ashift:I48MODE (match_operand:I48MODE 1 "reg_not_elim_operand" "r")
+                        (match_operand:I48MODE 2 "const23_operand" "I"))
                  (match_operand:I48MODE 3 "reg_or_8bit_operand" "rI")))]
   ""
-  "s%2sub<modesuffix> %1,%3,%0")
+  "s%P2sub<modesuffix> %1,%3,%0")
 
 (define_insn "*ssubl_se"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (sign_extend:DI
-        (minus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r")
-                           (match_operand:SI 2 "const48_operand" "I"))
+        (minus:SI (ashift:SI (match_operand:SI 1 "reg_not_elim_operand" "r")
+                             (match_operand:SI 2 "const23_operand" "I"))
                   (match_operand:SI 3 "reg_or_8bit_operand" "rI"))))]
   ""
-  "s%2subl %1,%3,%0")
+  "s%P2subl %1,%3,%0")
 
 (define_insn "subv<mode>3"
   [(set (match_operand:I48MODE 0 "register_operand" "=r")
   [(set (match_dup 5)
        (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
    (set (match_dup 0)
-       (plus:DI (mult:DI (match_dup 5) (match_dup 3))
+       (plus:DI (ashift:DI (match_dup 5) (match_dup 3))
                 (match_dup 4)))]
 {
+  operands[3] = GEN_INT (exact_log2 (INTVAL (operands [3])));
   if (can_create_pseudo_p ())
     operands[5] = gen_reg_rtx (DImode);
   else if (reg_overlap_mentioned_p (operands[5], operands[4]))
   [(set (match_dup 5)
        (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
    (set (match_dup 0)
-       (plus:SI (mult:SI (match_dup 6) (match_dup 3))
+       (plus:SI (ashift:SI (match_dup 6) (match_dup 3))
                 (match_dup 4)))]
 {
+  operands[3] = GEN_INT (exact_log2 (INTVAL (operands [3])));
   if (can_create_pseudo_p ())
     operands[5] = gen_reg_rtx (DImode);
   else if (reg_overlap_mentioned_p (operands[5], operands[4]))
   [(set (match_dup 5)
        (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
    (set (match_dup 0)
-       (sign_extend:DI (plus:SI (mult:SI (match_dup 6) (match_dup 3))
+       (sign_extend:DI (plus:SI (ashift:SI (match_dup 6) (match_dup 3))
                                 (match_dup 4))))]
 {
+  operands[3] = GEN_INT (exact_log2 (INTVAL (operands [3])));
   if (can_create_pseudo_p ())
     operands[5] = gen_reg_rtx (DImode);
   else if (reg_overlap_mentioned_p (operands[5], operands[4]))
   [(set (match_dup 5)
        (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
    (set (match_dup 0)
-       (minus:DI (mult:DI (match_dup 5) (match_dup 3))
+       (minus:DI (ashift:DI (match_dup 5) (match_dup 3))
                  (match_dup 4)))]
 {
+  operands[3] = GEN_INT (exact_log2 (INTVAL (operands [3])));
   if (can_create_pseudo_p ())
     operands[5] = gen_reg_rtx (DImode);
   else if (reg_overlap_mentioned_p (operands[5], operands[4]))
   [(set (match_dup 5)
        (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
    (set (match_dup 0)
-       (minus:SI (mult:SI (match_dup 6) (match_dup 3))
+       (minus:SI (ashift:SI (match_dup 6) (match_dup 3))
                 (match_dup 4)))]
 {
+  operands[3] = GEN_INT (exact_log2 (INTVAL (operands [3])));
   if (can_create_pseudo_p ())
     operands[5] = gen_reg_rtx (DImode);
   else if (reg_overlap_mentioned_p (operands[5], operands[4]))
   [(set (match_dup 5)
        (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
    (set (match_dup 0)
-       (sign_extend:DI (minus:SI (mult:SI (match_dup 6) (match_dup 3))
+       (sign_extend:DI (minus:SI (ashift:SI (match_dup 6) (match_dup 3))
                                  (match_dup 4))))]
 {
+  operands[3] = GEN_INT (exact_log2 (INTVAL (operands [3])));
   if (can_create_pseudo_p ())
     operands[5] = gen_reg_rtx (DImode);
   else if (reg_overlap_mentioned_p (operands[5], operands[4]))
index 4b6f0f15229971680a4875c84f2e2c820ab2d31e..d6789348894b40a37dab0caa4249980aa636336e 100644 (file)
   (and (match_code "const_int,const_wide_int,const_double,const_vector")
        (not (match_test "op == CONST0_RTX (mode)"))))
 
+;; Return 1 if OP is the constant 2 or 3.
+(define_predicate "const23_operand"
+  (and (match_code "const_int")
+       (match_test "INTVAL (op) == 2 || INTVAL (op) == 3")))
+
 ;; Return 1 if OP is the constant 4 or 8.
 (define_predicate "const48_operand"
   (and (match_code "const_int")
index e7de3ae4c9d527666ea476091f3c1047d4374fc1..3a93d177db6908c77b50afbd4cd194ca582dffbe 100644 (file)
@@ -1,3 +1,9 @@
+2018-01-04  Uros Bizjak  <ubizjak@gmail.com>
+
+       PR target/83628
+       * gcc.target/alpha/pr83628-1.c: New test.
+       * gcc.target/alpha/pr83628-2.c: Ditto.
+
 2018-01-04  Martin Liska  <mliska@suse.cz>
 
        PR ipa/82352
diff --git a/gcc/testsuite/gcc.target/alpha/pr83628-1.c b/gcc/testsuite/gcc.target/alpha/pr83628-1.c
new file mode 100644 (file)
index 0000000..a4a32d9
--- /dev/null
@@ -0,0 +1,19 @@
+/* PR target/83628 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+int
+get_int (int *p, size_t idx)
+{
+  return p[idx];
+}
+
+long
+get_long (long *p, size_t idx)
+{
+  return p[idx];
+}
+
+/* { dg-final { scan-assembler-not "\[ \t\]add\[ql\]" } } */
diff --git a/gcc/testsuite/gcc.target/alpha/pr83628-2.c b/gcc/testsuite/gcc.target/alpha/pr83628-2.c
new file mode 100644 (file)
index 0000000..0910d38
--- /dev/null
@@ -0,0 +1,29 @@
+/* PR target/83628 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int
+s4l (int a, int b)
+{
+  return a + b * 4;
+}
+
+int
+s8l (int a, int b)
+{
+  return a + b * 8;
+}
+
+long
+s4q (long a, long b)
+{
+  return a + b * 4;
+}
+
+long
+s8q (long a, long b)
+{
+  return a + b * 8;
+}
+
+/* { dg-final { scan-assembler-not "\[ \t\]add\[ql\]" } } */