[alpha] : Work around PR83628, performance regression when accessing arrays on alpha

Message ID CAFULd4b46=p4ihfYOfLW2NQEsDneDjQ4zbqpOumG4t2o58Gm_g@mail.gmail.com
State New
Headers show
Series
  • [alpha] : Work around PR83628, performance regression when accessing arrays on alpha
Related show

Commit Message

Uros Bizjak Jan. 12, 2018, 4:56 p.m.
Hello!

It turns out that without ashlsi3 named pattern combine pass won't
simplify subregs in:

(set (reg:SI 74)
    (plus:SI (subreg:SI (ashift:DI (reg:DI 17 $17 [ b ])
                (const_int 2 [0x2])) 0)
        (reg:SI 16 $16 [ a ])))

Attached patch adds relevant insn-and-split patterns to work around
this limitation.

2018-01-12  Uros Bizjak  <ubizjak@gmail.com>

    PR target/83628
    * config/alpha/alpha.md (*saddsi_1): New insn_ans_split pattern.
    (*saddl_se_1): Ditto.
    (*ssubsi_1): Ditto.
    (*ssubl_se_1): Ditto.

testsuite/ChangeLog:

2018-01-12  Uros Bizjak  <ubizjak@gmail.com>

    PR target/83628
    * gcc.target/alpha/pr83628-3.c: New test.

Bootstrapped and regression tested on alphaev68-linux-gnu.

Committed to mainline SVN.

Uros.

Patch

Index: config/alpha/alpha.md
===================================================================
--- config/alpha/alpha.md	(revision 256460)
+++ config/alpha/alpha.md	(working copy)
@@ -527,17 +527,50 @@ 
    s%P2add<modesuffix> %1,%3,%0
    s%P2sub<modesuffix> %1,%n3,%0")
 
+(define_insn_and_split "*saddsi_1"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+	(plus:SI
+	 (subreg:SI
+	  (ashift:DI (match_operand:DI 1 "reg_not_elim_operand" "r,r")
+		     (match_operand:DI 2 "const23_operand" "I,I")) 0)
+	 (match_operand:SI 3 "sext_add_operand" "rI,O")))]
+  ""
+  "#"
+  ""
+  [(set (match_dup 0)
+	(plus:SI (ashift:SI (match_dup 1) (match_dup 2))
+		 (match_dup 3)))]
+  "operands[1] = gen_lowpart (SImode, operands[1]);")
+
 (define_insn "*saddl_se"
   [(set (match_operand:DI 0 "register_operand" "=r,r")
 	(sign_extend:DI
-	 (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"))))]
+	 (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%P2addl %1,%3,%0
    s%P2subl %1,%n3,%0")
 
+(define_insn_and_split "*saddl_se_1"
+  [(set (match_operand:DI 0 "register_operand" "=r,r")
+	(sign_extend:DI
+	 (plus:SI
+	  (subreg:SI
+	   (ashift:DI (match_operand:DI 1 "reg_not_elim_operand" "r,r")
+		      (match_operand:DI 2 "const23_operand" "I,I")) 0)
+	 (match_operand:SI 3 "sext_add_operand" "rI,O"))))]
+  ""
+  "#"
+  ""
+  [(set (match_dup 0)
+	(sign_extend:DI
+	 (plus:SI (ashift:SI (match_dup 1) (match_dup 2))
+		  (match_dup 3))))]
+  "operands[1] = gen_lowpart (SImode, operands[1]);")
+
 (define_split
   [(set (match_operand:DI 0 "register_operand")
 	(sign_extend:DI
@@ -627,15 +660,48 @@ 
   ""
   "s%P2sub<modesuffix> %1,%3,%0")
 
+(define_insn_and_split "*ssubsi_1"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(minus:SI
+	 (subreg:SI
+	  (ashift:DI (match_operand:DI 1 "reg_not_elim_operand" "r")
+		     (match_operand:DI 2 "const23_operand" "I")) 0)
+	 (match_operand:SI 3 "reg_or_8bit_operand" "rI")))]
+  ""
+  "#"
+  ""
+  [(set (match_dup 0)
+	(minus:SI (ashift:SI (match_dup 1) (match_dup 2))
+		  (match_dup 3)))]
+  "operands[1] = gen_lowpart (SImode, operands[1]);")
+
 (define_insn "*ssubl_se"
   [(set (match_operand:DI 0 "register_operand" "=r")
 	(sign_extend:DI
-	 (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"))))]
+	 (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%P2subl %1,%3,%0")
 
+(define_insn_and_split "*ssubl_se_1"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+	(sign_extend:DI
+	 (minus:SI
+	  (subreg:SI
+	   (ashift:DI (match_operand:DI 1 "reg_not_elim_operand" "r")
+		      (match_operand:DI 2 "const23_operand" "I")) 0)
+	 (match_operand:SI 3 "reg_or_8bit_operand" "rI"))))]
+  ""
+  "#"
+  ""
+  [(set (match_dup 0)
+	(sign_extend:DI
+	 (minus:SI (ashift:SI (match_dup 1) (match_dup 2))
+		   (match_dup 3))))]
+  "operands[1] = gen_lowpart (SImode, operands[1]);")
+
 (define_insn "subv<mode>3"
   [(set (match_operand:I48MODE 0 "register_operand" "=r")
 	(minus:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "rJ")
@@ -1200,7 +1266,7 @@ 
 	 (subreg:SI (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
 			       (match_operand:DI 2 "const_int_operand" "P"))
 		    0)))]
-  "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3"
+  "IN_RANGE (INTVAL (operands[2]), 1, 3)"
 {
   if (operands[2] == const1_rtx)
     return "addl %r1,%r1,%0";
Index: testsuite/gcc.target/alpha/pr83628-3.c
===================================================================
--- testsuite/gcc.target/alpha/pr83628-3.c	(nonexistent)
+++ testsuite/gcc.target/alpha/pr83628-3.c	(working copy)
@@ -0,0 +1,29 @@ 
+/* PR target/83628 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int
+s4l (int a, int b)
+{
+  return a * 4 - b;
+}
+
+int
+s8l (int a, int b)
+{
+  return a * 8 - b;
+}
+
+long
+s4q (long a, long b)
+{
+  return a * 4 - b;
+}
+
+long
+s8q (long a, long b)
+{
+  return a * 8 - b;
+}
+
+/* { dg-final { scan-assembler-not "\[ \t\]sub\[ql\]" } } */