diff mbox

[1/N,ia64] -mfused-madd cleanup

Message ID 4CDB246D.9060306@redhat.com
State New
Headers show

Commit Message

Richard Henderson Nov. 10, 2010, 11:02 p.m. UTC
This patch begins the elimination of -mfused-madd in favor of -ffp-contract,
and converts the ia64 backend.  A common option file is introduced that will
be used by the other targets as they are converted.  A warning is generated
deprecating the old option name.

As for the ia64 changes, the non-fma patterns are eliminated, fnma<mode>4
is properly named, and V2SFmode is fixed up to use the FMA code.

Ok?


r~
From a2898b4fde42fcb7b078368eabbb3c1191ef52c6 Mon Sep 17 00:00:00 2001
From: Richard Henderson <rth@twiddle.net>
Date: Tue, 9 Nov 2010 12:25:53 -0800
Subject: [PATCH 1/3] ia64: move -mfused-madd to -ffp-contract.

Delete all patterns dependent on TARGET_FUSED_MADD; instead rely
on gimple optimizations producing FMA_EXPR.  Fixup naming of the
fnma<mode>4 patterns.  Fixup vector patterns to use FMA.
---
 gcc/config.gcc                                     |    2 +-
 gcc/config/fused-madd.opt                          |   25 +++
 gcc/config/ia64/hpux.h                             |    2 +-
 gcc/config/ia64/ia64.h                             |    2 +-
 gcc/config/ia64/ia64.md                            |  192 +-------------------
 gcc/config/ia64/ia64.opt                           |    4 -
 gcc/config/ia64/vect.md                            |  122 +++----------
 gcc/config/ia64/vms.h                              |    2 +-
 gcc/config/ia64/vms64.h                            |    2 +-
 .../gcc.target/ia64/mno-fused-madd-vect.c          |    2 +-
 gcc/testsuite/gcc.target/ia64/mno-fused-madd.c     |    2 +-
 11 files changed, 60 insertions(+), 297 deletions(-)
 create mode 100644 gcc/config/fused-madd.opt

Comments

Steve Ellcey Nov. 10, 2010, 11:24 p.m. UTC | #1
Do you know if getting rid of rules like this one will affect the code:

-(define_insn "*madddf4_trunc"
-  [(set (match_operand:SF 0 "fr_register_operand" "=f")
-       (float_truncate:SF
-         (plus:DF (mult:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
-                           (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))
-                  (match_operand:DF 3 "fr_reg_or_signed_fp01_operand" "fZ"))))]
-  "TARGET_FUSED_MADD"
-  "fma.s %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])


I am wondering if relying on FMA_EXPR will change the generated code for
"float x = (float) a * b + c" where a, b, and c are doubles.  Will we
generate an fma followed by an fnorm truncation instead of just a fma.s.

I'll put your patch in my nightly testing and see how it goes but other
then the above question I think it looks good.

Steve Ellcey
sje@cup.hp.com
Richard Henderson Nov. 10, 2010, 11:50 p.m. UTC | #2
On 11/10/2010 03:24 PM, Steve Ellcey wrote:
> I am wondering if relying on FMA_EXPR will change the generated code for
> "float x = (float) a * b + c" where a, b, and c are doubles.  Will we
> generate an fma followed by an fnorm truncation instead of just a fma.s.
> 
> I'll put your patch in my nightly testing and see how it goes but other
> then the above question I think it looks good.

Yeah, I wasn't quite sure what to do with those right away.

I'm pretty sure that the actual fma.d instruction is

  (fma:DF (reg:XF a) (reg:XF b) (reg:XF c))

by which I mean XFmode inputs to the infinite precision FMA
with a single rounding to DFmode at the end.

However, that's not something that the user can ever write.
The best we can do from source code is

  (float_trunc:DF (fma:XF (reg:XF a) (reg:XF b) (reg:XF c))

meaning a rounding from infinite precision to XFmode (80 bits) followed
by a second rounding to DFmode (53 bits).  We can obviously do this with
unsafe-math, but not otherwise.

OTOH, truncation to SFmode is, I think, safe all of the time since the
intermediate form of DF or XFmode has more than twice the precision of
the final result, and so the (lack of) double rounding ought not be visible.

Does that seem correct?


r~
Jakub Jelinek Nov. 11, 2010, 12:04 a.m. UTC | #3
On Wed, Nov 10, 2010 at 03:50:55PM -0800, Richard Henderson wrote:
> On 11/10/2010 03:24 PM, Steve Ellcey wrote:
> OTOH, truncation to SFmode is, I think, safe all of the time since the
> intermediate form of DF or XFmode has more than twice the precision of
> the final result, and so the (lack of) double rounding ought not be visible.

No, double rounding is a problem even if the precision is twice as large.
It is fairly easy to construct testcases.  So I think it would need to be an
unsafe math opt too...

	Jakub
diff mbox

Patch

diff --git a/gcc/config.gcc b/gcc/config.gcc
index c31373e..6a6e47d 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -333,7 +333,7 @@  x86_64-*-*)
 ia64-*-*)
 	extra_headers=ia64intrin.h
 	need_64bit_hwint=yes
-	extra_options="${extra_options} g.opt"
+	extra_options="${extra_options} g.opt fused-madd.opt"
 	;;
 hppa*-*-*)
 	cpu_type=pa
diff --git a/gcc/config/fused-madd.opt b/gcc/config/fused-madd.opt
new file mode 100644
index 0000000..b1214cb
--- /dev/null
+++ b/gcc/config/fused-madd.opt
@@ -0,0 +1,25 @@ 
+; -mfused-madd option (some targets only).
+;
+; Copyright (C) 2010
+; Free Software Foundation, Inc.
+;
+; This file is part of GCC.
+;
+; GCC is free software; you can redistribute it and/or modify it under
+; the terms of the GNU General Public License as published by the Free
+; Software Foundation; either version 3, or (at your option) any later
+; version.
+;
+; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+; WARRANTY; without even the implied warranty of MERCHANTABILITY or
+; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+; for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with GCC; see the file COPYING3.  If not see
+; <http://www.gnu.org/licenses/>.
+
+mfused-madd
+Target Undocumented Alias(ffp-contract=, fast, off) Warn(%<-mfused-madd%> is deprecated; use %<-ffp-contract=%> instead)
+
+; This comment is to ensure we retain the blank line above.
diff --git a/gcc/config/ia64/hpux.h b/gcc/config/ia64/hpux.h
index 47bbd1e..c0dae0a 100644
--- a/gcc/config/ia64/hpux.h
+++ b/gcc/config/ia64/hpux.h
@@ -106,7 +106,7 @@  do {							\
 
 #undef TARGET_DEFAULT
 #define TARGET_DEFAULT \
-  (MASK_DWARF2_ASM | MASK_BIG_ENDIAN | MASK_ILP32 | MASK_FUSED_MADD)
+  (MASK_DWARF2_ASM | MASK_BIG_ENDIAN | MASK_ILP32)
 
 /* ??? Might not be needed anymore.  */
 #define MEMBER_TYPE_FORCES_BLK(FIELD, MODE) ((MODE) == TFmode)
diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h
index fdac455..1b24c8e 100644
--- a/gcc/config/ia64/ia64.h
+++ b/gcc/config/ia64/ia64.h
@@ -96,7 +96,7 @@  enum ia64_inline_type
 /* Default target_flags if no switches are specified  */
 
 #ifndef TARGET_DEFAULT
-#define TARGET_DEFAULT (MASK_DWARF2_ASM | MASK_FUSED_MADD)
+#define TARGET_DEFAULT (MASK_DWARF2_ASM)
 #endif
 
 #ifndef TARGET_CPU_DEFAULT
diff --git a/gcc/config/ia64/ia64.md b/gcc/config/ia64/ia64.md
index 73e57b6..0ba3106 100644
--- a/gcc/config/ia64/ia64.md
+++ b/gcc/config/ia64/ia64.md
@@ -2757,24 +2757,6 @@ 
   "fmax %0 = %F1, %F2"
   [(set_attr "itanium_class" "fmisc")])
 
-(define_insn "*maddsf4"
-  [(set (match_operand:SF 0 "fr_register_operand" "=f")
-	(plus:SF (mult:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
-			  (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG"))
-		 (match_operand:SF 3 "fr_reg_or_signed_fp01_operand" "fZ")))]
-  "TARGET_FUSED_MADD"
-  "fma.s %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])
-
-(define_insn "*msubsf4"
-  [(set (match_operand:SF 0 "fr_register_operand" "=f")
-	(minus:SF (mult:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
-			   (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG"))
-		  (match_operand:SF 3 "fr_reg_or_signed_fp01_operand" "fZ")))]
-  "TARGET_FUSED_MADD"
-  "fms.s %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])
-
 (define_insn "*nmulsf3"
   [(set (match_operand:SF 0 "fr_register_operand" "=f")
 	(neg:SF (mult:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
@@ -2783,16 +2765,6 @@ 
   "fnmpy.s %0 = %F1, %F2"
   [(set_attr "itanium_class" "fmac")])
 
-(define_insn "*nmaddsf4"
-  [(set (match_operand:SF 0 "fr_register_operand" "=f")
-	(minus:SF (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG") 
-		  (mult:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
-			   (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG"))))]
-  "TARGET_FUSED_MADD"
-  "fnma.s %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])
-
-;; Official C99 versions of the fmaf family of operations.
 (define_insn "fmasf4"
   [(set (match_operand:SF 0 "fr_register_operand" "=f")
 	(fma:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
@@ -2802,7 +2774,7 @@ 
   "fma.s %0 = %F1, %F2, %F3"
   [(set_attr "itanium_class" "fmac")])
 
-(define_insn "*fmssf4"
+(define_insn "fmssf4"
   [(set (match_operand:SF 0 "fr_register_operand" "=f")
 	(fma:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
 		(match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")
@@ -2812,8 +2784,7 @@ 
   "fms.s %0 = %F1, %F2, %F3"
   [(set_attr "itanium_class" "fmac")])
 
-;; This insn is officially "-(a * b) + c" which is "(-a * b) + c".
-(define_insn "*nfmasf4"
+(define_insn "fnmasf4"
   [(set (match_operand:SF 0 "fr_register_operand" "=f")
 	(fma:SF (neg:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG"))
 		(match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")
@@ -2934,44 +2905,6 @@ 
   "fmax %0 = %F1, %F2"
   [(set_attr "itanium_class" "fmisc")])
 
-(define_insn "*madddf4"
-  [(set (match_operand:DF 0 "fr_register_operand" "=f")
-	(plus:DF (mult:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
-			  (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))
-		 (match_operand:DF 3 "fr_reg_or_signed_fp01_operand" "fZ")))]
-  "TARGET_FUSED_MADD"
-  "fma.d %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])
-
-(define_insn "*madddf4_trunc"
-  [(set (match_operand:SF 0 "fr_register_operand" "=f")
-	(float_truncate:SF
-	  (plus:DF (mult:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
-			    (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))
-		   (match_operand:DF 3 "fr_reg_or_signed_fp01_operand" "fZ"))))]
-  "TARGET_FUSED_MADD"
-  "fma.s %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])
-
-(define_insn "*msubdf4"
-  [(set (match_operand:DF 0 "fr_register_operand" "=f")
-	(minus:DF (mult:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
-			   (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))
-		  (match_operand:DF 3 "fr_reg_or_signed_fp01_operand" "fZ")))]
-  "TARGET_FUSED_MADD"
-  "fms.d %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])
-
-(define_insn "*msubdf4_trunc"
-  [(set (match_operand:SF 0 "fr_register_operand" "=f")
-	(float_truncate:SF
-	  (minus:DF (mult:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
-			     (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))
-		    (match_operand:DF 3 "fr_reg_or_signed_fp01_operand" "fZ"))))]
-  "TARGET_FUSED_MADD"
-  "fms.s %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])
-
 (define_insn "*nmuldf3"
   [(set (match_operand:DF 0 "fr_register_operand" "=f")
 	(neg:DF (mult:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
@@ -2989,26 +2922,6 @@ 
   "fnmpy.s %0 = %F1, %F2"
   [(set_attr "itanium_class" "fmac")])
 
-(define_insn "*nmadddf4"
-  [(set (match_operand:DF 0 "fr_register_operand" "=f")
-	(minus:DF (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")
-		  (mult:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
-			   (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))))]
-  "TARGET_FUSED_MADD"
-  "fnma.d %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])
-
-(define_insn "*nmadddf4_truncsf"
-  [(set (match_operand:SF 0 "fr_register_operand" "=f")
-	(float_truncate:SF
-	(minus:DF (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")
-		  (mult:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
-			   (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))))]
-  "TARGET_FUSED_MADD"
-  "fnma.s %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])
-
-;; Official C99 versions of the fma family of operations.
 (define_insn "fmadf4"
   [(set (match_operand:DF 0 "fr_register_operand" "=f")
 	(fma:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
@@ -3018,7 +2931,7 @@ 
   "fma.d %0 = %F1, %F2, %F3"
   [(set_attr "itanium_class" "fmac")])
 
-(define_insn "*fmsdf4"
+(define_insn "fmsdf4"
   [(set (match_operand:DF 0 "fr_register_operand" "=f")
 	(fma:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
 		(match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")
@@ -3028,8 +2941,7 @@ 
   "fms.d %0 = %F1, %F2, %F3"
   [(set_attr "itanium_class" "fmac")])
 
-;; See comment for nfmasf4.
-(define_insn "*nfmadf4"
+(define_insn "fnmadf4"
   [(set (match_operand:DF 0 "fr_register_operand" "=f")
 	(fma:DF (neg:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG"))
 		(match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")
@@ -3177,64 +3089,6 @@ 
   "fmax %0 = %F1, %F2"
   [(set_attr "itanium_class" "fmisc")])
 
-(define_insn "*maddxf4"
-  [(set (match_operand:XF 0 "fr_register_operand" "=f")
-	(plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
-			  (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
-		 (match_operand:XF 3 "xfreg_or_signed_fp01_operand" "fZ")))]
-  "TARGET_FUSED_MADD"
-  "fma %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])
-
-(define_insn "*maddxf4_truncsf"
-  [(set (match_operand:SF 0 "fr_register_operand" "=f")
-	(float_truncate:SF
-	  (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
-			    (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
-		   (match_operand:XF 3 "xfreg_or_signed_fp01_operand" "fZ"))))]
-  "TARGET_FUSED_MADD"
-  "fma.s %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])
-
-(define_insn "*maddxf4_truncdf"
-  [(set (match_operand:DF 0 "fr_register_operand" "=f")
-	(float_truncate:DF
-	  (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
-			    (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
-		   (match_operand:XF 3 "xfreg_or_signed_fp01_operand" "fZ"))))]
-  "TARGET_FUSED_MADD"
-  "fma.d %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])
-
-(define_insn "*msubxf4"
-  [(set (match_operand:XF 0 "fr_register_operand" "=f")
-	(minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
-			   (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
-		  (match_operand:XF 3 "xfreg_or_signed_fp01_operand" "fZ")))]
-  "TARGET_FUSED_MADD"
-  "fms %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])
-
-(define_insn "*msubxf4_truncsf"
-  [(set (match_operand:SF 0 "fr_register_operand" "=f")
-	(float_truncate:SF
-	  (minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
-			     (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
-		    (match_operand:XF 3 "xfreg_or_signed_fp01_operand" "fZ"))))]
-  "TARGET_FUSED_MADD"
-  "fms.s %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])
-
-(define_insn "*msubxf4_truncdf"
-  [(set (match_operand:DF 0 "fr_register_operand" "=f")
-	(float_truncate:DF
-	  (minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
-			     (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
-		    (match_operand:XF 3 "xfreg_or_signed_fp01_operand" "fZ"))))]
-  "TARGET_FUSED_MADD"
-  "fms.d %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])
-
 (define_insn "*nmulxf3"
   [(set (match_operand:XF 0 "fr_register_operand" "=f")
 	(neg:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
@@ -3263,39 +3117,6 @@ 
   "fnmpy.d %0 = %F1, %F2"
   [(set_attr "itanium_class" "fmac")])
 
-(define_insn "*nmaddxf4"
-  [(set (match_operand:XF 0 "fr_register_operand" "=f")
-	(minus:XF (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")
-		  (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
-			   (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
-   )))]
-  "TARGET_FUSED_MADD"
-  "fnma %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])
-
-(define_insn "*nmaddxf4_truncsf"
-  [(set (match_operand:SF 0 "fr_register_operand" "=f")
-	(float_truncate:SF
-	  (minus:XF (match_operand:XF 3 "xfreg_or_fp01_operand" "fG") 
-		    (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
-			     (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
-   ))))]
-  "TARGET_FUSED_MADD"
-  "fnma.s %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])
-
-(define_insn "*nmaddxf4_truncdf"
-  [(set (match_operand:DF 0 "fr_register_operand" "=f")
-	(float_truncate:DF
-	  (minus:XF (match_operand:XF 3 "xfreg_or_fp01_operand" "fG") 
-		    (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
-			     (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
-   ))))]
-  "TARGET_FUSED_MADD"
-  "fnma.d %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])
-
-;; Official C99 versions of the fmal family of operations.
 (define_insn "fmaxf4"
   [(set (match_operand:XF 0 "fr_register_operand" "=f")
 	(fma:XF (match_operand:XF 1 "fr_reg_or_fp01_operand" "fG")
@@ -3305,7 +3126,7 @@ 
   "fma %0 = %F1, %F2, %F3"
   [(set_attr "itanium_class" "fmac")])
 
-(define_insn "*fmsxf4"
+(define_insn "fmsxf4"
   [(set (match_operand:XF 0 "fr_register_operand" "=f")
 	(fma:XF (match_operand:XF 1 "fr_reg_or_fp01_operand" "fG")
 		(match_operand:XF 2 "fr_reg_or_fp01_operand" "fG")
@@ -3315,8 +3136,7 @@ 
   "fms %0 = %F1, %F2, %F3"
   [(set_attr "itanium_class" "fmac")])
 
-;; See comment for nfmasf4.
-(define_insn "*nfmaxf4"
+(define_insn "fnmaxf4"
   [(set (match_operand:XF 0 "fr_register_operand" "=f")
 	(fma:XF (neg:XF (match_operand:XF 1 "fr_reg_or_fp01_operand" "fG"))
 		(match_operand:XF 2 "fr_reg_or_fp01_operand" "fG")
diff --git a/gcc/config/ia64/ia64.opt b/gcc/config/ia64/ia64.opt
index 27cd5b1..7919858 100644
--- a/gcc/config/ia64/ia64.opt
+++ b/gcc/config/ia64/ia64.opt
@@ -178,8 +178,4 @@  msel-sched-dont-check-control-spec
 Target Report Var(mflag_sel_sched_dont_check_control_spec) Init(0)
 Don't generate checks for control speculation in selective scheduling
 
-mfused-madd
-Target Report Mask(FUSED_MADD)
-Enable fused multiply/add and multiply/subtract instructions
-
 ; This comment is to ensure we retain the blank line above.
diff --git a/gcc/config/ia64/vect.md b/gcc/config/ia64/vect.md
index ae23c75..6ab1002 100644
--- a/gcc/config/ia64/vect.md
+++ b/gcc/config/ia64/vect.md
@@ -903,106 +903,29 @@ 
   "fpnegabs %0 = %1"
   [(set_attr "itanium_class" "fmisc")])
 
-;; In order to convince combine to merge plus and mult to a useful fpma,
-;; we need a couple of extra patterns.
 (define_expand "addv2sf3"
-  [(parallel
-    [(set (match_operand:V2SF 0 "fr_register_operand" "")
-	  (plus:V2SF (match_operand:V2SF 1 "fr_register_operand" "")
-		     (match_operand:V2SF 2 "fr_register_operand" "")))
-     (use (match_dup 3))])]
+  [(set (match_operand:V2SF 0 "fr_register_operand" "")
+	(fma:V2SF (match_operand:V2SF 1 "fr_register_operand" "")
+		  (match_dup 3)
+		  (match_operand:V2SF 2 "fr_register_operand" "")))]
   ""
 {
   rtvec v = gen_rtvec (2, CONST1_RTX (SFmode), CONST1_RTX (SFmode));
   operands[3] = force_reg (V2SFmode, gen_rtx_CONST_VECTOR (V2SFmode, v));
-  if (!TARGET_FUSED_MADD)
-    {
-      emit_insn (gen_fpma (operands[0], operands[1], operands[3], operands[2]));
-      DONE;
-    }
 })
 
-;; The split condition here could be combine_completed, if we had such.
-(define_insn_and_split "*addv2sf3_1"
-  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
-	(plus:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
-		   (match_operand:V2SF 2 "fr_register_operand" "f")))
-   (use (match_operand:V2SF 3 "fr_register_operand" "f"))]
-  ""
-  "#"
-  "reload_completed"
-  [(set (match_dup 0)
-	(plus:V2SF
-	  (mult:V2SF (match_dup 1) (match_dup 3))
-	  (match_dup 2)))]
-  "")
-
-(define_insn_and_split "*addv2sf3_2"
-  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
-	(plus:V2SF
-	  (mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
-		     (match_operand:V2SF 2 "fr_register_operand" "f"))
-	  (match_operand:V2SF 3 "fr_register_operand" "f")))
-    (use (match_operand:V2SF 4 "" "X"))]
-  ""
-  "#"
-  ""
-  [(set (match_dup 0)
-	(plus:V2SF
-	  (mult:V2SF (match_dup 1) (match_dup 2))
-	  (match_dup 3)))]
-  "")
-
-;; In order to convince combine to merge minus and mult to a useful fpms,
-;; we need a couple of extra patterns.
 (define_expand "subv2sf3"
-  [(parallel
-    [(set (match_operand:V2SF 0 "fr_register_operand" "")
-	  (minus:V2SF (match_operand:V2SF 1 "fr_register_operand" "")
-		      (match_operand:V2SF 2 "fr_register_operand" "")))
-     (use (match_dup 3))])]
+  [(set (match_operand:V2SF 0 "fr_register_operand" "")
+	(fma:V2SF
+	  (match_operand:V2SF 1 "fr_register_operand" "")
+	  (match_dup 3)
+	  (neg:V2SF (match_operand:V2SF 2 "fr_register_operand" ""))))]
   ""
 {
   rtvec v = gen_rtvec (2, CONST1_RTX (SFmode), CONST1_RTX (SFmode));
   operands[3] = force_reg (V2SFmode, gen_rtx_CONST_VECTOR (V2SFmode, v));
-  if (!TARGET_FUSED_MADD)
-    {
-      emit_insn (gen_fpms (operands[0], operands[1], operands[3], operands[2]));
-      DONE;
-    }
 })
 
-;; The split condition here could be combine_completed, if we had such.
-(define_insn_and_split "*subv2sf3_1"
-  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
-	(minus:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
-		    (match_operand:V2SF 2 "fr_register_operand" "f")))
-   (use (match_operand:V2SF 3 "fr_register_operand" "f"))]
-  ""
-  "#"
-  "reload_completed"
-  [(set (match_dup 0)
-	(minus:V2SF
-	  (mult:V2SF (match_dup 1) (match_dup 3))
-	  (match_dup 2)))]
-  "")
-
-(define_insn_and_split "*subv2sf3_2"
-  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
-	(minus:V2SF
-	  (mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
-		     (match_operand:V2SF 2 "fr_register_operand" "f"))
-	  (match_operand:V2SF 3 "fr_register_operand" "f")))
-    (use (match_operand:V2SF 4 "" "X"))]
-  ""
-  "#"
-  ""
-  [(set (match_dup 0)
-	(minus:V2SF
-	  (mult:V2SF (match_dup 1) (match_dup 2))
-	  (match_dup 3)))]
-  "")
-
 (define_insn "mulv2sf3"
   [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
 	(mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
@@ -1011,22 +934,22 @@ 
   "fpmpy %0 = %1, %2"
   [(set_attr "itanium_class" "fmac")])
 
-(define_insn "fpma"
+(define_insn "fmav2sf4"
   [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
-	(plus:V2SF
-	  (mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
-		     (match_operand:V2SF 2 "fr_register_operand" "f"))
+	(fma:V2SF
+	  (match_operand:V2SF 1 "fr_register_operand" "f")
+	  (match_operand:V2SF 2 "fr_register_operand" "f")
 	  (match_operand:V2SF 3 "fr_register_operand" "f")))]
   ""
   "fpma %0 = %1, %2, %3"
   [(set_attr "itanium_class" "fmac")])
 
-(define_insn "fpms"
+(define_insn "fmsv2sf4"
   [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
-	(minus:V2SF
-	  (mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
-		     (match_operand:V2SF 2 "fr_register_operand" "f"))
-	  (match_operand:V2SF 3 "fr_register_operand" "f")))]
+	(fma:V2SF
+	  (match_operand:V2SF 1 "fr_register_operand" "f")
+	  (match_operand:V2SF 2 "fr_register_operand" "f")
+	  (neg:V2SF (match_operand:V2SF 3 "fr_register_operand" "f"))))]
   ""
   "fpms %0 = %1, %2, %3"
   [(set_attr "itanium_class" "fmac")])
@@ -1040,12 +963,11 @@ 
   "fpnmpy %0 = %1, %2"
   [(set_attr "itanium_class" "fmac")])
 
-(define_insn "*fpnma"
+(define_insn "fnmav2sf4"
   [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
-	(plus:V2SF
-	  (neg:V2SF
-	    (mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
-		       (match_operand:V2SF 2 "fr_register_operand" "f")))
+	(fma:V2SF
+	  (neg:V2SF (match_operand:V2SF 1 "fr_register_operand" "f"))
+	  (match_operand:V2SF 2 "fr_register_operand" "f")
 	  (match_operand:V2SF 3 "fr_register_operand" "f")))]
   ""
   "fpnma %0 = %1, %2, %3"
diff --git a/gcc/config/ia64/vms.h b/gcc/config/ia64/vms.h
index 4ec8161..1e1a04f 100644
--- a/gcc/config/ia64/vms.h
+++ b/gcc/config/ia64/vms.h
@@ -45,7 +45,7 @@  along with GCC; see the file COPYING3.  If not see
 
 /* Need .debug_line info generated from gcc and gas.  */
 #undef TARGET_DEFAULT
-#define TARGET_DEFAULT (MASK_DWARF2_ASM | MASK_GNU_AS | MASK_FUSED_MADD)
+#define TARGET_DEFAULT (MASK_DWARF2_ASM | MASK_GNU_AS)
 
 #define VMS_DEBUG_MAIN_POINTER "TRANSFER$BREAK$GO"
 
diff --git a/gcc/config/ia64/vms64.h b/gcc/config/ia64/vms64.h
index f9fcf8b..ac1d7a5 100644
--- a/gcc/config/ia64/vms64.h
+++ b/gcc/config/ia64/vms64.h
@@ -36,6 +36,6 @@  along with GCC; see the file COPYING3.  If not see
 #define POINTER_SIZE 64
 
 #undef TARGET_DEFAULT
-#define TARGET_DEFAULT (MASK_DWARF2_ASM | MASK_GNU_AS | MASK_FUSED_MADD | MASK_MALLOC64)
+#define TARGET_DEFAULT (MASK_DWARF2_ASM | MASK_GNU_AS | MASK_MALLOC64)
 
 #include "config/vms/vms-crtl-64.h"
diff --git a/gcc/testsuite/gcc.target/ia64/mno-fused-madd-vect.c b/gcc/testsuite/gcc.target/ia64/mno-fused-madd-vect.c
index 0e24bf6..fd80d06 100644
--- a/gcc/testsuite/gcc.target/ia64/mno-fused-madd-vect.c
+++ b/gcc/testsuite/gcc.target/ia64/mno-fused-madd-vect.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile */
-/* { dg-options "-O2 -mno-fused-madd -ftree-vectorize" } */
+/* { dg-options "-O2 -ffp-contract=off -ftree-vectorize" } */
 /* { dg-final { scan-assembler "fpmpy" } } */
 
 /* fpma and fpms will show in either way because there are no
diff --git a/gcc/testsuite/gcc.target/ia64/mno-fused-madd.c b/gcc/testsuite/gcc.target/ia64/mno-fused-madd.c
index d8ccc94..487519a 100644
--- a/gcc/testsuite/gcc.target/ia64/mno-fused-madd.c
+++ b/gcc/testsuite/gcc.target/ia64/mno-fused-madd.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile */
-/* { dg-options "-O2 -mno-fused-madd" } */
+/* { dg-options "-O2 -ffp-contract=off" } */
 /* { dg-final { scan-assembler-not "fma" } } */
 /* { dg-final { scan-assembler-not "fms" } } */
 /* { dg-final { scan-assembler-not "fnma" } } */