[PATCH] Recognize sqrt(1.0/x) as rsqrt.d on MIPS4

Roger Sayle roger@eyesopen.com
Mon Aug 9 20:17:00 GMT 2004


I was recently reading through Peter Markstein's "IA-64 and Elementary
Functions" when I came across an interesting factlet on page 147, that
in IEEE 754 mathematics sqrt(1.0/x) is a better approximation to the
reciprocal square root of x than the more commonly found 1.0/sqrt(x).

As a result, I've been investigating the impact of switching between
these forms, aside from the difference when x is -0.0, which returns
NaN for the first form and -Inf for the second.

One target that seems to be affected is GCC's MIPS backend, which is
missing an "optimization" to recognize that sqrt(1.0/x) can be
implemented using the rsqrt.d instruction, and likewise sqrtf(1.0f/x)
using rsqrt.s when using -ffast-math.


One solution is for the GCC middle-end to choose one form or the other
as the canonical RTL representation of reciprocal square root when the
flag_unsafe_math_optimizations flag is set, and then always simplify
RTL to that form.  This requires updating all affected targets to ensure
that their patterns reflect the chosen canonical form.  An alternate
solution is to handle this in the backends themselves, and add peephole2s
to convert instruction sequences to the recognized form.

Finally, the really lazy solution is to add duplicate define_insn's to
the MIPS backend to match both reciprocal square root "RTL patterns".
This is shorter, independent of any decision on a canonical form in the
middle-end, doesn't adversely penalize one form vs. the other in passes
other than peephole2 and is easy to implement by someone not intimately
familiar with GCC's peephole2 machinery :>


The following patch has been tested on mips-sgi-irix6.5 with a full
"make bootstrap", all default languages except gfortran (due to
PR 15930), and regression tested with a top-level "make -k check"
with no new failures.

Ok for mainline?


2004-08-09  Roger Sayle  <roger@eyesopen.com>

	* config/mips/mips.md: New reciprocal square root patterns that
	match sqrt(1.0/x) in addition to the existing 1.0/sqrt(x) insns.


Index: config/mips/mips.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.md,v
retrieving revision 1.264
diff -c -3 -p -r1.264 mips.md
*** config/mips/mips.md	1 Aug 2004 11:30:39 -0000	1.264
--- config/mips/mips.md	9 Aug 2004 02:51:41 -0000
***************
*** 2203,2208 ****
--- 2203,2248 ----
          (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
                        (const_int 8)
                        (const_int 4)))])
+
+ ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
+ ;; "divdf3" comment for details).
+ (define_insn ""
+   [(set (match_operand:DF 0 "register_operand" "=f")
+ 	(sqrt:DF (div:DF (match_operand:DF 1 "const_float_1_operand" "")
+ 			 (match_operand:DF 2 "register_operand" "f"))))]
+   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
+ {
+   if (TARGET_FIX_SB1)
+     return "rsqrt.d\t%0,%2\;mov.d\t%0,%0";
+   else
+     return "rsqrt.d\t%0,%2";
+ }
+   [(set_attr "type"	"frsqrt")
+    (set_attr "mode"	"DF")
+    (set (attr "length")
+         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
+                       (const_int 8)
+                       (const_int 4)))])
+
+ ;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
+ ;; "divdf3" comment for details).
+ (define_insn ""
+   [(set (match_operand:SF 0 "register_operand" "=f")
+ 	(sqrt:SF (div:SF (match_operand:SF 1 "const_float_1_operand" "")
+ 			 (match_operand:SF 2 "register_operand" "f"))))]
+   "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
+ {
+   if (TARGET_FIX_SB1)
+     return "rsqrt.s\t%0,%2\;mov.s\t%0,%0";
+   else
+     return "rsqrt.s\t%0,%2";
+ }
+   [(set_attr "type"	"frsqrt")
+    (set_attr "mode"	"SF")
+    (set (attr "length")
+         (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
+                       (const_int 8)
+                       (const_int 4)))])

  ;;
  ;;  ....................


Roger
--
Roger Sayle,                         E-mail: roger@eyesopen.com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833



More information about the Gcc-patches mailing list