Patchwork [powerpc] Generate FRIZ for (double)(long) under -ffast-math on powerpc

login
register
mail settings
Submitter Michael Meissner
Date Sept. 1, 2010, 3:24 p.m.
Message ID <20100901152456.GA5449@hungry-tiger.westford.ibm.com>
Download mbox | patch
Permalink /patch/63384/
State New
Headers show

Comments

Michael Meissner - Sept. 1, 2010, 3:24 p.m.
This patch optimizes (double)(long) operations to generate a single FRIZ round
instruction, instead of the convert to 64-bit integer and back.  It is only
done under -ffast-math because the FRIZ instruction generates a different
answer if the value is larger or smaller than will fit in a 64-bit integer
value.  I added a -mno-friz/-mfriz option to control whether this is generated
or not.

I did a bootstrap and make check yeilded no regressions.  Is this ok to install
in the tree?

[gcc]
2010-08-31  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* config/rs6000/rs6000.opt (-mfriz): New switch to control whether
	to convert (double)(long) into a single FRIZ instruction or not
	when -ffast-math is used.

	* config/rs6000/vsx.md (VSX_DF): New iterator for DF/V2DF modes.
	(vsx_float_fix_<mode>2): Optimize (double)(long) into X{S,V}RDPIZ
	or FRIZ instruction if -ffast-math.
	* config/rs6000/rs6000.md (friz): Ditto.

	* doc/invoke.texi (RS/6000 and PowerPC Options): Document -mfriz.

[gcc/testsuite]
2010-08-31  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* gcc.target/powerpc/ppc-fpconv-10.c: New file to test generating
	FRIZ/XSRIZ instruciton for (double)(long long)x.
	* gcc.target/powerpc/ppc-fpconv-11.c: Ditto.
David Edelsohn - Sept. 1, 2010, 11:37 p.m.
On Wed, Sep 1, 2010 at 11:24 AM, Michael Meissner
<meissner@linux.vnet.ibm.com> wrote:
> This patch optimizes (double)(long) operations to generate a single FRIZ round
> instruction, instead of the convert to 64-bit integer and back.  It is only
> done under -ffast-math because the FRIZ instruction generates a different
> answer if the value is larger or smaller than will fit in a 64-bit integer
> value.  I added a -mno-friz/-mfriz option to control whether this is generated
> or not.
>
> I did a bootstrap and make check yeilded no regressions.  Is this ok to install
> in the tree?
>
> [gcc]
> 2010-08-31  Michael Meissner  <meissner@linux.vnet.ibm.com>
>
>        * config/rs6000/rs6000.opt (-mfriz): New switch to control whether
>        to convert (double)(long) into a single FRIZ instruction or not
>        when -ffast-math is used.
>
>        * config/rs6000/vsx.md (VSX_DF): New iterator for DF/V2DF modes.
>        (vsx_float_fix_<mode>2): Optimize (double)(long) into X{S,V}RDPIZ
>        or FRIZ instruction if -ffast-math.
>        * config/rs6000/rs6000.md (friz): Ditto.
>
>        * doc/invoke.texi (RS/6000 and PowerPC Options): Document -mfriz.
>
> [gcc/testsuite]
> 2010-08-31  Michael Meissner  <meissner@linux.vnet.ibm.com>
>
>        * gcc.target/powerpc/ppc-fpconv-10.c: New file to test generating
>        FRIZ/XSRIZ instruciton for (double)(long long)x.
>        * gcc.target/powerpc/ppc-fpconv-11.c: Ditto.

Okay.

Thanks, David

Patch

Index: gcc/config/rs6000/rs6000.opt
===================================================================
--- gcc/config/rs6000/rs6000.opt	(revision 163697)
+++ gcc/config/rs6000/rs6000.opt	(working copy)
@@ -1,6 +1,7 @@ 
 ; Options for the rs6000 port of the compiler
 ;
-; Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+; Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
+; Foundation, Inc.
 ; Contributed by Aldy Hernandez <aldy@quesejoda.com>.
 ;
 ; This file is part of GCC.
@@ -115,6 +116,10 @@  mpopcntd
 Target Report Mask(POPCNTD)
 Use PowerPC V2.06 popcntd instruction
 
+mfriz
+Target Report Var(TARGET_FRIZ) Init(-1)
+Under -ffast-math, generate a FRIZ instruction for (double)(long long) conversions
+
 mveclibabi=
 Target RejectNegative Joined Var(rs6000_veclibabi_name)
 Vector library ABI to use
Index: gcc/config/rs6000/vsx.md
===================================================================
--- gcc/config/rs6000/vsx.md	(revision 163697)
+++ gcc/config/rs6000/vsx.md	(working copy)
@@ -28,6 +28,9 @@  (define_mode_iterator VSX_D [V2DF V2DI])
 ;; Iterator for the 2 32-bit vector types
 (define_mode_iterator VSX_W [V4SF V4SI])
 
+;; Iterator for the DF types
+(define_mode_iterator VSX_DF [V2DF DF])
+
 ;; Iterator for vector floating point types supported by VSX
 (define_mode_iterator VSX_F [V4SF V2DF])
 
@@ -1053,6 +1056,22 @@  (define_insn "vsx_xvcvspuxds"
   "VECTOR_UNIT_VSX_P (V2DFmode)"
   "xvcvspuxds %x0,%x1"
   [(set_attr "type" "vecfloat")])
+
+;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
+;; since the xsrdpiz instruction does not truncate the value if the floating
+;; point value is < LONG_MIN or > LONG_MAX.
+(define_insn "*vsx_float_fix_<mode>2"
+  [(set (match_operand:VSX_DF 0 "vsx_register_operand" "=<VSr>,?wa")
+	(float:VSX_DF
+	 (fix:<VSI>
+	  (match_operand:VSX_DF 1 "vsx_register_operand" "<VSr>,?wa"))))]
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
+   && VECTOR_UNIT_VSX_P (<MODE>mode) && flag_unsafe_math_optimizations
+   && !flag_trapping_math && TARGET_FRIZ"
+  "x<VSv>r<VSs>iz %x0,%x1"
+  [(set_attr "type" "<VStype_simple>")
+   (set_attr "fp_type" "<VSfptype_simple>")])
+
 
 ;; Logical and permute operations
 (define_insn "*vsx_and<mode>3"
Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md	(revision 163697)
+++ gcc/config/rs6000/rs6000.md	(working copy)
@@ -6983,6 +6983,18 @@  (define_insn "fctiwuz_<mode>"
   "fctiwuz %0,%1"
   [(set_attr "type" "fp")])
 
+;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
+;; since the friz instruction does not truncate the value if the floating
+;; point value is < LONG_MIN or > LONG_MAX.
+(define_insn "*friz"
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
+	(float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d"))))]
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_POPCNTB
+   && !VECTOR_UNIT_VSX_P (DFmode) && flag_unsafe_math_optimizations
+   && !flag_trapping_math && TARGET_FRIZ"
+  "friz %0,%1"
+  [(set_attr "type" "fp")])
+
 ;; No VSX equivalent to fctid
 (define_insn "lrint<mode>di2"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
Index: gcc/testsuite/gcc.target/powerpc/ppc-fpconv-11.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/ppc-fpconv-11.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/ppc-fpconv-11.c	(revision 0)
@@ -0,0 +1,10 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-options "-O2 -mcpu=power5 -ffast-math" } */
+/* { dg-final { scan-assembler-not "xsrdpiz" } } */
+/* { dg-final { scan-assembler "friz" } } */
+
+double round_double_llong (double a)
+{
+  return (double)(long long)a;
+}
Index: gcc/testsuite/gcc.target/powerpc/ppc-fpconv-10.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/ppc-fpconv-10.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/ppc-fpconv-10.c	(revision 0)
@@ -0,0 +1,11 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-O2 -mcpu=power7 -ffast-math" } */
+/* { dg-final { scan-assembler "xsrdpiz" } } */
+/* { dg-final { scan-assembler-not "friz" } } */
+
+double round_double_llong (double a)
+{
+  return (double)(long long)a;
+}
Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi	(revision 163697)
+++ gcc/doc/invoke.texi	(working copy)
@@ -789,7 +789,7 @@  See RS/6000 and PowerPC Options.
 -msdata=@var{opt}  -mvxworks  -G @var{num}  -pthread @gol
 -mrecip -mrecip=@var{opt} -mno-recip -mrecip-precision
 -mno-recip-precision @gol
--mveclibabi=@var{type}}
+-mveclibabi=@var{type} -mfriz -mno-friz}
 
 @emph{RX Options}
 @gccoptlist{-m64bit-doubles  -m32bit-doubles  -fpu  -nofpu@gol
@@ -15931,6 +15931,15 @@  GCC will currently emit calls to @code{a
 for power7.  Both @option{-ftree-vectorize} and
 @option{-funsafe-math-optimizations} have to be enabled.  The MASS
 libraries will have to be specified at link time.
+
+@item -mfriz
+@itemx -mno-friz
+@opindex mfriz
+Generate (do not generate) the @code{friz} instruction when the
+@option{-funsafe-math-optimizations} option is used to optimize
+rounding a floating point value to 64-bit integer and back to floating
+point.  The @code{friz} instruction does not return the same value if
+the floating point number is too large to fit in an integer.
 @end table
 
 @node RX Options