From 688e49197de88a4d7615eafd2b7691623a8424d1 Mon Sep 17 00:00:00 2001 From: Michael Meissner Date: Thu, 2 Sep 2010 17:10:15 +0000 Subject: [PATCH] Optimize (double)(long) to generate FRIZ if -ffast-math From-SVN: r163786 --- gcc/ChangeLog | 13 +++++++++++++ gcc/config/rs6000/rs6000.md | 12 ++++++++++++ gcc/config/rs6000/rs6000.opt | 7 ++++++- gcc/config/rs6000/vsx.md | 19 +++++++++++++++++++ gcc/doc/invoke.texi | 11 ++++++++++- gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/gcc.target/powerpc/ppc-fpconv-10.c | 11 +++++++++++ gcc/testsuite/gcc.target/powerpc/ppc-fpconv-11.c | 10 ++++++++++ 8 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/powerpc/ppc-fpconv-10.c create mode 100644 gcc/testsuite/gcc.target/powerpc/ppc-fpconv-11.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 474d62e..4062f95 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2010-09-02 Michael Meissner + + * 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_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. + 2010-09-02 Joseph Myers * opth-gen.awk (quote, comma): Remove unused variables. diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 5c68c3f..23fde85 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -6983,6 +6983,18 @@ "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 "lrintdi2" [(set (match_operand:DI 0 "gpc_reg_operand" "=d") diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt index 56d6888..659bcb6 100644 --- a/gcc/config/rs6000/rs6000.opt +++ b/gcc/config/rs6000/rs6000.opt @@ -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 . ; ; 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 diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md index c6a126bb..4b395e3 100644 --- a/gcc/config/rs6000/vsx.md +++ b/gcc/config/rs6000/vsx.md @@ -28,6 +28,9 @@ ;; 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 @@ "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_2" + [(set (match_operand:VSX_DF 0 "vsx_register_operand" "=,?wa") + (float:VSX_DF + (fix: + (match_operand:VSX_DF 1 "vsx_register_operand" ",?wa"))))] + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT + && VECTOR_UNIT_VSX_P (mode) && flag_unsafe_math_optimizations + && !flag_trapping_math && TARGET_FRIZ" + "xriz %x0,%x1" + [(set_attr "type" "") + (set_attr "fp_type" "")]) + ;; Logical and permute operations (define_insn "*vsx_and3" diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index cdd8d98..797a660 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -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{acosd2}, @code{acosf4}, 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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 83799c5..e947d3c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2010-09-02 Michael Meissner + + * 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. + 2010-09-02 Eric Botcazou * g++.dg/debug/dwarf2/nested-2.C: Allow for ! as comment delimiter. diff --git a/gcc/testsuite/gcc.target/powerpc/ppc-fpconv-10.c b/gcc/testsuite/gcc.target/powerpc/ppc-fpconv-10.c new file mode 100644 index 0000000..59ba5f9 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/ppc-fpconv-10.c @@ -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; +} diff --git a/gcc/testsuite/gcc.target/powerpc/ppc-fpconv-11.c b/gcc/testsuite/gcc.target/powerpc/ppc-fpconv-11.c new file mode 100644 index 0000000..f6d28cd --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/ppc-fpconv-11.c @@ -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; +} -- 2.7.4