From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 9618 invoked by alias); 11 Mar 2013 00:52:42 -0000 Received: (qmail 9610 invoked by uid 22791); 11 Mar 2013 00:52:41 -0000 X-SWARE-Spam-Status: No, hits=-2.5 required=5.0 tests=AWL,BAYES_00,KHOP_THREADED,MSGID_FROM_MTA_HEADER,RCVD_IN_DNSWL_NONE,RCVD_IN_HOSTKARMA_YE X-Spam-Check-By: sourceware.org Received: from blu0-omc1-s15.blu0.hotmail.com (HELO blu0-omc1-s15.blu0.hotmail.com) (65.55.116.26) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 11 Mar 2013 00:52:34 +0000 Received: from BLU0-SMTP76 ([65.55.116.9]) by blu0-omc1-s15.blu0.hotmail.com with Microsoft SMTPSVC(6.0.3790.4675); Sun, 10 Mar 2013 17:52:34 -0700 X-EIP: [hqPp/+uEAp8yRnTwPd33DEhxwklUkqmt] Message-ID: Received: from [192.168.2.10] ([69.158.172.5]) by BLU0-SMTP76.phx.gbl over TLS secured channel with Microsoft SMTPSVC(6.0.3790.4675); Sun, 10 Mar 2013 17:52:32 -0700 CC: gcc-patches@gcc.gnu.org From: John David Anglin To: dave.anglin@bell.net, John David Anglin In-Reply-To: <20130218164557.GA2332@hiauly1.hia.nrc.ca> Content-Type: multipart/mixed; boundary="Apple-Mail-10-256340949" Subject: Re: [committed] Work around bug in powf function on HP-UX MIME-Version: 1.0 (Apple Message framework v936) Date: Mon, 11 Mar 2013 00:52:00 -0000 References: <20130218164557.GA2332@hiauly1.hia.nrc.ca> Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2013-03/txt/msg00388.txt.bz2 --Apple-Mail-10-256340949 Content-Type: text/plain; charset="US-ASCII"; format=flowed; delsp=yes Content-Transfer-Encoding: 7bit Content-length: 701 On 18-Feb-13, at 11:45 AM, John David Anglin wrote: > 2013-02-18 John David Anglin > > PR target/56347 > * config/pa/pa.c (pa_conditional_register_usage): On HP-UX, mark > registers %fr12 and %fr12R as call used. I committed the attached change. It no longer unconditionally clobbers %fr12 and %fr12R and instead uses special call patterns that clobber %fr12 to work around the problem. It is not perfect in that only direct calls are detected, but I think that is the best compromise. Tested on hppa2.0w-hp-hpux11.11 and hppa64-hp-hpux11.11. Build tested on hppa-unknown-linux-gnu. Committed to trunk. Dave -- John David Anglin dave.anglin@bell.net --Apple-Mail-10-256340949 Content-Disposition: attachment; filename="pa-powf.d.5.txt" Content-Type: text/plain; x-unix-mode=0644; name="pa-powf.d.5.txt" Content-Transfer-Encoding: 7bit Content-length: 10362 2013-03-10 John David Anglin 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. Index: config/pa/pa.md =================================================================== --- config/pa/pa.md (revision 196546) +++ config/pa/pa.md (working copy) @@ -7600,7 +7600,6 @@ (match_operand 2 "" ""))) (clobber (reg:SI 2))])] "" - " { rtx op; rtx dst = operands[0]; @@ -7668,7 +7667,13 @@ { 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 @@ 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 @@ } DONE; -}") +}) (define_insn "call_val_symref" [(set (match_operand 0 "" "") @@ -7722,6 +7740,26 @@ (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 @@ (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 @@ (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)) Index: config/pa/pa.c =================================================================== --- config/pa/pa.c (revision 196546) +++ config/pa/pa.c (working copy) @@ -10313,21 +10313,6 @@ { 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++) --Apple-Mail-10-256340949--