]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR rtl-optimization/60501 (LRA emits add patterns which might clobber cc)
authorAndreas Krebbel <Andreas.Krebbel@de.ibm.com>
Mon, 24 Mar 2014 17:38:09 +0000 (17:38 +0000)
committerAndreas Krebbel <krebbel@gcc.gnu.org>
Mon, 24 Mar 2014 17:38:09 +0000 (17:38 +0000)
2014-03-24  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>

PR rtl-optimization/60501
* optabs.def (addptr3_optab): New optab.
* optabs.c (gen_addptr3_insn, have_addptr3_insn): New function.
* doc/md.texi ("addptrm3"): Document new RTL standard expander.
* expr.h (gen_addptr3_insn, have_addptr3_insn): Add prototypes.

* lra.c (emit_add3_insn): Use the addptr pattern if available.

* config/s390/s390.md ("addptrdi3", "addptrsi3"): New expanders.

From-SVN: r208796

gcc/ChangeLog
gcc/config/s390/s390.md
gcc/doc/md.texi
gcc/expr.h
gcc/lra.c
gcc/optabs.c
gcc/optabs.def

index e24b5faac8d34d1df694b386aafd645409cb861c..d904fc022a932dcb32a132fa85ee2005c58c6713 100644 (file)
@@ -1,3 +1,15 @@
+2014-03-24  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>
+
+       PR rtl-optimization/60501
+       * optabs.def (addptr3_optab): New optab.
+       * optabs.c (gen_addptr3_insn, have_addptr3_insn): New function.
+       * doc/md.texi ("addptrm3"): Document new RTL standard expander.
+       * expr.h (gen_addptr3_insn, have_addptr3_insn): Add prototypes.
+
+       * lra.c (emit_add3_insn): Use the addptr pattern if available.
+
+       * config/s390/s390.md ("addptrdi3", "addptrsi3"): New expanders.
+
 2014-03-24  Ulrich Drepper  <drepper@gmail.com>
 
        * config/i386/avx512fintrin.h: Define _mm512_set1_ps and
index 76902b5eae589a2bd63db3612dc4d2fc996b62dc..7d9d1ad7ecd3a81da667df53fdb98232c952f379 100644 (file)
   [(set_attr "op_type"  "<RRer>,RXE")
    (set_attr "type"     "fsimp<mode>")])
 
+;
+; Pointer add instruction patterns
+;
+
+; This will match "*la_64"
+(define_expand "addptrdi3"
+  [(set (match_operand:DI 0 "register_operand" "")
+        (plus:DI (match_operand:DI 1 "register_operand" "")
+                (match_operand:DI 2 "nonmemory_operand" "")))]
+  "TARGET_64BIT"
+{
+  HOST_WIDE_INT c = INTVAL (operands[2]);
+
+  if (GET_CODE (operands[2]) == CONST_INT)
+    {
+      if (!CONST_OK_FOR_CONSTRAINT_P (c, 'K', "K")
+         && !CONST_OK_FOR_CONSTRAINT_P (c, 'O', "Os"))
+        {
+         operands[2] = force_const_mem (DImode, operands[2]);
+         operands[2] = force_reg (DImode, operands[2]);
+        }
+      else if (!DISP_IN_RANGE (INTVAL (operands[2])))
+        operands[2] = force_reg (DImode, operands[2]);
+    }
+})
+
+; For 31 bit we have to prevent the generated pattern from matching
+; normal ADDs since la only does a 31 bit add.  This is supposed to
+; match "force_la_31".
+(define_expand "addptrsi3"
+  [(parallel
+    [(set (match_operand:SI 0 "register_operand" "")
+         (plus:SI (match_operand:SI 1 "register_operand" "")
+                  (match_operand:SI 2 "nonmemory_operand" "")))
+                  (use (const_int 0))])]
+  "!TARGET_64BIT"
+{
+  HOST_WIDE_INT c = INTVAL (operands[2]);
+
+  if (GET_CODE (operands[2]) == CONST_INT)
+    {
+      if (!CONST_OK_FOR_CONSTRAINT_P (c, 'K', "K")
+         && !CONST_OK_FOR_CONSTRAINT_P (c, 'O', "Os"))
+        {
+         operands[2] = force_const_mem (SImode, operands[2]);
+         operands[2] = force_reg (SImode, operands[2]);
+        }
+      else if (!DISP_IN_RANGE (INTVAL (operands[2])))
+        operands[2] = force_reg (SImode, operands[2]);
+    }
+})
 
 ;;
 ;;- Subtract instructions.
index 746acc2bce7b6f79b40ec120c7ac91c7df97780e..85fd4b90f427189a16506b0f94146f26b494e2a7 100644 (file)
@@ -4720,6 +4720,17 @@ Add operand 2 and operand 1, storing the result in operand 0.  All operands
 must have mode @var{m}.  This can be used even on two-address machines, by
 means of constraints requiring operands 1 and 0 to be the same location.
 
+@cindex @code{addptr@var{m}3} instruction pattern
+@item @samp{addptr@var{m}3}
+Like @code{add@var{m}3} but is guaranteed to only be used for address
+calculations.  The expanded code is not allowed to clobber the
+condition code.  It only needs to be defined if @code{add@var{m}3}
+sets the condition code.  If adds used for address calculations and
+normal adds are not compatible it is required to expand a distinct
+pattern (e.g. using an unspec).  The pattern is used by LRA to emit
+address calculations.  @code{add@var{m}3} is used if
+@code{addptr@var{m}3} is not defined.
+
 @cindex @code{ssadd@var{m}3} instruction pattern
 @cindex @code{usadd@var{m}3} instruction pattern
 @cindex @code{sub@var{m}3} instruction pattern
index 5111f06e8560af52b17f813f018341b799c7bb74..524da6731a9771b20aed1482798875238d5b8526 100644 (file)
@@ -180,10 +180,12 @@ extern void emit_libcall_block (rtx, rtx, rtx, rtx);
    Likewise for subtraction and for just copying.  */
 extern rtx gen_add2_insn (rtx, rtx);
 extern rtx gen_add3_insn (rtx, rtx, rtx);
+extern rtx gen_addptr3_insn (rtx, rtx, rtx);
 extern rtx gen_sub2_insn (rtx, rtx);
 extern rtx gen_sub3_insn (rtx, rtx, rtx);
 extern rtx gen_move_insn (rtx, rtx);
 extern int have_add2_insn (rtx, rtx);
+extern int have_addptr3_insn (rtx, rtx, rtx);
 extern int have_sub2_insn (rtx, rtx);
 
 /* Emit a pair of rtl insns to compare two rtx's and to jump
index 77074e296540da75550ff08b70a74db055bafc07..c1b92d8eee463e15542a5d889f4115fdb1bc8483 100644 (file)
--- a/gcc/lra.c
+++ b/gcc/lra.c
@@ -254,6 +254,19 @@ emit_add3_insn (rtx x, rtx y, rtx z)
   rtx insn, last;
 
   last = get_last_insn ();
+
+  if (have_addptr3_insn (x, y, z))
+    {
+      insn = gen_addptr3_insn (x, y, z);
+
+      /* If the target provides an "addptr" pattern it hopefully does
+        for a reason.  So falling back to the normal add would be
+        a bug.  */
+      lra_assert (insn != NULL_RTX);
+      emit_insn (insn);
+      return insn;
+    }
+
   insn = emit_insn (gen_rtx_SET (VOIDmode, x,
                                 gen_rtx_PLUS (GET_MODE (y), y, z)));
   if (recog_memoized (insn) < 0)
index cec25a443cec025c69a413010aa6b93e4c375b0f..c4540f8856ceff75b21e5617dbc4cad1aeec4848 100644 (file)
@@ -4755,6 +4755,43 @@ have_add2_insn (rtx x, rtx y)
   return 1;
 }
 
+/* Generate and return an insn body to add Y to X.  */
+
+rtx
+gen_addptr3_insn (rtx x, rtx y, rtx z)
+{
+  enum insn_code icode = optab_handler (addptr3_optab, GET_MODE (x));
+
+  gcc_assert (insn_operand_matches (icode, 0, x));
+  gcc_assert (insn_operand_matches (icode, 1, y));
+  gcc_assert (insn_operand_matches (icode, 2, z));
+
+  return GEN_FCN (icode) (x, y, z);
+}
+
+/* Return true if the target implements an addptr pattern and X, Y,
+   and Z are valid for the pattern predicates.  */
+
+int
+have_addptr3_insn (rtx x, rtx y, rtx z)
+{
+  enum insn_code icode;
+
+  gcc_assert (GET_MODE (x) != VOIDmode);
+
+  icode = optab_handler (addptr3_optab, GET_MODE (x));
+
+  if (icode == CODE_FOR_nothing)
+    return 0;
+
+  if (!insn_operand_matches (icode, 0, x)
+      || !insn_operand_matches (icode, 1, y)
+      || !insn_operand_matches (icode, 2, z))
+    return 0;
+
+  return 1;
+}
+
 /* Generate and return an insn body to subtract Y from X.  */
 
 rtx
index decdaf31fc5f3d53ca5abdf7dc083bd09942ab0a..9b8974080357a446878d0942444ef935ad71dbd5 100644 (file)
@@ -191,6 +191,7 @@ OPTAB_D (addv4_optab, "addv$I$a4")
 OPTAB_D (subv4_optab, "subv$I$a4")
 OPTAB_D (mulv4_optab, "mulv$I$a4")
 OPTAB_D (negv3_optab, "negv$I$a3")
+OPTAB_D (addptr3_optab, "addptr$a3")
 
 OPTAB_D (smul_highpart_optab, "smul$a3_highpart")
 OPTAB_D (umul_highpart_optab, "umul$a3_highpart")