]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/56347 (FAIL: gfortran.dg/integer_exponentiation_2.f90 -O2 execution...
authorJohn David Anglin <dave.anglin@nrc-cnrc.gc.ca>
Mon, 11 Mar 2013 00:44:28 +0000 (00:44 +0000)
committerJohn David Anglin <danglin@gcc.gnu.org>
Mon, 11 Mar 2013 00:44:28 +0000 (00:44 +0000)
PR target/56347
* config/pa/pa.md (call_value): Check for calls to powf and direct to
new call patterns that clobber %fr12.
(call_val_powf, call_val_powf_pic, call_val_powf_64bit): New insn,
split and postreload patterns.
* config/pa/pa.c (pa_conditional_register_usage): Revert marking
registers %fr12 and %fr12R as call used.

From-SVN: r196588

gcc/ChangeLog
gcc/config/pa/pa.c
gcc/config/pa/pa.md

index f318a80f0845dcabd0f29247b3e21a51af2877f6..a3469f47b07aaf2e11f1ec3e8fd51182d7314b63 100644 (file)
@@ -1,3 +1,13 @@
+2013-03-10  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
+
+       PR target/56347
+       * config/pa/pa.md (call_value): Check for calls to powf and direct to
+       new call patterns that clobber %fr12.
+       (call_val_powf, call_val_powf_pic, call_val_powf_64bit): New insn,
+       split and postreload patterns.
+       * config/pa/pa.c (pa_conditional_register_usage): Revert marking
+       registers %fr12 and %fr12R as call used.
+
 2013-03-09  Steven Bosscher  <steven@gcc.gnu.org>
 
        * dse.c (delete_dead_store_insn): Respect TDF_DETAILS.
index 7816eeb54e4ba59c115b717d231021206501a0a1..0d39483d908ec1250e97f6833891ac7e46da1886 100644 (file)
@@ -10313,21 +10313,6 @@ pa_conditional_register_usage (void)
 {
   int i;
 
-  if (TARGET_HPUX)
-    {
-      /* Work around powf bug in libm.  */
-      if (TARGET_64BIT)
-       {
-         /* Mark %fr12 as call used.  */
-         call_used_regs[40] = 1;
-       }
-      else
-       {
-         /* Mark %fr12 and %fr12R as call used.  */
-         call_used_regs[48] = 1;
-         call_used_regs[49] = 1;
-       }
-    }
   if (!TARGET_64BIT && !TARGET_PA_11)
     {
       for (i = 56; i <= FP_REG_LAST; i++)
index d5696e908e080e0a876519e36a2c6a6dd416459b..5e6d5652e71c4bd4fb69af93c6d2c42d5a540c1f 100644 (file)
@@ -7600,7 +7600,6 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
                         (match_operand 2 "" "")))
              (clobber (reg:SI 2))])]
   ""
-  "
 {
   rtx op;
   rtx dst = operands[0];
@@ -7668,7 +7667,13 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
     {
       rtx r4 = gen_rtx_REG (word_mode, 4);
       if (GET_CODE (op) == SYMBOL_REF)
-         emit_call_insn (gen_call_val_symref_64bit (dst, op, nb, r4));
+       {
+         if (TARGET_HPUX && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT
+             && !strcmp (targetm.strip_name_encoding (XSTR (op, 0)), "powf"))
+           emit_call_insn (gen_call_val_powf_64bit (dst, op, nb, r4));
+         else
+           emit_call_insn (gen_call_val_symref_64bit (dst, op, nb, r4));
+       }
       else
        {
          op = force_reg (word_mode, op);
@@ -7682,10 +7687,23 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
          if (flag_pic)
            {
              rtx r4 = gen_rtx_REG (word_mode, 4);
-             emit_call_insn (gen_call_val_symref_pic (dst, op, nb, r4));
+
+             if (TARGET_HPUX && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT
+                 && !strcmp (targetm.strip_name_encoding (XSTR (op, 0)),
+                             "powf"))
+               emit_call_insn (gen_call_val_powf_pic (dst, op, nb, r4));
+             else
+               emit_call_insn (gen_call_val_symref_pic (dst, op, nb, r4));
            }
          else
-           emit_call_insn (gen_call_val_symref (dst, op, nb));
+           {
+             if (TARGET_HPUX && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT
+                 && !strcmp (targetm.strip_name_encoding (XSTR (op, 0)),
+                             "powf"))
+               emit_call_insn (gen_call_val_powf (dst, op, nb));
+             else
+               emit_call_insn (gen_call_val_symref (dst, op, nb));
+           }
        }
       else
        {
@@ -7702,7 +7720,7 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
     }
 
   DONE;
-}")
+})
 
 (define_insn "call_val_symref"
   [(set (match_operand 0 "" "")
@@ -7722,6 +7740,26 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
        (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
              (symbol_ref "pa_attr_length_call (insn, 0)")))])
 
+;; powf function clobbers %fr12
+(define_insn "call_val_powf"
+  [(set (match_operand 0 "" "")
+       (call (mem:SI (match_operand 1 "call_operand_address" ""))
+             (match_operand 2 "" "i")))
+   (clobber (reg:SI 1))
+   (clobber (reg:SI 2))
+   (clobber (reg:DF 48))
+   (use (const_int 1))]
+  "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
+  "*
+{
+  pa_output_arg_descriptor (insn);
+  return pa_output_call (insn, operands[1], 0);
+}"
+  [(set_attr "type" "call")
+   (set (attr "length")
+       (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
+             (symbol_ref "pa_attr_length_call (insn, 0)")))])
+
 (define_insn "call_val_symref_pic"
   [(set (match_operand 0 "" "")
        (call (mem:SI (match_operand 1 "call_operand_address" ""))
@@ -7804,6 +7842,95 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
        (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
              (symbol_ref "pa_attr_length_call (insn, 0)")))])
 
+;; powf function clobbers %fr12
+(define_insn "call_val_powf_pic"
+  [(set (match_operand 0 "" "")
+       (call (mem:SI (match_operand 1 "call_operand_address" ""))
+             (match_operand 2 "" "i")))
+   (clobber (reg:SI 1))
+   (clobber (reg:SI 2))
+   (clobber (reg:DF 48))
+   (clobber (match_operand 3))
+   (use (reg:SI 19))
+   (use (const_int 1))]
+  "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
+  "#")
+
+;; Split out the PIC register save and restore after reload.  As the
+;; split is done after reload, there are some situations in which we
+;; unnecessarily save and restore %r4.  This happens when there is a
+;; single call and the PIC register is not used after the call.
+;;
+;; The split has to be done since call_from_call_insn () can't handle
+;; the pattern as is.  Noreturn calls are special because they have to
+;; terminate the basic block.  The split has to contain more than one
+;; insn.
+(define_split
+  [(parallel [(set (match_operand 0 "" "")
+             (call (mem:SI (match_operand 1 "call_operand_address" ""))
+                   (match_operand 2 "" "")))
+             (clobber (reg:SI 1))
+             (clobber (reg:SI 2))
+             (clobber (reg:DF 48))
+             (clobber (match_operand 3))
+             (use (reg:SI 19))
+             (use (const_int 1))])]
+  "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed
+   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
+  [(set (match_dup 3) (reg:SI 19))
+   (parallel [(set (match_dup 0)
+             (call (mem:SI (match_dup 1))
+                   (match_dup 2)))
+             (clobber (reg:SI 1))
+             (clobber (reg:SI 2))
+             (clobber (reg:DF 48))
+             (use (reg:SI 19))
+             (use (const_int 1))])]
+  "")
+
+(define_split
+  [(parallel [(set (match_operand 0 "" "")
+             (call (mem:SI (match_operand 1 "call_operand_address" ""))
+                   (match_operand 2 "" "")))
+             (clobber (reg:SI 1))
+             (clobber (reg:SI 2))
+             (clobber (reg:DF 48))
+             (clobber (match_operand 3))
+             (use (reg:SI 19))
+             (use (const_int 1))])]
+  "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
+  [(set (match_dup 3) (reg:SI 19))
+   (parallel [(set (match_dup 0)
+             (call (mem:SI (match_dup 1))
+                   (match_dup 2)))
+             (clobber (reg:SI 1))
+             (clobber (reg:SI 2))
+             (clobber (reg:DF 48))
+             (use (reg:SI 19))
+             (use (const_int 1))])
+   (set (reg:SI 19) (match_dup 3))]
+  "")
+
+(define_insn "*call_val_powf_pic_post_reload"
+  [(set (match_operand 0 "" "")
+       (call (mem:SI (match_operand 1 "call_operand_address" ""))
+             (match_operand 2 "" "i")))
+   (clobber (reg:SI 1))
+   (clobber (reg:SI 2))
+   (clobber (reg:DF 48))
+   (use (reg:SI 19))
+   (use (const_int 1))]
+  "TARGET_HPUX && !TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
+  "*
+{
+  pa_output_arg_descriptor (insn);
+  return pa_output_call (insn, operands[1], 0);
+}"
+  [(set_attr "type" "call")
+   (set (attr "length")
+       (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
+             (symbol_ref "pa_attr_length_call (insn, 0)")))])
+
 ;; This pattern is split if it is necessary to save and restore the
 ;; PIC register.
 (define_insn "call_val_symref_64bit"
@@ -7894,6 +8021,101 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
        (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
              (symbol_ref "pa_attr_length_call (insn, 0)")))])
 
+;; powf function clobbers %fr12
+(define_insn "call_val_powf_64bit"
+  [(set (match_operand 0 "" "")
+       (call (mem:SI (match_operand 1 "call_operand_address" ""))
+             (match_operand 2 "" "i")))
+   (clobber (reg:DI 1))
+   (clobber (reg:DI 2))
+   (clobber (reg:DF 40))
+   (clobber (match_operand 3))
+   (use (reg:DI 27))
+   (use (reg:DI 29))
+   (use (const_int 1))]
+  "TARGET_64BIT && TARGET_HPUX"
+  "#")
+
+;; Split out the PIC register save and restore after reload.  As the
+;; split is done after reload, there are some situations in which we
+;; unnecessarily save and restore %r4.  This happens when there is a
+;; single call and the PIC register is not used after the call.
+;;
+;; The split has to be done since call_from_call_insn () can't handle
+;; the pattern as is.  Noreturn calls are special because they have to
+;; terminate the basic block.  The split has to contain more than one
+;; insn.
+(define_split
+  [(parallel [(set (match_operand 0 "" "")
+             (call (mem:SI (match_operand 1 "call_operand_address" ""))
+                   (match_operand 2 "" "")))
+             (clobber (reg:DI 1))
+             (clobber (reg:DI 2))
+             (clobber (reg:DF 40))
+             (clobber (match_operand 3))
+             (use (reg:DI 27))
+             (use (reg:DI 29))
+             (use (const_int 1))])]
+  "TARGET_64BIT && TARGET_HPUX && reload_completed
+   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
+  [(set (match_dup 3) (reg:DI 27))
+   (parallel [(set (match_dup 0)
+             (call (mem:SI (match_dup 1))
+                   (match_dup 2)))
+             (clobber (reg:DI 1))
+             (clobber (reg:DI 2))
+             (clobber (reg:DF 40))
+             (use (reg:DI 27))
+             (use (reg:DI 29))
+             (use (const_int 1))])]
+  "")
+
+(define_split
+  [(parallel [(set (match_operand 0 "" "")
+             (call (mem:SI (match_operand 1 "call_operand_address" ""))
+                   (match_operand 2 "" "")))
+             (clobber (reg:DI 1))
+             (clobber (reg:DI 2))
+             (clobber (reg:DF 40))
+             (clobber (match_operand 3))
+             (use (reg:DI 27))
+             (use (reg:DI 29))
+             (use (const_int 1))])]
+  "TARGET_64BIT && TARGET_HPUX && reload_completed"
+  [(set (match_dup 3) (reg:DI 27))
+   (parallel [(set (match_dup 0)
+             (call (mem:SI (match_dup 1))
+                   (match_dup 2)))
+             (clobber (reg:DI 1))
+             (clobber (reg:DI 2))
+             (clobber (reg:DF 40))
+             (use (reg:DI 27))
+             (use (reg:DI 29))
+             (use (const_int 1))])
+   (set (reg:DI 27) (match_dup 3))]
+  "")
+
+(define_insn "*call_val_powf_64bit_post_reload"
+  [(set (match_operand 0 "" "")
+       (call (mem:SI (match_operand 1 "call_operand_address" ""))
+             (match_operand 2 "" "i")))
+   (clobber (reg:DI 1))
+   (clobber (reg:DI 2))
+   (clobber (reg:DF 40))
+   (use (reg:DI 27))
+   (use (reg:DI 29))
+   (use (const_int 1))]
+  "TARGET_64BIT && TARGET_HPUX"
+  "*
+{
+  pa_output_arg_descriptor (insn);
+  return pa_output_call (insn, operands[1], 0);
+}"
+  [(set_attr "type" "call")
+   (set (attr "length")
+       (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
+             (symbol_ref "pa_attr_length_call (insn, 0)")))])
+
 (define_insn "call_val_reg"
   [(set (match_operand 0 "" "")
        (call (mem:SI (reg:SI 22))