re PR target/68609 (PowerPC reciprocal estimate missed opportunities)
authorDavid Edelsohn <dje.gcc@gmail.com>
Sat, 5 Dec 2015 12:53:45 +0000 (12:53 +0000)
committerDavid Edelsohn <dje@gcc.gnu.org>
Sat, 5 Dec 2015 12:53:45 +0000 (07:53 -0500)
        PR target/68609
        * config/rs6000/rs6000-protos.h (rs6000_emit_swsqrt): Rename and add
        bool arguement.
        * config/rs6000/rs6000.c (rs6000_emit_swsqrt): Rename. Add
        non-reciporcal path.
        * config/rs6000/rs6000.md (rsqrt<mode>2): Call new function name.
        (sqrt<mode>2): Replace define_insn with define_expand that may call
        rs6000_emit_swsqrt.

From-SVN: r231317

gcc/ChangeLog
gcc/config/rs6000/rs6000-protos.h
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.md

index 0ad4e901e1c427318c25dcfce44629a6c8315c2a..0d4e6f2decf0ed8ddbe612c1b37a880a9f043194 100644 (file)
@@ -1,3 +1,14 @@
+2015-12-05  David Edelsohn  <dje.gcc@gmail.com>
+
+       PR target/68609
+       * config/rs6000/rs6000-protos.h (rs6000_emit_swsqrt): Rename and add
+       bool arguement.
+       * config/rs6000/rs6000.c (rs6000_emit_swsqrt): Rename. Add
+       non-reciporcal path.
+       * config/rs6000/rs6000.md (rsqrt<mode>2): Call new function name.
+       (sqrt<mode>2): Replace define_insn with define_expand that may call
+       rs6000_emit_swsqrt.
+       
 2015-12-04  Aditya Kumar  <aditya.k7@samsung.com>
            Sebastian Pop  <s.pop@samsung.com>
 
index 050076547870c162a02db5d4e68950f5b8be894c..d9c7a79af3955e8a8beb651460ea73031b6eb849 100644 (file)
@@ -137,7 +137,7 @@ extern void rs6000_expand_atomic_compare_and_swap (rtx op[]);
 extern void rs6000_expand_atomic_exchange (rtx op[]);
 extern void rs6000_expand_atomic_op (enum rtx_code, rtx, rtx, rtx, rtx, rtx);
 extern void rs6000_emit_swdiv (rtx, rtx, rtx, bool);
-extern void rs6000_emit_swrsqrt (rtx, rtx);
+extern void rs6000_emit_swsqrt (rtx, rtx, bool);
 extern void output_toc (FILE *, rtx, int, machine_mode);
 extern rtx rs6000_longcall_ref (rtx);
 extern void rs6000_fatal_bad_address (rtx);
index 2b2c170d6e9c936a344c4aef0ce2d0e3761a3e0f..6b22f93e0ffbd053b1b85e4b4345e642543fad7c 100644 (file)
@@ -32910,7 +32910,7 @@ rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p)
    rsqrt.  Assumes no trapping math and finite arguments.  */
 
 void
-rs6000_emit_swrsqrt (rtx dst, rtx src)
+rs6000_emit_swsqrt (rtx dst, rtx src, bool recip)
 {
   machine_mode mode = GET_MODE (src);
   rtx x0 = gen_reg_rtx (mode);
@@ -32943,6 +32943,16 @@ rs6000_emit_swrsqrt (rtx dst, rtx src)
   emit_insn (gen_rtx_SET (x0, gen_rtx_UNSPEC (mode, gen_rtvec (1, src),
                                              UNSPEC_RSQRT)));
 
+  /* If (src == 0.0) filter infinity to prevent NaN for sqrt(0.0).  */
+  if (!recip)
+    {
+      rtx zero = force_reg (mode, CONST0_RTX (mode));
+      rtx target = emit_conditional_move (x0, GT, src, zero, mode,
+                                         x0, zero, mode, 0);
+      if (target != x0)
+       emit_move_insn (x0, target);
+    }
+
   /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
   rs6000_emit_msub (y, src, halfthree, src);
 
@@ -32959,7 +32969,12 @@ rs6000_emit_swrsqrt (rtx dst, rtx src)
       x0 = x1;
     }
 
-  emit_move_insn (dst, x0);
+  /* If not reciprocal, multiply by src to produce sqrt.  */
+  if (!recip)
+    emit_insn (gen_mul (dst, src, x0));
+  else
+    emit_move_insn (dst, x0);
+
   return;
 }
 
index 39e1b299a72e89b2abb4d52a084ed07d6ed48cfe..66a62ef41863e3ddd316368dc355138ec4661d59 100644 (file)
    (match_operand:RECIPF 1 "gpc_reg_operand" "")]
   "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
 {
-  rs6000_emit_swrsqrt (operands[0], operands[1]);
+  rs6000_emit_swsqrt (operands[0], operands[1], 1);
   DONE;
 })
 \f
   [(set_attr "type" "<Fs>div")
    (set_attr "fp_type" "fp_div_<Fs>")])
 
-(define_insn "sqrt<mode>2"
+(define_insn "*sqrt<mode>2_internal"
   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
        (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
   "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
   [(set_attr "type" "<Fs>sqrt")
    (set_attr "fp_type" "fp_sqrt_<Fs>")])
 
+(define_expand "sqrt<mode>2"
+  [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
+       (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
+  "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
+   && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
+{
+  if (<MODE>mode == SFmode
+      && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
+      && !optimize_function_for_size_p (cfun)
+      && flag_finite_math_only && !flag_trapping_math
+      && flag_unsafe_math_optimizations)
+    {
+      rs6000_emit_swsqrt (operands[0], operands[1], 0);
+      DONE;
+    }
+})
+
 ;; Floating point reciprocal approximation
 (define_insn "fre<Fs>"
   [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")