[PATCH][AArch64] Improve add immediate expansion
authorWilco Dijkstra <wdijkstr@arm.com>
Tue, 24 Nov 2015 14:46:05 +0000 (14:46 +0000)
committerJames Greenhalgh <jgreenhalgh@gcc.gnu.org>
Tue, 24 Nov 2015 14:46:05 +0000 (14:46 +0000)
gcc/

* gcc/config/aarch64/aarch64.md (add<mode>3):
Block early expansion into 2 add instructions.
(add<mode>3_pluslong): New pattern to combine complex
immediates into 2 additions.

From-SVN: r230814

gcc/ChangeLog
gcc/config/aarch64/aarch64.md

index 5203b2865d376e56a880388a6a96b9eb846d9199..6a5ebdeeed8fa9a568d9a87ca05cf11c3d655584 100644 (file)
@@ -1,3 +1,10 @@
+2015-11-24  Wilco Dijkstra  <wdijkstr@arm.com>
+
+       * gcc/config/aarch64/aarch64.md (add<mode>3):
+       Block early expansion into 2 add instructions.
+       (add<mode>3_pluslong): New pattern to combine complex
+       immediates into 2 additions.
+
 2015-11-24  Segher Boessenkool  <segher@kernel.crashing.org>
 
        PR target/66217
index 28a7f8c6fc8f63e194cfa3ede3cea39e1abefe25..c11e8ec01df4418044726a2bf771922ec004e43f 100644 (file)
              (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
   ""
   "
-  if (! aarch64_plus_operand (operands[2], VOIDmode))
+  if (!aarch64_plus_operand (operands[2], VOIDmode))
     {
-      HOST_WIDE_INT imm = INTVAL (operands[2]);
-
-      if (aarch64_move_imm (imm, <MODE>mode) && can_create_pseudo_p ())
-        {
+      if (can_create_pseudo_p ())
+       {
          rtx tmp = gen_reg_rtx (<MODE>mode);
          emit_move_insn (tmp, operands[2]);
          operands[2] = tmp;
-        }
+       }
       else
-        {
-         rtx subtarget = ((optimize && can_create_pseudo_p ())
-                          ? gen_reg_rtx (<MODE>mode) : operands[0]);
-
-         if (imm < 0)
-           imm = -(-imm & ~0xfff);
-         else
-           imm &= ~0xfff;
-
-         emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
-         operands[1] = subtarget;
-         operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
-        }
+       {
+         HOST_WIDE_INT imm = INTVAL (operands[2]);
+         imm = imm >= 0 ? imm & 0xfff : -(-imm & 0xfff);
+         emit_insn (gen_add<mode>3 (operands[0], operands[1],
+                                    GEN_INT (INTVAL (operands[2]) - imm)));
+         operands[1] = operands[0];
+         operands[2] = GEN_INT (imm);
+       }
+    }
+  "
+)
+
+;; Find add with a 2-instruction immediate and merge into 2 add instructions.
+
+(define_insn_and_split "*add<mode>3_pluslong"
+  [(set
+    (match_operand:GPI 0 "register_operand" "")
+    (plus:GPI (match_operand:GPI 1 "register_operand" "")
+             (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
+  "!aarch64_plus_operand (operands[2], VOIDmode)
+   && !aarch64_move_imm (INTVAL (operands[2]), <MODE>mode)"
+  "#"
+  "&& true"
+  [(set (match_dup 0) (plus:GPI (match_dup 1) (match_dup 3)))
+   (set (match_dup 0) (plus:GPI (match_dup 0) (match_dup 4)))]
+  "
+    {
+      HOST_WIDE_INT imm = INTVAL (operands[2]);
+      imm = imm >= 0 ? imm & 0xfff : -(-imm & 0xfff);
+      operands[3] = GEN_INT (INTVAL (operands[2]) - imm);
+      operands[4] = GEN_INT (imm);
     }
   "
 )